mirror of
https://git.cloudron.io/cloudron/gitea-app.git
synced 2025-04-13 19:44:15 +00:00
Compare commits
384 commits
Author | SHA1 | Date | |
---|---|---|---|
|
d0d4b89f12 | ||
|
16253c0192 | ||
|
c9ba138d8a | ||
|
7337ff8517 | ||
|
94f2007015 | ||
|
1110ee23e2 | ||
|
ccaa24df33 | ||
|
9c4f201845 | ||
|
2f0edb0cb4 | ||
|
217b6ad97d | ||
|
cb0adb4d95 | ||
|
574bb07847 | ||
|
d259e03bee | ||
|
edf51f882f | ||
|
96e8c6b370 | ||
|
c0384ea5db | ||
|
ffc49beb18 | ||
|
b51354ea67 | ||
|
3017db2ca3 | ||
|
afc6c1a336 | ||
|
856e8ffded | ||
|
0e8051524b | ||
|
343c4f4487 | ||
|
fa8b746489 | ||
|
e703139dad | ||
|
038c2634f7 | ||
|
506fc44188 | ||
|
b37adcbcba | ||
|
d5b80c9393 | ||
|
e180f84aef | ||
|
090c4c43a8 | ||
|
ce1c328a27 | ||
|
e76784cb8f | ||
|
64d8d5b661 | ||
|
bf30c8e13b | ||
|
381562f347 | ||
|
ffa9d52206 | ||
|
7d0d52ceae | ||
|
f19465b3d6 | ||
|
662cfae820 | ||
|
e365f033d1 | ||
|
b8e5fcc22d | ||
|
a176ab5f20 | ||
|
9b773524ce | ||
|
9c4088e812 | ||
|
c956c27334 | ||
|
75aa1f09a5 | ||
|
9f363fb373 | ||
|
e06c3d5bb5 | ||
|
aa7a6f9d69 | ||
|
56cb2ba6b2 | ||
|
08868f64d4 | ||
|
d7c3ae38fe | ||
|
9b7aedc025 | ||
|
70c144095a | ||
|
69df4d1e0f | ||
|
07982e33aa | ||
|
59266f120a | ||
|
c03ec98517 | ||
|
885a32e340 | ||
|
459646512e | ||
|
5d44c03115 | ||
|
4961b7c4c8 | ||
|
cfc5ab5a37 | ||
|
6259356ae2 | ||
|
813f32d310 | ||
|
162054ef99 | ||
|
18ad051734 | ||
|
ea6a6b84d9 | ||
|
ab0ab3c11c | ||
|
84c505ad43 | ||
|
366e8560b0 | ||
|
0a81a63829 | ||
|
4fc500fca6 | ||
|
8393426612 | ||
|
a08dd3ee47 | ||
|
63fce06157 | ||
|
d0c1e65913 | ||
|
88732c63c9 | ||
|
d62cca74cc | ||
|
f96533530f | ||
|
3e95af2256 | ||
|
90693772de | ||
|
092f2089f2 | ||
|
16ffe8295f | ||
|
61d2691859 | ||
|
19c4b2a7ff | ||
|
5c7c228ff4 | ||
|
62b03b02d5 | ||
|
7dd4447091 | ||
|
d23339e2e3 | ||
|
32daf79b3b | ||
|
2d0a1f14e6 | ||
|
bbae02fa50 | ||
|
e176d6c705 | ||
|
dd44f81d04 | ||
|
a4b0af1f02 | ||
|
4b15736f81 | ||
|
8876fedd40 | ||
|
65df2c54da | ||
|
245b93ea02 | ||
|
8596073c51 | ||
|
6a85b0cea2 | ||
|
5205ba5e83 | ||
|
f668f4f3ab | ||
|
7eca682cec | ||
|
f9f867ca89 | ||
|
9580ece3a1 | ||
|
f2818dc4f9 | ||
|
35ac25e140 | ||
|
3cb4caaeac | ||
|
55d2b0d320 | ||
|
8f55a89978 | ||
|
5240330992 | ||
|
95fc696bcd | ||
|
77b3e2b033 | ||
|
5fbd69679c | ||
|
2c837eeb8f | ||
|
040fcf3386 | ||
|
58298a6b20 | ||
|
6b2e221264 | ||
|
1e9964fe49 | ||
|
23fa45cbc8 | ||
|
572226155c | ||
|
50ec10f0ae | ||
|
a99dfc8e2a | ||
|
6bbea49e07 | ||
|
f53e024f69 | ||
|
68fe1f97d0 | ||
|
896336f7c2 | ||
|
ea91e676cf | ||
|
94e9181ced | ||
|
8808e8c0b2 | ||
|
d00238c1ad | ||
|
07442c675c | ||
|
ed1846cd28 | ||
|
e10793d421 | ||
|
9eea9fe0be | ||
|
298cb33e86 | ||
|
89240fc070 | ||
|
6b2af3eab4 | ||
|
32eebcff8f | ||
|
166dac9b12 | ||
|
26db0254c7 | ||
|
35e3edaa6c | ||
|
93370fa502 | ||
|
3398da164d | ||
|
6ce20e9e75 | ||
|
cb14653680 | ||
|
46982e68f7 | ||
|
a2d2edabaf | ||
|
7261adc546 | ||
|
a338dc215a | ||
|
a12cf5f70b | ||
|
730611229e | ||
|
fcb4caff89 | ||
|
200dc7676f | ||
|
320fbf86d9 | ||
|
04d857e88b | ||
|
e2f6fb52b3 | ||
|
4224cc9692 | ||
|
d416ec0dc7 | ||
|
ea5ff4e574 | ||
|
27720786bf | ||
|
f48a4c4d72 | ||
|
65fbb9cb7d | ||
|
63bfe621d1 | ||
|
a6688ede57 | ||
|
7f2646bfb3 | ||
|
aafc1968ec | ||
|
2f85d288e0 | ||
|
e5296ab5ee | ||
|
77e05f56bf | ||
|
4eab21379e | ||
|
1da61b548f | ||
|
76df0b0113 | ||
|
d9fa8399fe | ||
|
aa0b00cd1e | ||
|
8999bc9112 | ||
|
a7734d29fb | ||
|
b667082cec | ||
|
9abcb0c5ec | ||
|
3f6593c676 | ||
|
5f7b0457db | ||
|
7adfed915b | ||
|
2af74e6817 | ||
|
57ad6d200a | ||
|
4df53960f5 | ||
|
2fb28433fb | ||
|
6874ea9d46 | ||
|
2c284d36fa | ||
|
83da665570 | ||
|
a427a098fe | ||
|
eb4f29375b | ||
|
05dcb14e8d | ||
|
5a03ee8f27 | ||
|
e62f99643d | ||
|
73027148c6 | ||
|
67a138be41 | ||
|
2c32dcf6bd | ||
|
dc7f7e2f4e | ||
|
9a03f268cb | ||
|
fde6dfa485 | ||
|
8b16de1dcd | ||
|
1074999c40 | ||
|
0cfe7fea88 | ||
|
a3bb9db92e | ||
|
8c84f905e7 | ||
|
0008351e7c | ||
|
0aab01b926 | ||
|
2877b4e599 | ||
|
f5f690ebd9 | ||
|
4a5bf98d60 | ||
|
3e84ab8730 | ||
|
c0d7b41a77 | ||
|
df77df2347 | ||
|
f18b11626c | ||
|
75917ed6e1 | ||
|
8033a4f001 | ||
|
6c2c00a53a | ||
|
86e13642e6 | ||
|
257b51d226 | ||
|
37544c8e9b | ||
|
a04656847a | ||
|
5e8950ec86 | ||
|
2637ef1b4b | ||
|
0bea878d12 | ||
|
bed765a1e4 | ||
|
1e38bd58c6 | ||
|
a0f8607250 | ||
|
4c0e49def0 | ||
|
c9937d6134 | ||
|
3d51637daf | ||
|
65a87ede58 | ||
|
11800518cb | ||
|
731be1ccf8 | ||
|
32c5507674 | ||
|
1deeedfc87 | ||
|
86a0949b14 | ||
|
1aee702ada | ||
|
6833bcd31b | ||
|
1a433ecee0 | ||
|
c1f261592e | ||
|
282eed291e | ||
|
43900e7897 | ||
|
5ff6e0a410 | ||
|
3b9989fcf0 | ||
|
8b92a4feb4 | ||
|
f510244950 | ||
|
8744b525cd | ||
|
172c5f7307 | ||
|
48299030e6 | ||
|
8e84cf4817 | ||
|
c263876cdd | ||
|
6429ca8909 | ||
|
0cf326f08f | ||
|
2cc40fffef | ||
|
9a3c9338c3 | ||
|
58a6351ab2 | ||
|
ef557e98d7 | ||
|
2a17c1717d | ||
|
62f9860bf5 | ||
|
522923dbee | ||
|
b117af4511 | ||
|
dc2987aafb | ||
|
50a2444e76 | ||
|
ea72f04000 | ||
|
2759c0d852 | ||
|
7b0ec195e6 | ||
|
a677369189 | ||
|
2e8b2c637f | ||
|
07d07b342a | ||
|
93fa56da6b | ||
|
e68a0333a9 | ||
|
5ed9ee9284 | ||
|
a94c165c34 | ||
|
1b053028a0 | ||
|
5e7a1b2a37 | ||
|
cc63133f85 | ||
|
08cbfbb9d4 | ||
|
9944104273 | ||
|
076dd3946b | ||
|
2885c388e8 | ||
|
8693f77352 | ||
|
5a0d2ea12e | ||
|
3fbe8140a7 | ||
|
ac4eecf92b | ||
|
3fc5685027 | ||
|
9320ee11ad | ||
|
664677527a | ||
|
b1f8b8cb9a | ||
|
b72d7ad682 | ||
|
5b625519c1 | ||
|
9551b31c8e | ||
|
4514b6fc9b | ||
|
783cce292c | ||
|
538f3fdead | ||
|
b2b86f170f | ||
|
4301fd5117 | ||
|
7aebe88c3e | ||
|
91cc96705e | ||
|
6fe012f901 | ||
|
29197622fc | ||
|
3adbf0b442 | ||
|
6c0a2ab20b | ||
|
1943723dd3 | ||
|
2d15227f2e | ||
|
cbc0bfb222 | ||
|
10df3c6ba9 | ||
|
047ec295bc | ||
|
31b8a17230 | ||
|
ebb46bb7ac | ||
|
53f180ef95 | ||
|
d89fc6a0ec | ||
|
1039d32995 | ||
|
6b25bb66c7 | ||
|
e566c94b43 | ||
|
0d2e1cfff0 | ||
|
f830faac79 | ||
|
319e6d275c | ||
|
9128339000 | ||
|
f7ca27425a | ||
|
9907d1c9cd | ||
|
8d16e4d734 | ||
|
150d490801 | ||
|
4a4e4ff4f1 | ||
|
24e9499d9c | ||
|
8c66d9ed76 | ||
|
60d06af70d | ||
|
15c28c940d | ||
|
5f5d3a7b53 | ||
|
0902b92a7d | ||
|
d675d60e1d | ||
|
07d3c6bfcf | ||
|
60f9045cbb | ||
|
a633dcab9a | ||
|
435f30cf8c | ||
|
157f500660 | ||
|
2eae86ee53 | ||
|
3993229ac3 | ||
|
9793215e7c | ||
|
6e04300610 | ||
|
587235be2b | ||
|
de3369808e | ||
|
5e99be936a | ||
|
12f58af585 | ||
|
9971919cf9 | ||
|
65bc13c2b7 | ||
|
c231b12f2d | ||
|
1265366151 | ||
|
278116abdb | ||
|
8a942dc8f7 | ||
|
1b15db85e3 | ||
|
d37044f8e0 | ||
|
e7671bd3f2 | ||
|
32cc8175e5 | ||
|
534e4884b4 | ||
|
6e1f363b88 | ||
|
3eb57f2c07 | ||
|
b16095eef5 | ||
|
18b3ae6bc2 | ||
|
fbf8e5f953 | ||
|
106e65df9e | ||
|
1b629265fa | ||
|
f9949c11a3 | ||
|
a7e693c4ed | ||
|
b00d2aced2 | ||
|
c2419ba46c | ||
|
b39e1850d7 | ||
|
4d37e33eee | ||
|
b86f9c7a20 | ||
|
7fd766b348 | ||
|
525327c150 | ||
|
bc658da61e | ||
|
25f206ccdb | ||
|
d3553de1a6 | ||
|
99379fdbb3 | ||
|
21a9fccd60 | ||
|
8837d2fd60 | ||
|
a66843c3e3 | ||
|
67403a6d2a | ||
|
c137f79e9b | ||
|
0249f20656 | ||
|
5d00e930ff |
20 changed files with 5762 additions and 431 deletions
50
CHANGELOG
50
CHANGELOG
|
@ -1,50 +0,0 @@
|
|||
[0.1.0]
|
||||
* Initial package (forked from Gogs app)
|
||||
|
||||
[0.1.1]
|
||||
* Removed reference to Gogs
|
||||
|
||||
[0.1.2]
|
||||
* Updated description
|
||||
|
||||
[0.1.3]
|
||||
* Updated to version 1.1.2
|
||||
|
||||
[1.0.0]
|
||||
* Update to version 1.1.3
|
||||
|
||||
[1.0.1]
|
||||
* Update Git to v2.7.4-0ubuntu1.2
|
||||
* Fixes critical security issue that allows remote command execution in git
|
||||
* https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-1000117.html
|
||||
|
||||
[1.0.2]
|
||||
* Preserve SECRET_KEY across updates and restarts
|
||||
|
||||
[1.0.3]
|
||||
* Update to version 1.1.4
|
||||
|
||||
[1.1.0]
|
||||
* Update to version 1.2.0
|
||||
* New logo!
|
||||
* SECURITY: Sanitation fix from Gogs (#1461)
|
||||
* Status-API
|
||||
* Implement GPG api
|
||||
* https://github.com/go-gitea/gitea/releases/tag/v1.2.0
|
||||
|
||||
[1.1.1]
|
||||
* Update to version 1.2.1
|
||||
* Fix PR, milestone and label functionality if issue unit is disabled (#2710) (#2714)
|
||||
* Fix plain readme didn't render correctly on repo home page (#2705) (#2712)
|
||||
* Fix so that user can still fork his own repository to his organizations (#2699) (#2707)
|
||||
* Fix .netrc authentication (#2700) (#2708)
|
||||
* Fix slice out of bounds error in mailer (#2479) (#2696)
|
||||
|
||||
[1.1.2]
|
||||
* Update to version 1.2.2
|
||||
* Add checks for commits with missing author and time (#2771) (#2785)
|
||||
* Fix sending mail with a non-latin display name (#2559) (#2783)
|
||||
* Sync MaxGitDiffLineCharacters with conf/app.ini (#2779) (#2780)
|
||||
* Update vendor git (#2765) (#2772)
|
||||
* Fix emojify image URL (#2769) (#2773)
|
||||
|
1762
CHANGELOG.md
Normal file
1762
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,14 +4,20 @@
|
|||
"author": "Gitea developers",
|
||||
"description": "file://DESCRIPTION.md",
|
||||
"tagline": "A painless self-hosted Git Service",
|
||||
"version": "1.1.2",
|
||||
"healthCheckPath": "/healthcheck",
|
||||
"version": "1.35.3",
|
||||
"upstreamVersion": "1.23.7",
|
||||
"healthCheckPath": "/explore",
|
||||
"httpPort": 3000,
|
||||
"memoryLimit": 536870912,
|
||||
"addons": {
|
||||
"mysql": { },
|
||||
"sendmail": { },
|
||||
"localstorage": { },
|
||||
"ldap": { }
|
||||
"mysql": {},
|
||||
"sendmail": {
|
||||
"supportsDisplayName": true
|
||||
},
|
||||
"localstorage": {},
|
||||
"oidc": {
|
||||
"loginRedirectUri": "/user/oauth2/cloudron/callback"
|
||||
}
|
||||
},
|
||||
"tcpPorts": {
|
||||
"SSH_PORT": {
|
||||
|
@ -20,18 +26,35 @@
|
|||
"defaultValue": 29418
|
||||
}
|
||||
},
|
||||
"manifestVersion": 1,
|
||||
"manifestVersion": 2,
|
||||
"website": "https://gitea.io",
|
||||
"contactEmail": "apps@cloudron.io",
|
||||
"icon": "file://logo.png",
|
||||
"optionalSso": true,
|
||||
"mediaLinks": [
|
||||
"https://s3.amazonaws.com/cloudron-app-screenshots/io.gitea.cloudronapp/f89a2ab8d49094c80589f69a2d60bef63b2dbb62/1.png",
|
||||
"https://s3.amazonaws.com/cloudron-app-screenshots/io.gitea.cloudronapp/f89a2ab8d49094c80589f69a2d60bef63b2dbb62/2.png",
|
||||
"https://s3.amazonaws.com/cloudron-app-screenshots/io.gitea.cloudronapp/f89a2ab8d49094c80589f69a2d60bef63b2dbb62/3.png",
|
||||
"https://s3.amazonaws.com/cloudron-app-screenshots/io.gitea.cloudronapp/f89a2ab8d49094c80589f69a2d60bef63b2dbb62/4.png",
|
||||
"https://s3.amazonaws.com/cloudron-app-screenshots/io.gitea.cloudronapp/f89a2ab8d49094c80589f69a2d60bef63b2dbb62/5.png"
|
||||
"https://screenshots.cloudron.io/io.gitea.cloudronapp/1.png",
|
||||
"https://screenshots.cloudron.io/io.gitea.cloudronapp/2.png",
|
||||
"https://screenshots.cloudron.io/io.gitea.cloudronapp/3.png",
|
||||
"https://screenshots.cloudron.io/io.gitea.cloudronapp/4.png",
|
||||
"https://screenshots.cloudron.io/io.gitea.cloudronapp/5.png"
|
||||
],
|
||||
"tags": [ "version control", "git", "code hosting", "development" ],
|
||||
"changelog": "file://CHANGELOG",
|
||||
"postInstallMessage": "file://POSTINSTALL.md"
|
||||
"tags": [
|
||||
"version control",
|
||||
"git",
|
||||
"code hosting",
|
||||
"development",
|
||||
"github",
|
||||
"bitbucket",
|
||||
"gitlab"
|
||||
],
|
||||
"changelog": "file://CHANGELOG.md",
|
||||
"postInstallMessage": "file://POSTINSTALL.md",
|
||||
"checklist": {
|
||||
"change-default-password": {
|
||||
"message": "Change the default admin password"
|
||||
}
|
||||
},
|
||||
"minBoxVersion": "8.1.0",
|
||||
"forumUrl": "https://forum.cloudron.io/category/19/gitea",
|
||||
"documentationUrl": "https://docs.cloudron.io/apps/gitea/"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
This app packages Gitea <upstream>1.2.2</upstream>
|
||||
|
||||
Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket or Gitlab.
|
||||
|
||||
### Purpose
|
||||
|
|
31
Dockerfile
31
Dockerfile
|
@ -1,22 +1,27 @@
|
|||
FROM cloudron/base:0.10.0
|
||||
|
||||
ENV VERSION 1.2.2
|
||||
FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c6637eaf4a41ec4e596c
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y openssh-server git && \
|
||||
apt-get install -y openssh-server git asciidoctor pandoc pipx && \
|
||||
rm -rf /etc/ssh_host_* && \
|
||||
rm -r /var/cache/apt /var/lib/apt/lists
|
||||
|
||||
# pipx --global does not work, not sure why
|
||||
RUN PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install jupyter docutils --include-deps
|
||||
|
||||
ADD supervisor/ /etc/supervisor/conf.d/
|
||||
|
||||
RUN adduser --disabled-login --gecos 'Gitea' git
|
||||
# by default, git account is created as inactive which prevents login via openssh
|
||||
# https://github.com/gitlabhq/gitlabhq/issues/5304
|
||||
RUN passwd -d git
|
||||
RUN useradd --comment "Gogs" --create-home --shell /bin/bash git
|
||||
RUN passwd -d git # by default, git account is created as inactive which prevents login via openssh. this disables password for account
|
||||
WORKDIR /home/git
|
||||
|
||||
RUN mkdir -p /home/git/gitea
|
||||
## TODO: use redis as well
|
||||
RUN curl -L https://dl.gitea.io/gitea/${VERSION}/gitea-${VERSION}-linux-amd64 -o /home/git/gitea/gitea \
|
||||
# for autosign feature
|
||||
ENV GNUPGHOME="/app/data/gnupg"
|
||||
|
||||
# renovate: datasource=github-releases depName=go-gitea/gitea versioning=semver extractVersion=^v(?<version>.+)$
|
||||
ARG GITEA_VERSION=1.23.7
|
||||
|
||||
RUN mkdir -p /home/git/gitea && \
|
||||
curl -L https://github.com/go-gitea/gitea/releases/download/v${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64 -o /home/git/gitea/gitea \
|
||||
&& chmod +x /home/git/gitea/gitea
|
||||
|
||||
# setup config paths
|
||||
|
@ -31,9 +36,7 @@ RUN ln -s /app/data/gitconfig /home/git/.gitconfig
|
|||
|
||||
ADD start.sh /home/git/start.sh
|
||||
|
||||
# disable pam authentication for sshd
|
||||
RUN sed -e 's/UsePAM yes/UsePAM no/' -e 's/UsePrivilegeSeparation yes/UsePrivilegeSeparation no/' -i /etc/ssh/sshd_config
|
||||
RUN echo "UseDNS no" >> /etc/ssh/sshd_config
|
||||
COPY sshd_config /etc/ssh/sshd_config
|
||||
|
||||
CMD [ "/home/git/start.sh" ]
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
This app integrates with the Cloudron SSO. Admins on Cloudron automatically
|
||||
become admins on Gitea.
|
||||
This app is pre-setup with an admin account. The initial credentials are:
|
||||
|
||||
If you want to disable Cloudron SSO, do the following:
|
||||
|
||||
* Admin Panel -> Authentication -> 'cloudron' -> Uncheck 'This authentication is activated'
|
||||
* Admin Panel -> Users -> Change Authentication Source to 'Local' and also give a password
|
||||
|
||||
You can edit `/app/data/app.ini` and add any custom configuration. See the
|
||||
[configuration cheat sheet](https://docs.gitea.io/en-us/config-cheat-sheet)
|
||||
for more information.
|
||||
**Username**: root<br/>
|
||||
**Password**: changeme<br/>
|
||||
|
||||
<sso>
|
||||
Use the `Local` authentication source for logging in as admin.
|
||||
</sso>
|
||||
|
|
|
@ -48,23 +48,31 @@ ENABLED = true
|
|||
; APP_DATA_PATH/attachments
|
||||
PATH =
|
||||
|
||||
[oauth2_client]
|
||||
ENABLE_AUTO_REGISTRATION = true
|
||||
USERNAME = sub
|
||||
UPDATE_AVATAR = false
|
||||
ACCOUNT_LINKING = auto
|
||||
|
||||
[mailer]
|
||||
ENABLED = true
|
||||
|
||||
; those settings are protected and can't be modified
|
||||
HOST = ##MAIL_SERVER:##MAIL_PORT
|
||||
SMTP_ADDR = ##MAIL_SERVER
|
||||
SMTP_PORT = ##MAIL_PORT
|
||||
USER = ##MAIL_SMTP_USERNAME
|
||||
PASSWD = ##MAIL_SMTP_PASSWORD
|
||||
FROM = ##MAIL_FROM
|
||||
SKIP_VERIFY = true
|
||||
PROTOCOL = smtps
|
||||
FORCE_TRUST_SERVER_CERT = true
|
||||
|
||||
|
||||
[security]
|
||||
; those settings are protected and can't be modified
|
||||
INSTALL_LOCK = true
|
||||
SECRET_KEY = ##SECRET_KEY
|
||||
|
||||
REVERSE_PROXY_LIMIT = 1
|
||||
REVERSE_PROXY_TRUSTED_PROXIES = *
|
||||
|
||||
[service]
|
||||
DISABLE_REGISTRATION = false
|
||||
|
@ -95,3 +103,32 @@ PATH =
|
|||
[indexer]
|
||||
; this setting is protected and can't be modified
|
||||
ISSUE_INDEXER_PATH = /app/data/appdata/indexers/issues.bleve
|
||||
|
||||
[session]
|
||||
PROVIDER = file
|
||||
PROVIDER_CONFIG = /run/gitea/sessions
|
||||
COOKIE_SECURE = true
|
||||
COOKIE_NAME = cloudron_gitea
|
||||
GC_INTERVAL_TIME = 2592000
|
||||
|
||||
[markup.asciidoc]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .adoc,.asciidoc
|
||||
RENDER_COMMAND = "asciidoctor -s -a showtitle --out-file=- -"
|
||||
; Input is not a standard input but a file
|
||||
IS_INPUT_FILE = false
|
||||
|
||||
[markup.restructuredtext]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .rst
|
||||
RENDER_COMMAND = "timeout 30s pandoc +RTS -M512M -RTS -f rst"
|
||||
IS_INPUT_FILE = false
|
||||
|
||||
[markup.jupyter]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .ipynb
|
||||
RENDER_COMMAND = "jupyter nbconvert --stdin --stdout --to html --template basic"
|
||||
IS_INPUT_FILE = false
|
||||
|
||||
[markup.sanitizer.jupyter.img]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
|
|
4
renovate.json5
Normal file
4
renovate.json5
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["local>devops/renovator//default.renovate.json5"]
|
||||
}
|
37
sshd_config
Normal file
37
sshd_config
Normal file
|
@ -0,0 +1,37 @@
|
|||
Port 29418
|
||||
|
||||
AddressFamily any
|
||||
ListenAddress 0.0.0.0
|
||||
ListenAddress ::
|
||||
|
||||
HostKey /app/data/sshd/ssh_host_rsa_key
|
||||
HostKey /app/data/sshd/ssh_host_ecdsa_key
|
||||
HostKey /app/data/sshd/ssh_host_ed25519_key
|
||||
|
||||
LogLevel INFO
|
||||
|
||||
# no reverse DNS lookup
|
||||
UseDNS no
|
||||
UsePAM no
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
PrintMotd no
|
||||
PrintLastLog no
|
||||
|
||||
LoginGraceTime 120
|
||||
StrictModes yes
|
||||
PubkeyAuthentication yes
|
||||
PermitUserEnvironment yes
|
||||
PermitRootLogin no
|
||||
ChallengeResponseAuthentication no
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
HostbasedAuthentication no
|
||||
|
||||
AllowUsers git
|
||||
|
||||
Banner none
|
||||
Subsystem sftp /usr/lib/ssh/sftp-server
|
||||
|
||||
AcceptEnv GIT_PROTOCOL LANG LC_*
|
||||
|
101
start.sh
101
start.sh
|
@ -2,29 +2,50 @@
|
|||
|
||||
set -eu -o pipefail
|
||||
|
||||
mkdir -p /run/gitea/tmp/uploads
|
||||
mkdir -p /run/gitea/tmp/uploads /run/sshd /run/gitea/sessions
|
||||
|
||||
setup_ldap_source() {
|
||||
# CLOUDRON_OIDC_PROVIDER_NAME not supported as it will be used in rest route!
|
||||
setup_oidc_source() {
|
||||
set -eu
|
||||
|
||||
# Wait for gitea to finish db setup, before we insert ldap source in db
|
||||
while ! curl --fail http://localhost:3000/healthcheck; do
|
||||
echo "Waiting for gitea to come up"
|
||||
echo "==> Setup OIDC source"
|
||||
|
||||
now=$(date +%s)
|
||||
mysql -u"${CLOUDRON_MYSQL_USERNAME}" -p"${CLOUDRON_MYSQL_PASSWORD}" -h"${CLOUDRON_MYSQL_HOST}" -P"${CLOUDRON_MYSQL_PORT}" --database="${CLOUDRON_MYSQL_DATABASE}" -e \
|
||||
"REPLACE INTO login_source (id, type, name, is_active, cfg, created_unix, updated_unix) VALUES (1,6,'cloudron', 1,'{\"Provider\":\"openidConnect\",\"ClientID\":\"${CLOUDRON_OIDC_CLIENT_ID}\",\"ClientSecret\":\"${CLOUDRON_OIDC_CLIENT_SECRET}\",\"OpenIDConnectAutoDiscoveryURL\":\"${CLOUDRON_OIDC_ISSUER}/.well-known/openid-configuration\",\"CustomURLMapping\":null,\"IconURL\":\"\",\"Scopes\":[\"openid email profile\"],\"RequiredClaimName\":\"\",\"RequiredClaimValue\":\"\",\"GroupClaimName\":\"\",\"AdminGroup\":\"\",\"GroupTeamMap\":\"\",\"GroupTeamMapRemoval\":false,\"RestrictedGroup\":\"\"}','${now}','${now}')"
|
||||
}
|
||||
|
||||
setup_root_user() {
|
||||
set -eu
|
||||
|
||||
if sudo -H -u git /home/git/gitea/gitea admin user create --username root --password changeme --email admin@cloudron.local --admin -c /run/gitea/app.ini; then
|
||||
echo "==> root user added"
|
||||
else
|
||||
echo "==> Failed to add root user"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
setup_auth() {
|
||||
set -eu
|
||||
|
||||
# Wait for gitea to finish db setup, before we do any db operations
|
||||
while ! curl --fail http://localhost:3000/explore; do
|
||||
echo "==> Waiting for gitea to come up"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
now=$(date +%s)
|
||||
echo "==> Gitea is up, setting up auth"
|
||||
|
||||
# Get the existing LDAP source status. This allows the user to disable LDAP
|
||||
ldap_status=$(mysql -u"${MYSQL_USERNAME}" -p"${MYSQL_PASSWORD}" -h mysql --database="${MYSQL_DATABASE}" -N -B -e "select is_actived from login_source WHERE name='cloudron';")
|
||||
[[ -z "${ldap_status}" ]] && ldap_status="1"
|
||||
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
|
||||
setup_oidc_source
|
||||
fi
|
||||
|
||||
if mysql -u"${MYSQL_USERNAME}" -p"${MYSQL_PASSWORD}" -h mysql --database="${MYSQL_DATABASE}" \
|
||||
-e "REPLACE INTO login_source (id, type, name, is_actived, cfg, created_unix, updated_unix) VALUES (1,2,'cloudron',${ldap_status},'{\"Name\":\"cloudron\",\"Host\":\"${LDAP_SERVER}\",\"Port\":${LDAP_PORT},\"UseSSL\":false,\"SkipVerify\":true,\"BindDN\":\"${LDAP_BIND_DN}\",\"BindPassword\":\"${LDAP_BIND_PASSWORD}\",\"UserBase\":\"${LDAP_USERS_BASE_DN}\",\"AttributeUsername\":\"username\",\"AttributeName\":\"displayname\",\"AttributeSurname\":\"\",\"AttributeMail\":\"mail\",\"Filter\":\"(\\\\u007C(mail=%[1]s)(username=%[1]s))\",\"AdminFilter\":\"(memberof=cn=admins,${LDAP_GROUPS_BASE_DN})\"}','${now}','${now}');"; then
|
||||
echo "LDAP Authentication was setup with status ${ldap_status}"
|
||||
else
|
||||
echo "Failed to setup LDAP authentication"
|
||||
exit 1
|
||||
user_count=$(mysql -u"${CLOUDRON_MYSQL_USERNAME}" -p"${CLOUDRON_MYSQL_PASSWORD}" -h"${CLOUDRON_MYSQL_HOST}" -P"${CLOUDRON_MYSQL_PORT}" --database="${CLOUDRON_MYSQL_DATABASE}" -N -B -e "SELECT count(*) FROM user")
|
||||
# be careful, not to create root user for existing LDAP based installs
|
||||
if [[ "${user_count}" == "0" ]]; then
|
||||
echo "==> Setting up root user for first run"
|
||||
setup_root_user
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -50,35 +71,28 @@ fi
|
|||
chmod 0600 /app/data/sshd/*_key
|
||||
chmod 0644 /app/data/sshd/*.pub
|
||||
|
||||
sed -e "s/^Port .*/Port ${SSH_PORT}/" \
|
||||
-e "s/^#ListenAddress .*/ListenAddress 0.0.0.0/" \
|
||||
-e "s,^HostKey /etc/ssh/,HostKey /app/data/sshd/," \
|
||||
/etc/ssh/sshd_config > /run/gitea/sshd_config
|
||||
sed -e "s/^Port .*/Port ${SSH_PORT}/" /etc/ssh/sshd_config > /run/gitea/sshd_config
|
||||
|
||||
cp /home/git/app.ini.template "/run/gitea/app.ini"
|
||||
if [[ ! -f /app/data/app.ini ]]; then
|
||||
echo -e "; Add customizations here - https://docs.gitea.io/en-us/config-cheat-sheet/" > /app/data/app.ini
|
||||
|
||||
# create default user config file
|
||||
if ! [ -f /app/data/app.ini ]; then
|
||||
cp /home/git/app.ini.template /app/data/app.ini
|
||||
fi
|
||||
|
||||
if [ "$(crudini --get /app/data/app.ini security SECRET_KEY)" == "##SECRET_KEY" ]; then
|
||||
echo "Generating new SECRET_KEY"
|
||||
echo "==> Generating new SECRET_KEY"
|
||||
crudini --set "/app/data/app.ini" security SECRET_KEY $(pwgen -1 -s)
|
||||
fi
|
||||
|
||||
# merge user config file
|
||||
cp /home/git/app.ini.template "/run/gitea/app.ini"
|
||||
crudini --merge "/run/gitea/app.ini" < "/app/data/app.ini"
|
||||
|
||||
# override important values
|
||||
crudini --set "/run/gitea/app.ini" database DB_TYPE mysql
|
||||
crudini --set "/run/gitea/app.ini" database HOST "${MYSQL_HOST}:${MYSQL_PORT}"
|
||||
crudini --set "/run/gitea/app.ini" database NAME "${MYSQL_DATABASE}"
|
||||
crudini --set "/run/gitea/app.ini" database USER "${MYSQL_USERNAME}"
|
||||
crudini --set "/run/gitea/app.ini" database PASSWD "${MYSQL_PASSWORD}"
|
||||
crudini --set "/run/gitea/app.ini" database HOST "${CLOUDRON_MYSQL_HOST}:${CLOUDRON_MYSQL_PORT}"
|
||||
crudini --set "/run/gitea/app.ini" database NAME "${CLOUDRON_MYSQL_DATABASE}"
|
||||
crudini --set "/run/gitea/app.ini" database USER "${CLOUDRON_MYSQL_USERNAME}"
|
||||
crudini --set "/run/gitea/app.ini" database PASSWD "${CLOUDRON_MYSQL_PASSWORD}"
|
||||
crudini --set "/run/gitea/app.ini" database SSL_MODE "disable"
|
||||
crudini --set "/run/gitea/app.ini" server PROTOCOL "http"
|
||||
crudini --set "/run/gitea/app.ini" server DOMAIN "${APP_DOMAIN}"
|
||||
crudini --set "/run/gitea/app.ini" server DOMAIN "${CLOUDRON_APP_DOMAIN}"
|
||||
crudini --set "/run/gitea/app.ini" server ROOT_URL "https://%(DOMAIN)s/"
|
||||
crudini --set "/run/gitea/app.ini" server HTTP_ADDR ""
|
||||
crudini --set "/run/gitea/app.ini" server HTTP_PORT "3000"
|
||||
|
@ -87,22 +101,25 @@ crudini --set "/run/gitea/app.ini" server SSH_PORT "${SSH_PORT}"
|
|||
crudini --set "/run/gitea/app.ini" server APP_DATA_PATH "/app/data/appdata"
|
||||
crudini --set "/run/gitea/app.ini" repository ROOT "/app/data/repository"
|
||||
crudini --set "/run/gitea/app.ini" repository.upload TEMP_PATH "/run/gitea/tmp/uploads"
|
||||
crudini --set "/run/gitea/app.ini" mailer HOST "${MAIL_SMTP_SERVER}:${MAIL_SMTP_PORT}"
|
||||
crudini --set "/run/gitea/app.ini" mailer USER "${MAIL_SMTP_USERNAME}"
|
||||
crudini --set "/run/gitea/app.ini" mailer PASSWD "${MAIL_SMTP_PASSWORD}"
|
||||
crudini --set "/run/gitea/app.ini" mailer FROM "${MAIL_FROM}"
|
||||
crudini --set "/run/gitea/app.ini" mailer SKIP_VERIFY "true"
|
||||
crudini --set "/run/gitea/app.ini" mailer SMTP_ADDR "${CLOUDRON_MAIL_SMTP_SERVER}"
|
||||
crudini --set "/run/gitea/app.ini" mailer SMTP_PORT "${CLOUDRON_MAIL_SMTPS_PORT}"
|
||||
crudini --set "/run/gitea/app.ini" mailer PROTOCOL smtps
|
||||
crudini --set "/run/gitea/app.ini" mailer USER "${CLOUDRON_MAIL_SMTP_USERNAME}"
|
||||
crudini --set "/run/gitea/app.ini" mailer PASSWD "${CLOUDRON_MAIL_SMTP_PASSWORD}"
|
||||
crudini --set "/run/gitea/app.ini" mailer FROM "${CLOUDRON_MAIL_FROM_DISPLAY_NAME:-Gitea} <${CLOUDRON_MAIL_FROM}>"
|
||||
crudini --set "/run/gitea/app.ini" mailer FORCE_TRUST_SERVER_CERT "true"
|
||||
crudini --set "/run/gitea/app.ini" security INSTALL_LOCK "true"
|
||||
crudini --set "/run/gitea/app.ini" security REVERSE_PROXY_LIMIT 1
|
||||
crudini --set "/run/gitea/app.ini" security REVERSE_PROXY_TRUSTED_PROXIES "*"
|
||||
crudini --set "/run/gitea/app.ini" log MODE "console"
|
||||
crudini --set "/run/gitea/app.ini" log ROOT_PATH "/run/gitea"
|
||||
crudini --set "/run/gitea/app.ini" indexer ISSUE_INDEXER_PATH "/app/data/appdata/indexers/issues.bleve"
|
||||
|
||||
|
||||
mkdir -p /app/data/repository /app/data/ssh
|
||||
|
||||
echo "==> Creating dirs and changing permissions"
|
||||
mkdir -p /app/data/repository /app/data/ssh /app/data/custom /app/data/gnupg
|
||||
chown -R git:git /app/data /run/gitea
|
||||
|
||||
( setup_ldap_source ) &
|
||||
# this expects app.ini to be available
|
||||
( setup_auth ) &
|
||||
|
||||
exec /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf --nodaemon -i Gitea
|
||||
|
||||
|
|
|
@ -9,4 +9,4 @@ stdout_logfile=/dev/stdout
|
|||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
environment=HOME="/home/git",USER="git"
|
||||
environment=HOME="/home/git",USER="git",GITEA_CUSTOM="/app/data/custom"
|
||||
|
|
|
@ -8,4 +8,3 @@ stdout_logfile=/dev/stdout
|
|||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
ssh -o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ${SCRIPT_DIR}/id_rsa "$@"
|
||||
ssh -o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ${SCRIPT_DIR}/id_ed25519 "$@"
|
||||
|
|
7
test/id_ed25519
Normal file
7
test/id_ed25519
Normal file
|
@ -0,0 +1,7 @@
|
|||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACDECyFdxcmgOemNvs0wUhkgzfj9IS2OTG6bU5AXfNkXfgAAAJAoNQg/KDUI
|
||||
PwAAAAtzc2gtZWQyNTUxOQAAACDECyFdxcmgOemNvs0wUhkgzfj9IS2OTG6bU5AXfNkXfg
|
||||
AAAEC9nIZlzus9hn/b99E/cnSE2Vpycx0invItrrzgOX9qwMQLIV3FyaA56Y2+zTBSGSDN
|
||||
+P0hLY5MbptTkBd82Rd+AAAADW5lYnVsb25AbHVuYXI=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
test/id_ed25519.pub
Normal file
1
test/id_ed25519.pub
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQLIV3FyaA56Y2+zTBSGSDN+P0hLY5MbptTkBd82Rd+ nebulon@lunar
|
27
test/id_rsa
27
test/id_rsa
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA14L+HdwPXRHC2A+fyRv1FTsRE/OPl0Z0KnEigzIIdA65CzTy
|
||||
l3m3ATNFI1o/Ies7RW6rsr9UHuLLufNVg1NwIBdns8sPE4pSZSjfdPnznifIIs7y
|
||||
wL/vn2D3JEhpA8EOasSy0c+z+6X23evsLB3D81y7ICsBc16Q147WZ6D+QMUP+A4b
|
||||
wlmEcy0hAoPx/jnnPlRDVOK1ZnBvuAaHBkcBh+sA272BhB6Kv13MBu0wctDjKw5w
|
||||
cNmgVWbzBBtK1L8BZVMDKmKWZ2PKP4GkkpnAvkD0+4sdARe148faV8HHigAKKNN7
|
||||
vt+njs6nHuS4ksJL1E9cKGHdBJudJc3p24iI7QIDAQABAoIBABm5ojnQPek/KIIA
|
||||
A3PPKYc6QMSf60EEgPNcA+GjRE0OQNpsnJSmS8kR5KvepvCWksGr/0Tb/9+b9POi
|
||||
b0+40waRpKhakdckSMeYhGwDNihn2UUGbQXDI4hj27xyBE8VaXInPq063OIqInjF
|
||||
I7D0cKKJLDEf0RGDdUi13TQLjK4QX78W/9S8d5ClznAVi4wUBb1urs7fAoVetn/i
|
||||
PnlEj9KZHio4mCg28djTudAoWzjzUikRqKRYY5QNEJ13abVoLqIRSRHC1DzwpxVv
|
||||
Y88l4hmm6IcmWGo0O9lpu5IJFvEmngfpmyaVbeLE0fhLPFWcEHARw37SThTZVQeY
|
||||
Tx1816UCgYEA9j5dyNbFcC4YL9i9DQyut658bYziY2vsAvZNMMf249IJGbZOxlZK
|
||||
ylB00zlbO/2uNh12Y9z6BN2hO2lER3O3SM75tCnvXR0+qG+xmfjLcRVczEkU10+r
|
||||
8UxKBgg7Sf9uvfeONefEYPwiwzFoWgdaFSrR2sCmuoHPwfc9i+PSp+8CgYEA4Azq
|
||||
DToKdv6VBWPlNXT6OW3+HUPeHF087Ve03+3orCckZ+d2DImEOvWdt+pDeGQJJcq+
|
||||
o+SzZk9FjFOIiQehuA44OFrvcbag9YAlm1JQYYrRTdZEJz3iSucXCzJH/P5TrB84
|
||||
BHvzgCklZzZ0IpEFxzMe8oNS6XfJmilh6I98YOMCgYBybOy7xUGeLW1D3p2LENen
|
||||
t0dOyObyeFYF0lpwTpulphZgglz8wWCjvttqw/5nVCy+LNa09RyhYjPoHbSC13zW
|
||||
MofKdqoqRMq3DqAjAn/XHqwuqc8rdnRZ/q9vOigC7NWTJRRKbFbPEps8xRrOqxfr
|
||||
OiimVFul02ito6xP8yAStQKBgQDHbPdPup/h9wzx9U7p3Ct1vt/3cJddK+i1YeIP
|
||||
iBYYVebjzXSYCDd4u3MdZxmTKYey6dnyy/ibUmgXVassPWzHBXEpSFflIaf3nY7b
|
||||
x9LgX82ZuOSFAWJRRYyPXLwTBtW3WTplU2cUZotyaVfKBMfd3TToq9e7E/KQk9Eg
|
||||
Tcdp/QKBgCyKD1gGU/H1bsQOuWHuFR1v7v82V1DLVjyn5kllej0tlfTLO/5uUsEE
|
||||
SIjGHfTHxgpww9HN9BPyy8xdQMAc6p7UyvJAIyhg679AQBrMLLvhE5niaGu4jQOa
|
||||
ZVY6nZUQNCwgxJwnUkFnOyXDYjzjyxZOCAWPxghYbS+IEl1GzhZU
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXgv4d3A9dEcLYD5/JG/UVOxET84+XRnQqcSKDMgh0DrkLNPKXebcBM0UjWj8h6ztFbquyv1Qe4su581WDU3AgF2ezyw8TilJlKN90+fOeJ8gizvLAv++fYPckSGkDwQ5qxLLRz7P7pfbd6+wsHcPzXLsgKwFzXpDXjtZnoP5AxQ/4DhvCWYRzLSECg/H+Oec+VENU4rVmcG+4BocGRwGH6wDbvYGEHoq/XcwG7TBy0OMrDnBw2aBVZvMEG0rUvwFlUwMqYpZnY8o/gaSSmcC+QPT7ix0BF7Xjx9pXwceKAAoo03u+36eOzqce5LiSwkvUT1woYd0Em50lzenbiIjt girish@beast
|
3593
test/package-lock.json
generated
Normal file
3593
test/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,17 +8,11 @@
|
|||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"ejs": "^2.3.4",
|
||||
"expect.js": "^0.3.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^2.3.4",
|
||||
"rimraf": "^2.4.4",
|
||||
"superagent": "^1.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"selenium-server-standalone-jar": "^3.3.1",
|
||||
"selenium-webdriver": "^3.3.0",
|
||||
"superagent": "^1.8.5"
|
||||
"chromedriver": "^135.0.0",
|
||||
"expect.js": "^0.3.1",
|
||||
"mocha": "^11.1.0",
|
||||
"selenium-webdriver": "^4.31.0",
|
||||
"superagent": "^10.2.0"
|
||||
}
|
||||
}
|
||||
|
|
444
test/test.js
444
test/test.js
|
@ -1,267 +1,214 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/* jslint node:true */
|
||||
/* global it:false */
|
||||
/* global xit:false */
|
||||
/* global describe:false */
|
||||
/* global before:false */
|
||||
/* global after:false */
|
||||
/* jshint esversion: 8 */
|
||||
/* global it, xit, describe, before, after, afterEach */
|
||||
|
||||
'use strict';
|
||||
|
||||
var execSync = require('child_process').execSync,
|
||||
ejs = require('ejs'),
|
||||
require('chromedriver');
|
||||
|
||||
const execSync = require('child_process').execSync,
|
||||
expect = require('expect.js'),
|
||||
fs = require('fs'),
|
||||
mkdirp = require('mkdirp'),
|
||||
path = require('path'),
|
||||
rimraf = require('rimraf'),
|
||||
superagent = require('superagent'),
|
||||
webdriver = require('selenium-webdriver');
|
||||
{ Builder, By, until } = require('selenium-webdriver'),
|
||||
{ Options } = require('selenium-webdriver/chrome');
|
||||
|
||||
var by = require('selenium-webdriver').By,
|
||||
until = require('selenium-webdriver').until,
|
||||
Builder = require('selenium-webdriver').Builder;
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
if (!process.env.USERNAME || !process.env.PASSWORD || !process.env.EMAIL) {
|
||||
console.log('USERNAME, PASSWORD and EMAIL env vars need to be set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
describe('Application life cycle test', function () {
|
||||
this.timeout(0);
|
||||
var server, browser = new Builder().forBrowser('chrome').build();
|
||||
var LOCATION = 'test';
|
||||
var repodir = '/tmp/testrepo';
|
||||
var app, reponame = 'testrepo';
|
||||
var username = process.env.USERNAME;
|
||||
var password = process.env.PASSWORD;
|
||||
var TIMEOUT = parseInt(process.env.TIMEOUT, 10) || 5000;
|
||||
var email, token;
|
||||
|
||||
before(function (done) {
|
||||
if (!process.env.USERNAME) return done(new Error('USERNAME env var not set'));
|
||||
if (!process.env.PASSWORD) return done(new Error('PASSWORD env var not set'));
|
||||
const TIMEOUT = parseInt(process.env.TIMEOUT, 10) || 5000;
|
||||
const EXEC_ARGS = { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' };
|
||||
const LOCATION = process.env.LOCATION || 'test';
|
||||
const SSH_PORT = 29420;
|
||||
|
||||
var seleniumJar= require('selenium-server-standalone-jar');
|
||||
var SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
|
||||
server = new SeleniumServer(seleniumJar.path, { port: 4444 });
|
||||
server.start();
|
||||
let app, browser;
|
||||
|
||||
done();
|
||||
const repodir = '/tmp/testrepo';
|
||||
const reponame = 'testrepo';
|
||||
|
||||
const username = process.env.USERNAME;
|
||||
const password = process.env.PASSWORD;
|
||||
|
||||
before(function () {
|
||||
const chromeOptions = new Options().windowSize({ width: 1280, height: 1024 });
|
||||
if (process.env.CI) chromeOptions.addArguments('no-sandbox', 'disable-dev-shm-usage', 'headless');
|
||||
browser = new Builder().forBrowser('chrome').setChromeOptions(chromeOptions).build();
|
||||
if (!fs.existsSync('./screenshots')) fs.mkdirSync('./screenshots');
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
after(function () {
|
||||
browser.quit();
|
||||
server.stop();
|
||||
rimraf.sync(repodir);
|
||||
done();
|
||||
fs.rmSync(repodir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
function waitForUrl(url, done) {
|
||||
browser.wait(function () {
|
||||
return browser.getCurrentUrl().then(function (currentUrl) {
|
||||
return currentUrl === url;
|
||||
});
|
||||
}, TIMEOUT).then(function () { done(); });
|
||||
}
|
||||
afterEach(async function () {
|
||||
if (!process.env.CI || !app) return;
|
||||
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
if (!currentUrl.includes(app.domain)) return;
|
||||
expect(this.currentTest.title).to.be.a('string');
|
||||
|
||||
const screenshotData = await browser.takeScreenshot();
|
||||
fs.writeFileSync(`./screenshots/${new Date().getTime()}-${this.currentTest.title.replaceAll(' ', '_')}.png`, screenshotData, 'base64');
|
||||
});
|
||||
|
||||
function getAppInfo() {
|
||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||
|
||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0];
|
||||
|
||||
const inspect = JSON.parse(execSync('cloudron inspect'));
|
||||
app = inspect.apps.filter(function (a) { return a.location.indexOf(LOCATION) === 0; })[0];
|
||||
expect(app).to.be.an('object');
|
||||
}
|
||||
|
||||
function setAvatar(done) {
|
||||
browser.get('https://' + app.fqdn + '/user/settings/avatar').then(function () {
|
||||
return browser.findElement(by.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png'));
|
||||
}).then(function () {
|
||||
return browser.findElement(by.xpath('//button[contains(text(), "Update Avatar Setting")]')).click();
|
||||
}).then(function () {
|
||||
if (app.manifest.version === '1.0.3') {
|
||||
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(),"updated successfully")]')), TIMEOUT);
|
||||
} else {
|
||||
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(),"Your avatar setting has been updated.")]')), TIMEOUT);
|
||||
}
|
||||
}).then(function () {
|
||||
done();
|
||||
});
|
||||
async function waitForElement(elem) {
|
||||
await browser.wait(until.elementLocated(elem), TIMEOUT);
|
||||
await browser.wait(until.elementIsVisible(browser.findElement(elem)), TIMEOUT);
|
||||
}
|
||||
|
||||
function checkAvatar(done) {
|
||||
return done();
|
||||
superagent.get('https://' + app.fqdn + '/avatars/a3e6f3316fc1738e29d621e6a26e93d3').end(function (error, result) {
|
||||
expect(error).to.be(null);
|
||||
expect(result.statusCode).to.be(200);
|
||||
done();
|
||||
});
|
||||
function sleep(millis) {
|
||||
return new Promise(resolve => setTimeout(resolve, millis));
|
||||
}
|
||||
|
||||
function editFile(done) {
|
||||
browser.get('https://' + app.fqdn + '/' + username + '/' + reponame + '/_edit/master/newfile').then(function () {
|
||||
var cm = browser.findElement(by.xpath('//div[contains(@class,"CodeMirror")]'));
|
||||
var text = 'yo';
|
||||
return browser.executeScript('arguments[0].CodeMirror.setValue("' + text + '");', cm);
|
||||
}).then(function () {
|
||||
return browser.findElement(by.xpath('//input[@name="commit_summary"]')).sendKeys('Dummy edit');
|
||||
}).then(function () {
|
||||
return browser.findElement(by.xpath('//button[contains(text(), "Commit Changes")]')).click();
|
||||
}).then(function () {
|
||||
waitForUrl('https://' + app.fqdn + '/' + username + '/' + reponame + '/src/master/newfile', done);
|
||||
});
|
||||
async function setAvatar() {
|
||||
await browser.get('https://' + app.fqdn + '/user/settings');
|
||||
|
||||
var button = await browser.findElement(By.xpath('//label[contains(text(), "Use Custom Avatar")]'));
|
||||
await browser.executeScript('arguments[0].scrollIntoView(false)', button);
|
||||
await browser.findElement(By.xpath('//label[contains(text(), "Use Custom Avatar")]')).click();
|
||||
await browser.findElement(By.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png'));
|
||||
await browser.findElement(By.xpath('//button[contains(text(), "Update Avatar")]')).click();
|
||||
await browser.wait(until.elementLocated(By.xpath('//p[contains(text(),"Your avatar has been updated.")]')), TIMEOUT);
|
||||
}
|
||||
|
||||
function login(done) {
|
||||
browser.get('https://' + app.fqdn + '/user/login').then(function () {
|
||||
return browser.findElement(by.id('user_name')).sendKeys(username);
|
||||
}).then(function () {
|
||||
return browser.findElement(by.id('password')).sendKeys(password);
|
||||
}).then(function () {
|
||||
return browser.findElement(by.tagName('form')).submit();
|
||||
}).then(function () {
|
||||
return browser.wait(until.elementLocated(by.linkText('Dashboard')), TIMEOUT);
|
||||
}).then(function () {
|
||||
done();
|
||||
});
|
||||
async function checkAvatar() {
|
||||
await browser.get(`https://${app.fqdn}/${username}`);
|
||||
|
||||
const avatarSrc = await browser.findElement(By.xpath('//div[@id="profile-avatar"]/a/img')).getAttribute('src');
|
||||
|
||||
const response = await superagent.get(avatarSrc);
|
||||
expect(response.statusCode).to.equal(200);
|
||||
}
|
||||
|
||||
function addPublicKey(done) {
|
||||
var publicKey = fs.readFileSync(__dirname + '/id_rsa.pub', 'utf8');
|
||||
async function login(username, password) {
|
||||
await browser.get('https://' + app.fqdn + '/user/login');
|
||||
|
||||
var sshPage;
|
||||
if (app.manifest.version === '1.0.3') {
|
||||
sshPage = 'https://' + app.fqdn + '/user/settings/ssh';
|
||||
} else {
|
||||
sshPage = 'https://' + app.fqdn + '/user/settings/keys';
|
||||
await browser.findElement(By.id('user_name')).sendKeys(username);
|
||||
await browser.findElement(By.id('password')).sendKeys(password);
|
||||
await browser.findElement(By.xpath('//form[@action="/user/login"]//button')).click();
|
||||
await browser.wait(until.elementLocated(By.xpath('//img[contains(@class, "avatar")]')), TIMEOUT);
|
||||
}
|
||||
|
||||
async function adminLogin() {
|
||||
await login('root', 'changeme');
|
||||
}
|
||||
|
||||
async function loginOIDC(username, password, alreadyAuthenticated = true) {
|
||||
browser.manage().deleteAllCookies();
|
||||
await browser.get(`https://${app.fqdn}/user/login`);
|
||||
await browser.sleep(2000);
|
||||
|
||||
|
||||
await browser.findElement(By.xpath('//a[contains(@class, "openidConnect") and contains(., "Sign in with cloudron")]')).click();
|
||||
await browser.sleep(2000);
|
||||
|
||||
if (!alreadyAuthenticated) {
|
||||
await waitForElement(By.id('inputUsername'));
|
||||
await browser.findElement(By.id('inputUsername')).sendKeys(username);
|
||||
await browser.findElement(By.id('inputPassword')).sendKeys(password);
|
||||
await browser.sleep(2000);
|
||||
await browser.findElement(By.id('loginSubmitButton')).click();
|
||||
await browser.sleep(2000);
|
||||
}
|
||||
|
||||
browser.get(sshPage).then(function () {
|
||||
return browser.findElement(by.xpath('//div[text()="Add Key"]')).click();
|
||||
}).then(function () {
|
||||
return browser.findElement(by.id('ssh-key-title')).sendKeys('testkey');
|
||||
}).then(function () {
|
||||
return browser.findElement(by.id('ssh-key-content')).sendKeys(publicKey.trim()); // #3480
|
||||
}).then(function () {
|
||||
var button = browser.findElement(by.xpath('//button[contains(text(), "Add Key")]'));
|
||||
return browser.executeScript('arguments[0].scrollIntoView(false)', button);
|
||||
}).then(function () {
|
||||
return browser.findElement(by.xpath('//button[contains(text(), "Add Key")]')).click();
|
||||
}).then(function () {
|
||||
if (app.manifest.version === '1.0.3') {
|
||||
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(), "added successfully!")]')), TIMEOUT);
|
||||
} else {
|
||||
return browser.wait(until.elementLocated(by.xpath('//p[contains(text(), "has been added.")]')), TIMEOUT);
|
||||
}
|
||||
}).then(function () {
|
||||
done();
|
||||
});
|
||||
await waitForElement(By.xpath('//img[contains(@class, "avatar")]'));
|
||||
}
|
||||
|
||||
function createRepo(done) {
|
||||
var getRepoPage;
|
||||
if (app.manifest.version === '1.0.3') {
|
||||
getRepoPage = browser.get('https://' + app.fqdn).then(function () {
|
||||
return browser.findElement(by.linkText('New Repository')).click();
|
||||
}).then(function () {
|
||||
return browser.wait(until.elementLocated(by.xpath('//*[contains(text(), "New Repository")]')), TIMEOUT);
|
||||
async function logout() {
|
||||
await browser.get('https://' + app.fqdn);
|
||||
|
||||
await browser.findElement(By.xpath('//img[contains(@class, "avatar")]')).click();
|
||||
await sleep(2000);
|
||||
await browser.findElement(By.xpath('//a[@data-url="/user/logout"]')).click();
|
||||
await sleep(2000);
|
||||
}
|
||||
|
||||
async function addPublicKey() {
|
||||
const publicKey = fs.readFileSync(__dirname + '/id_ed25519.pub', 'utf8');
|
||||
execSync(`chmod g-rw,o-rw ${__dirname}/id_ed25519`); // ssh will complain about perms later
|
||||
|
||||
await browser.get('https://' + app.fqdn + '/user/settings/keys');
|
||||
|
||||
await browser.wait(until.elementLocated(By.id('add-ssh-button')), TIMEOUT);
|
||||
await browser.findElement(By.id('add-ssh-button')).click();
|
||||
await browser.findElement(By.id('ssh-key-title')).sendKeys('testkey');
|
||||
await browser.findElement(By.id('ssh-key-content')).sendKeys(publicKey.trim()); // #3480
|
||||
var button = browser.findElement(By.xpath('//button[contains(text(), "Add Key")]'));
|
||||
await browser.executeScript('arguments[0].scrollIntoView(false)', button);
|
||||
await browser.findElement(By.xpath('//form//button[contains(text(),"Add Key")]')).click();
|
||||
|
||||
await browser.wait(until.elementLocated(By.xpath('//p[contains(text(), "has been added.")]')), TIMEOUT);
|
||||
}
|
||||
|
||||
async function createRepo() {
|
||||
await browser.get(`https://${app.fqdn}/repo/create`);
|
||||
await browser.wait(until.elementLocated(By.id('repo_name')));
|
||||
await browser.findElement(By.id('repo_name')).sendKeys(reponame);
|
||||
var button = browser.findElement(By.xpath('//button[contains(text(), "Create Repository")]'));
|
||||
await browser.executeScript('arguments[0].scrollIntoView(true)', button);
|
||||
await browser.findElement(By.id('auto-init')).click();
|
||||
await browser.findElement(By.xpath('//button[contains(text(), "Create Repository")]')).click();
|
||||
|
||||
await browser.wait(function () {
|
||||
return browser.getCurrentUrl().then(function (url) {
|
||||
return url === 'https://' + app.fqdn + '/' + username + '/' + reponame;
|
||||
});
|
||||
} else {
|
||||
getRepoPage = browser.get('https://' + app.fqdn + '/repo/create');
|
||||
}
|
||||
|
||||
getRepoPage.then(function () {
|
||||
return browser.findElement(by.id('repo_name')).sendKeys(reponame);
|
||||
}).then(function () {
|
||||
var button = browser.findElement(by.xpath('//button[contains(text(), "Create Repository")]'));
|
||||
return browser.executeScript('arguments[0].scrollIntoView(true)', button);
|
||||
}).then(function () {
|
||||
return browser.findElement(by.id('auto-init')).click();
|
||||
}).then(function () {
|
||||
return browser.findElement(by.xpath('//button[contains(text(), "Create Repository")]')).click();
|
||||
}).then(function () {
|
||||
browser.wait(function () {
|
||||
return browser.getCurrentUrl().then(function (url) {
|
||||
return url === 'https://' + app.fqdn + '/' + username + '/' + reponame;
|
||||
});
|
||||
}, TIMEOUT);
|
||||
}).then(function () {
|
||||
done();
|
||||
});
|
||||
}, TIMEOUT);
|
||||
}
|
||||
|
||||
function checkCloneUrl(done) {
|
||||
browser.get('https://' + app.fqdn + '/' + username + '/' + reponame).then(function () {
|
||||
return browser.findElement(by.id('repo-clone-ssh')).click();
|
||||
}).then(function () {
|
||||
return browser.findElement(by.id('repo-clone-url')).getAttribute('value');
|
||||
}).then(function (cloneUrl) {
|
||||
expect(cloneUrl).to.be('ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + '.git');
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function cloneRepo(done) {
|
||||
rimraf.sync(repodir);
|
||||
function cloneRepo() {
|
||||
fs.rmSync(repodir, { recursive: true, force: true });
|
||||
var env = Object.create(process.env);
|
||||
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
||||
execSync('git clone ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + '.git ' + repodir, { env: env });
|
||||
done();
|
||||
execSync(`git clone ssh://git@${app.fqdn}:${SSH_PORT}/${username}/${reponame}.git ${repodir}`, { env: env });
|
||||
}
|
||||
|
||||
function pushFile(done) {
|
||||
var env = Object.create(process.env);
|
||||
function pushFile() {
|
||||
const env = Object.create(process.env);
|
||||
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
||||
execSync('touch newfile && git add newfile && git commit -a -mx && git push ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + ' master',
|
||||
execSync(`touch newfile && git add newfile && git commit -a -mx && git push ssh://git@${app.fqdn}:${SSH_PORT}/${username}/${reponame} main`,
|
||||
{ env: env, cwd: repodir });
|
||||
rimraf.sync('/tmp/testrepo');
|
||||
done();
|
||||
fs.rmSync(repodir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
function fileExists() {
|
||||
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
||||
}
|
||||
|
||||
xit('build app', function () {
|
||||
execSync('cloudron build', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
async function sendMail() {
|
||||
await browser.get(`https://${app.fqdn}/-/admin/config`);
|
||||
await browser.sleep(3000);
|
||||
const button = await browser.findElement(By.xpath('//button[contains(., "Send")]'));
|
||||
await browser.executeScript('arguments[0].scrollIntoView(true)', button);
|
||||
await browser.findElement(By.xpath('//input[@name="email"]')).sendKeys('test@cloudron.io');
|
||||
await browser.findElement(By.xpath('//button[contains(., "Send")]')).click();
|
||||
await browser.wait(until.elementLocated(By.xpath('//p[contains(., "A testing email has been sent")]')), TIMEOUT);
|
||||
}
|
||||
|
||||
it('can login', function (done) {
|
||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||
|
||||
superagent.post('https://' + inspect.apiEndpoint + '/api/v1/developer/login').send({
|
||||
username: username,
|
||||
password: password
|
||||
}).end(function (error, result) {
|
||||
if (error) return done(error);
|
||||
if (result.statusCode !== 200) return done(new Error('Login failed with status ' + result.statusCode));
|
||||
|
||||
token = result.body.token;
|
||||
|
||||
superagent.get('https://' + inspect.apiEndpoint + '/api/v1/profile')
|
||||
.query({ access_token: token }).end(function (error, result) {
|
||||
if (error) return done(error);
|
||||
if (result.statusCode !== 200) return done(new Error('Get profile failed with status ' + result.statusCode));
|
||||
|
||||
email = result.body.email;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('install app', function () {
|
||||
execSync('cloudron install --new --wait --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
xit('build app', function () { execSync('cloudron build', EXEC_ARGS); });
|
||||
it('install app', function () { execSync(`cloudron install --location ${LOCATION} -p SSH_PORT=${SSH_PORT}`, EXEC_ARGS); });
|
||||
|
||||
it('can get app information', getAppInfo);
|
||||
it('can get the main page', function (done) {
|
||||
superagent.get('https://' + app.fqdn).end(function (error, result) {
|
||||
expect(error).to.be(null);
|
||||
expect(result.status).to.eql(200);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('can admin login', adminLogin);
|
||||
it('can send mail', sendMail);
|
||||
it('can logout', logout);
|
||||
|
||||
it('can login', login);
|
||||
it('can login', loginOIDC.bind(null, username, password, false));
|
||||
it('can set avatar', setAvatar);
|
||||
it('can get avatar', checkAvatar);
|
||||
|
||||
|
@ -269,76 +216,61 @@ return done();
|
|||
|
||||
it('can create repo', createRepo);
|
||||
|
||||
it('displays correct clone url', checkCloneUrl);
|
||||
|
||||
it('can clone the url', cloneRepo);
|
||||
|
||||
it('can add and push a file', pushFile);
|
||||
it('can edit file', editFile);
|
||||
|
||||
it('can restart app', function (done) {
|
||||
execSync('cloudron restart --wait');
|
||||
done();
|
||||
});
|
||||
it('can restart app', function () { execSync('cloudron restart --app ' + app.id); });
|
||||
|
||||
it('can login', login);
|
||||
it('displays correct clone url', checkCloneUrl);
|
||||
xit('can login', loginOIDC.bind(null, username, password)); // no need to relogin since session persists
|
||||
it('can clone the url', cloneRepo);
|
||||
it('file exists in repo', fileExists);
|
||||
|
||||
it('backup app', function () {
|
||||
execSync('cloudron backup create --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
it('backup app', function () { execSync('cloudron backup create --app ' + app.id, EXEC_ARGS); });
|
||||
it('restore app', function () { execSync('cloudron restore --app ' + app.id, EXEC_ARGS); });
|
||||
|
||||
it('restore app', function () {
|
||||
execSync('cloudron restore --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
|
||||
it('can login', login);
|
||||
it('can login', loginOIDC.bind(null, username, password));
|
||||
it('can get avatar', checkAvatar);
|
||||
it('can clone the url', cloneRepo);
|
||||
it('file exists in repo', function () { expect(fs.existsSync(repodir + '/newfile')).to.be(true); });
|
||||
|
||||
it('move to different location', function () {
|
||||
browser.manage().deleteAllCookies();
|
||||
execSync('cloudron configure --wait --location ' + LOCATION + '2', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION + '2'; })[0];
|
||||
expect(app).to.be.an('object');
|
||||
});
|
||||
it('move to different location', async function () {
|
||||
//browser.manage().deleteAllCookies(); // commented because of error "'Network.deleteCookie' wasn't found"
|
||||
// ensure we don't hit NXDOMAIN in the mean time
|
||||
await browser.get('about:blank');
|
||||
|
||||
it('can login', login);
|
||||
execSync('cloudron configure --location ' + LOCATION + '2 --app ' + app.id, EXEC_ARGS);
|
||||
});
|
||||
it('can get app information', getAppInfo);
|
||||
|
||||
it('can login', loginOIDC.bind(null, username, password));
|
||||
it('can get avatar', checkAvatar);
|
||||
it('displays correct clone url', checkCloneUrl);
|
||||
it('can clone the url', cloneRepo);
|
||||
it('file exists in repo', function () { expect(fs.existsSync(repodir + '/newfile')).to.be(true); });
|
||||
|
||||
it('uninstall app', function () {
|
||||
execSync('cloudron uninstall --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
it('uninstall app', async function () {
|
||||
// ensure we don't hit NXDOMAIN in the mean time
|
||||
await browser.get('about:blank');
|
||||
execSync('cloudron uninstall --app ' + app.id, EXEC_ARGS);
|
||||
});
|
||||
|
||||
// check if the _first_ login via email succeeds
|
||||
it('can login via email', function (done) {
|
||||
execSync('cloudron install --new --wait --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||
// No SSO
|
||||
it('install app (no sso)', function () { execSync(`cloudron install --no-sso --location ${LOCATION} -p SSH_PORT=${SSH_PORT}`, EXEC_ARGS); });
|
||||
|
||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0];
|
||||
expect(app).to.be.an('object');
|
||||
it('can get app information', getAppInfo);
|
||||
it('can admin login (no sso)', adminLogin);
|
||||
it('can logout', logout);
|
||||
|
||||
login(function (error) {
|
||||
if (error) return done(error);
|
||||
execSync('cloudron uninstall --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
done();
|
||||
});
|
||||
it('uninstall app (no sso)', async function () {
|
||||
await browser.get('about:blank');
|
||||
execSync('cloudron uninstall --app ' + app.id, EXEC_ARGS);
|
||||
});
|
||||
|
||||
// test update
|
||||
it('can install app', function () {
|
||||
execSync('cloudron install --new --wait --appstore-id ' + app.manifest.id + ' --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
it('can install app', function () { execSync(`cloudron install --appstore-id ${app.manifest.id} --location ${LOCATION} -p SSH_PORT=${SSH_PORT}`, EXEC_ARGS); });
|
||||
|
||||
it('can get app information', getAppInfo);
|
||||
it('can login', login);
|
||||
it('can login', loginOIDC.bind(null, username, password));
|
||||
it('can set avatar', setAvatar);
|
||||
it('can get avatar', checkAvatar);
|
||||
it('can add public key', addPublicKey);
|
||||
|
@ -346,15 +278,21 @@ return done();
|
|||
it('can clone the url', cloneRepo);
|
||||
it('can add and push a file', pushFile);
|
||||
|
||||
it('can update', function () {
|
||||
execSync('cloudron install --wait --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
});
|
||||
it('can update', function () { execSync('cloudron update --app ' + app.id, EXEC_ARGS); });
|
||||
it('can get app information', getAppInfo);
|
||||
|
||||
it('can admin login', adminLogin);
|
||||
it('can send mail', sendMail);
|
||||
it('can logout', logout);
|
||||
|
||||
it('can login', loginOIDC.bind(null, username, password));
|
||||
it('can get avatar', checkAvatar);
|
||||
it('can clone the url', cloneRepo);
|
||||
it('file exists in cloned repo', fileExists);
|
||||
|
||||
it('uninstall app', function () {
|
||||
execSync('cloudron uninstall --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
||||
it('uninstall app', async function () {
|
||||
// ensure we don't hit NXDOMAIN in the mean time
|
||||
await browser.get('about:blank');
|
||||
execSync('cloudron uninstall --app ' + app.id, EXEC_ARGS);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue