mirror of
https://git.cloudron.io/cloudron/gitea-app.git
synced 2024-09-27 22:01:53 +00:00
Compare commits
373 commits
Author | SHA1 | Date | |
---|---|---|---|
|
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 | ||
|
619bd735a6 | ||
|
a59430be60 | ||
|
3e04f6b996 | ||
|
7481ed9f60 | ||
|
93e8df020f | ||
|
2329c01ba5 | ||
|
bf67824fa6 | ||
|
795e6efb0a | ||
|
d984b4fe6c | ||
|
6a90609565 | ||
|
c67b13585f | ||
|
24d40b7912 | ||
|
83ca72d103 | ||
|
8b65c0a5db | ||
|
8685d0606a | ||
|
355ee698dc | ||
|
b8b3abfbfc | ||
|
3970139ea7 | ||
|
9b4fb46cf3 | ||
|
4357f4b3b9 | ||
|
821c13e7eb | ||
|
a03fb92253 | ||
|
c636d1dd87 | ||
|
5ecde5c49b | ||
|
47a9de45c9 | ||
|
cc112ff9bb | ||
|
8b7ec669bc | ||
|
6ab83644d7 | ||
|
5827bf87a7 | ||
|
b4156a8192 | ||
|
f89a2ab8d4 | ||
|
5522fc9398 | ||
|
240716671d |
20 changed files with 5232 additions and 360 deletions
|
@ -1,3 +0,0 @@
|
||||||
[0.1.0]
|
|
||||||
* Initial package (forked from Gogs app)
|
|
||||||
|
|
1631
CHANGELOG.md
Normal file
1631
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,14 +4,16 @@
|
||||||
"author": "Gitea developers",
|
"author": "Gitea developers",
|
||||||
"description": "file://DESCRIPTION.md",
|
"description": "file://DESCRIPTION.md",
|
||||||
"tagline": "A painless self-hosted Git Service",
|
"tagline": "A painless self-hosted Git Service",
|
||||||
"version": "0.1.0",
|
"version": "1.33.2",
|
||||||
"healthCheckPath": "/healthcheck",
|
"upstreamVersion": "1.22.2",
|
||||||
|
"healthCheckPath": "/explore",
|
||||||
"httpPort": 3000,
|
"httpPort": 3000,
|
||||||
|
"memoryLimit": 536870912,
|
||||||
"addons": {
|
"addons": {
|
||||||
"mysql": { },
|
"mysql": { },
|
||||||
"sendmail": { },
|
"sendmail": { "supportsDisplayName": true },
|
||||||
"localstorage": { },
|
"localstorage": { },
|
||||||
"ldap": { }
|
"oidc": { "loginRedirectUri": "/user/oauth2/cloudron/callback" }
|
||||||
},
|
},
|
||||||
"tcpPorts": {
|
"tcpPorts": {
|
||||||
"SSH_PORT": {
|
"SSH_PORT": {
|
||||||
|
@ -20,22 +22,22 @@
|
||||||
"defaultValue": 29418
|
"defaultValue": 29418
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"manifestVersion": 1,
|
"manifestVersion": 2,
|
||||||
"website": "https://gitea.io",
|
"website": "https://gitea.io",
|
||||||
"contactEmail": "apps@cloudron.io",
|
"contactEmail": "apps@cloudron.io",
|
||||||
"icon": "file://logo.png",
|
"icon": "file://logo.png",
|
||||||
|
"optionalSso": true,
|
||||||
"mediaLinks": [
|
"mediaLinks": [
|
||||||
"https://i.imgur.com/3iEQsux.jpg",
|
"https://screenshots.cloudron.io/io.gitea.cloudronapp/1.png",
|
||||||
"https://i.imgur.com/glqFnj8.jpg",
|
"https://screenshots.cloudron.io/io.gitea.cloudronapp/2.png",
|
||||||
"https://i.imgur.com/ad1FEpi.jpg",
|
"https://screenshots.cloudron.io/io.gitea.cloudronapp/3.png",
|
||||||
"https://i.imgur.com/q81EcGa.jpg",
|
"https://screenshots.cloudron.io/io.gitea.cloudronapp/4.png",
|
||||||
"https://i.imgur.com/L2CQeN0.jpg",
|
"https://screenshots.cloudron.io/io.gitea.cloudronapp/5.png"
|
||||||
"https://i.imgur.com/cNuvMum.jpg",
|
|
||||||
"https://i.imgur.com/xCYRqaF.jpg",
|
|
||||||
"https://i.imgur.com/ILpRBCe.jpg",
|
|
||||||
"https://i.imgur.com/0BHnrcL.jpg"
|
|
||||||
],
|
],
|
||||||
"tags": [ "version control", "git", "code hosting", "development" ],
|
"tags": [ "version control", "git", "code hosting", "development", "github", "bitbucket", "gitlab" ],
|
||||||
"changelog": "file://CHANGELOG",
|
"changelog": "file://CHANGELOG.md",
|
||||||
"postInstallMessage": "file://POSTINSTALL.md"
|
"postInstallMessage": "file://POSTINSTALL.md",
|
||||||
|
"minBoxVersion": "7.5.1",
|
||||||
|
"forumUrl": "https://forum.cloudron.io/category/19/gitea",
|
||||||
|
"documentationUrl": "https://docs.cloudron.io/apps/gitea/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket or Gitlab. The initial development have been done on Gogs but we have forked it and named it Gitea. If you want to read more about the reasons why we have done that please read this blog post.
|
Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket or Gitlab.
|
||||||
|
|
||||||
This app packages Gogs <upstream>1.1.1</upstream>
|
|
||||||
|
|
||||||
### Purpose
|
### Purpose
|
||||||
|
|
||||||
|
@ -20,9 +18,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
|
||||||
- Gravatar and custom source
|
- Gravatar and custom source
|
||||||
- Mail service
|
- Mail service
|
||||||
- Administration panel
|
- Administration panel
|
||||||
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
|
|
||||||
- Multi-language support ([15 languages](https://crowdin.com/project/gogs))
|
|
||||||
|
|
||||||
### Bug reports
|
### Bug reports
|
||||||
|
|
||||||
Open bugs on [Github](https://git.cloudron.io/dswd/gitea-app/issues)
|
Open bugs on [Github](https://git.cloudron.io/cloudron/gitea-app/issues)
|
||||||
|
|
19
Dockerfile
19
Dockerfile
|
@ -1,11 +1,10 @@
|
||||||
FROM cloudron/base:0.10.0
|
FROM cloudron/base:4.2.0@sha256:46da2fffb36353ef714f97ae8e962bd2c212ca091108d768ba473078319a47f4
|
||||||
|
|
||||||
ENV VERSION 1.1.1
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y openssh-server && \
|
apt-get install -y openssh-server git asciidoctor pandoc && \
|
||||||
rm -rf /etc/ssh_host_* && \
|
rm -rf /etc/ssh_host_* && \
|
||||||
rm -r /var/cache/apt /var/lib/apt/lists
|
rm -r /var/cache/apt /var/lib/apt/lists
|
||||||
|
RUN pip3 install jupyter
|
||||||
|
|
||||||
ADD supervisor/ /etc/supervisor/conf.d/
|
ADD supervisor/ /etc/supervisor/conf.d/
|
||||||
|
|
||||||
|
@ -15,7 +14,13 @@ RUN adduser --disabled-login --gecos 'Gitea' git
|
||||||
RUN passwd -d git
|
RUN passwd -d git
|
||||||
|
|
||||||
RUN mkdir -p /home/git/gitea
|
RUN mkdir -p /home/git/gitea
|
||||||
## TODO: use redis as well
|
WORKDIR /home/git
|
||||||
|
|
||||||
|
# for autosign feature
|
||||||
|
ENV GNUPGHOME="/app/data/gnupg"
|
||||||
|
|
||||||
|
ARG VERSION=1.22.2
|
||||||
|
|
||||||
RUN curl -L https://dl.gitea.io/gitea/${VERSION}/gitea-${VERSION}-linux-amd64 -o /home/git/gitea/gitea \
|
RUN curl -L https://dl.gitea.io/gitea/${VERSION}/gitea-${VERSION}-linux-amd64 -o /home/git/gitea/gitea \
|
||||||
&& chmod +x /home/git/gitea/gitea
|
&& chmod +x /home/git/gitea/gitea
|
||||||
|
|
||||||
|
@ -31,9 +36,7 @@ RUN ln -s /app/data/gitconfig /home/git/.gitconfig
|
||||||
|
|
||||||
ADD start.sh /home/git/start.sh
|
ADD start.sh /home/git/start.sh
|
||||||
|
|
||||||
# disable pam authentication for sshd
|
COPY sshd_config /etc/ssh/sshd_config
|
||||||
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
|
|
||||||
|
|
||||||
CMD [ "/home/git/start.sh" ]
|
CMD [ "/home/git/start.sh" ]
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
This app integrates with the Cloudron SSO. Admins on Cloudron automatically
|
This app is pre-setup with an admin account. The initial credentials are:
|
||||||
become admins on Gitea.
|
|
||||||
|
|
||||||
If you want to disable Cloudron SSO, do the following:
|
**Username**: root<br/>
|
||||||
|
**Password**: changeme<br/>
|
||||||
|
|
||||||
* Admin Panel -> Authentication -> 'cloudron' -> Uncheck 'This authentication is activated'
|
Please change the admin password immediately.
|
||||||
* Admin Panel -> Users -> Change Authentication Source to 'Local' and also give a password
|
|
||||||
|
|
||||||
You can create a `/app/data/app.ini` with any custom configuration. See the
|
|
||||||
[configuration cheat sheet](https://docs.gitea.io/en-us/config-cheat-sheet)
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
|
<sso>
|
||||||
|
Use the `Local` authentication source for logging in as admin.
|
||||||
|
</sso>
|
||||||
|
|
|
@ -2,7 +2,9 @@ APP_NAME = Gitea
|
||||||
RUN_USER = git
|
RUN_USER = git
|
||||||
RUN_MODE = prod
|
RUN_MODE = prod
|
||||||
|
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
|
; those settings are protected and can't be modified
|
||||||
DB_TYPE = mysql
|
DB_TYPE = mysql
|
||||||
HOST = ##MYSQL_HOST:##MYSQL_PORT
|
HOST = ##MYSQL_HOST:##MYSQL_PORT
|
||||||
NAME = ##MYSQL_DATABASE
|
NAME = ##MYSQL_DATABASE
|
||||||
|
@ -11,7 +13,9 @@ PASSWD = ##MYSQL_PASSWORD
|
||||||
SSL_MODE = disable
|
SSL_MODE = disable
|
||||||
PATH =
|
PATH =
|
||||||
|
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
|
; those settings are protected and can't be modified
|
||||||
PROTOCOL = http
|
PROTOCOL = http
|
||||||
DOMAIN = ##DOMAIN
|
DOMAIN = ##DOMAIN
|
||||||
ROOT_URL = https://%(DOMAIN)s/
|
ROOT_URL = https://%(DOMAIN)s/
|
||||||
|
@ -20,55 +24,111 @@ HTTP_PORT = 3000
|
||||||
DISABLE_SSH = ##DISABLE_SSH
|
DISABLE_SSH = ##DISABLE_SSH
|
||||||
SSH_PORT = ##SSH_PORT
|
SSH_PORT = ##SSH_PORT
|
||||||
APP_DATA_PATH = /app/data/appdata
|
APP_DATA_PATH = /app/data/appdata
|
||||||
|
|
||||||
; Landing page for non-logged users, can be "home" or "explore"
|
; Landing page for non-logged users, can be "home" or "explore"
|
||||||
LANDING_PAGE = explore
|
LANDING_PAGE = explore
|
||||||
|
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
|
; this setting is protected and can't be modified
|
||||||
ROOT = /app/data/repository
|
ROOT = /app/data/repository
|
||||||
|
|
||||||
SCRIPT_TYPE = bash
|
SCRIPT_TYPE = bash
|
||||||
|
|
||||||
|
|
||||||
[repository.upload]
|
[repository.upload]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
|
; this setting is protected and can't be modified
|
||||||
TEMP_PATH = /run/gitea/tmp/uploads
|
TEMP_PATH = /run/gitea/tmp/uploads
|
||||||
|
|
||||||
|
|
||||||
[release.attachment]
|
[release.attachment]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
; APP_DATA_PATH/attachments
|
; APP_DATA_PATH/attachments
|
||||||
PATH =
|
PATH =
|
||||||
|
|
||||||
|
[oauth2_client]
|
||||||
|
ENABLE_AUTO_REGISTRATION = true
|
||||||
|
USERNAME = sub
|
||||||
|
UPDATE_AVATAR = false
|
||||||
|
ACCOUNT_LINKING = auto
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
HOST = ##MAIL_SERVER:##MAIL_PORT
|
|
||||||
|
; those settings are protected and can't be modified
|
||||||
|
SMTP_ADDR = ##MAIL_SERVER
|
||||||
|
SMTP_PORT = ##MAIL_PORT
|
||||||
USER = ##MAIL_SMTP_USERNAME
|
USER = ##MAIL_SMTP_USERNAME
|
||||||
PASSWD = ##MAIL_SMTP_PASSWORD
|
PASSWD = ##MAIL_SMTP_PASSWORD
|
||||||
FROM = ##MAIL_FROM
|
FROM = ##MAIL_FROM
|
||||||
SKIP_VERIFY = true
|
PROTOCOL = smtps
|
||||||
|
FORCE_TRUST_SERVER_CERT = true
|
||||||
|
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
|
; those settings are protected and can't be modified
|
||||||
INSTALL_LOCK = true
|
INSTALL_LOCK = true
|
||||||
SECRET_KEY = ##SECRET_KEY
|
SECRET_KEY = ##SECRET_KEY
|
||||||
|
REVERSE_PROXY_LIMIT = 1
|
||||||
|
REVERSE_PROXY_TRUSTED_PROXIES = *
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
DISABLE_REGISTRATION = false
|
DISABLE_REGISTRATION = false
|
||||||
SHOW_REGISTRATION_BUTTON = false
|
SHOW_REGISTRATION_BUTTON = false
|
||||||
ENABLE_NOTIFY_MAIL = true
|
ENABLE_NOTIFY_MAIL = true
|
||||||
|
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
; those settings are protected and can't be modified
|
||||||
MODE = console
|
MODE = console
|
||||||
; used for xorm.log
|
; used for xorm.log
|
||||||
ROOT_PATH = /run/gitea
|
ROOT_PATH = /run/gitea
|
||||||
|
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
; APP_DATA_PATH/avatars
|
; APP_DATA_PATH/avatars
|
||||||
AVATAR_UPLOAD_PATH =
|
AVATAR_UPLOAD_PATH =
|
||||||
GRAVATAR_SOURCE = gravatar
|
GRAVATAR_SOURCE = gravatar
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
|
|
||||||
|
|
||||||
[attachment]
|
[attachment]
|
||||||
ENABLE = true
|
ENABLE = true
|
||||||
; APP_DATA_PATH/attachments
|
; APP_DATA_PATH/attachments
|
||||||
PATH =
|
PATH =
|
||||||
|
|
||||||
|
|
||||||
[indexer]
|
[indexer]
|
||||||
|
; this setting is protected and can't be modified
|
||||||
ISSUE_INDEXER_PATH = /app/data/appdata/indexers/issues.bleve
|
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
|
||||||
|
|
BIN
logo.png
BIN
logo.png
Binary file not shown.
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 8.9 KiB |
80
sshd_config
Normal file
80
sshd_config
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# Package generated configuration file
|
||||||
|
# See the sshd_config(5) manpage for details
|
||||||
|
|
||||||
|
# What ports, IPs and protocols we listen for
|
||||||
|
Port 29418
|
||||||
|
# Use these options to restrict which interfaces/protocols sshd will bind to
|
||||||
|
ListenAddress 0.0.0.0
|
||||||
|
ListenAddress ::
|
||||||
|
Protocol 2
|
||||||
|
# HostKeys for protocol version 2
|
||||||
|
HostKey /app/data/sshd/ssh_host_rsa_key
|
||||||
|
HostKey /app/data/sshd/ssh_host_dsa_key
|
||||||
|
HostKey /app/data/sshd/ssh_host_ecdsa_key
|
||||||
|
HostKey /app/data/sshd/ssh_host_ed25519_key
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
SyslogFacility AUTH
|
||||||
|
LogLevel INFO
|
||||||
|
|
||||||
|
# Authentication:
|
||||||
|
LoginGraceTime 120
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
StrictModes yes
|
||||||
|
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
#AuthorizedKeysFile %h/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||||
|
IgnoreRhosts yes
|
||||||
|
# similar for protocol version 2
|
||||||
|
HostbasedAuthentication no
|
||||||
|
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
|
||||||
|
#IgnoreUserKnownHosts yes
|
||||||
|
|
||||||
|
# To enable empty passwords, change to yes (NOT RECOMMENDED)
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
|
||||||
|
# Change to yes to enable challenge-response passwords (beware issues with
|
||||||
|
# some PAM modules and threads)
|
||||||
|
ChallengeResponseAuthentication no
|
||||||
|
|
||||||
|
# Change to no to disable tunnelled clear text passwords
|
||||||
|
#PasswordAuthentication yes
|
||||||
|
|
||||||
|
# Kerberos options
|
||||||
|
#KerberosAuthentication no
|
||||||
|
#KerberosGetAFSToken no
|
||||||
|
#KerberosOrLocalPasswd yes
|
||||||
|
#KerberosTicketCleanup yes
|
||||||
|
|
||||||
|
# GSSAPI options
|
||||||
|
#GSSAPIAuthentication no
|
||||||
|
#GSSAPICleanupCredentials yes
|
||||||
|
|
||||||
|
X11Forwarding yes
|
||||||
|
X11DisplayOffset 10
|
||||||
|
PrintMotd no
|
||||||
|
PrintLastLog yes
|
||||||
|
TCPKeepAlive yes
|
||||||
|
#UseLogin no
|
||||||
|
|
||||||
|
#MaxStartups 10:30:60
|
||||||
|
#Banner /etc/issue.net
|
||||||
|
|
||||||
|
# Allow client to pass locale environment variables
|
||||||
|
AcceptEnv LANG LC_*
|
||||||
|
|
||||||
|
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||||
|
|
||||||
|
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||||
|
# and session processing. If this is enabled, PAM authentication will
|
||||||
|
# be allowed through the ChallengeResponseAuthentication and
|
||||||
|
# PasswordAuthentication. Depending on your PAM configuration,
|
||||||
|
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||||
|
# the setting of "PermitRootLogin without-password".
|
||||||
|
# If you just want the PAM account and session checks to run without
|
||||||
|
# PAM authentication, then enable this but set PasswordAuthentication
|
||||||
|
# and ChallengeResponseAuthentication to 'no'.
|
||||||
|
UsePAM no
|
||||||
|
UseDNS no
|
118
start.sh
118
start.sh
|
@ -2,29 +2,49 @@
|
||||||
|
|
||||||
set -eu -o pipefail
|
set -eu -o pipefail
|
||||||
|
|
||||||
mkdir -p /run/gitea/tmp/uploads
|
mkdir -p /run/gitea/tmp/uploads /run/sshd /run/gitea/sessions
|
||||||
|
|
||||||
setup_ldap_source() {
|
setup_oidc_source() {
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
# Wait for gitea to finish db setup, before we insert ldap source in db
|
echo "==> Setup OIDC source"
|
||||||
while ! curl --fail http://localhost:3000/healthcheck; do
|
|
||||||
echo "Waiting for gitea to come up"
|
now=$(date +%s)
|
||||||
|
mysql -u"${CLOUDRON_MYSQL_USERNAME}" -p"${CLOUDRON_MYSQL_PASSWORD}" -h mysql --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
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
now=$(date +%s)
|
echo "==> Gitea is up, setting up auth"
|
||||||
|
|
||||||
# Get the existing LDAP source status. This allows the user to disable LDAP
|
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
|
||||||
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';")
|
setup_oidc_source
|
||||||
[[ -z "${ldap_status}" ]] && ldap_status="1"
|
fi
|
||||||
|
|
||||||
if mysql -u"${MYSQL_USERNAME}" -p"${MYSQL_PASSWORD}" -h mysql --database="${MYSQL_DATABASE}" \
|
user_count=$(mysql -u"${CLOUDRON_MYSQL_USERNAME}" -p"${CLOUDRON_MYSQL_PASSWORD}" -h mysql --database="${CLOUDRON_MYSQL_DATABASE}" -N -B -e "SELECT count(*) FROM user")
|
||||||
-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
|
# be careful, not to create root user for existing LDAP based installs
|
||||||
echo "LDAP Authentication was setup with status ${ldap_status}"
|
if [[ "${user_count}" == "0" ]]; then
|
||||||
else
|
echo "==> Setting up root user for first run"
|
||||||
echo "Failed to setup LDAP authentication"
|
setup_root_user
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,35 +70,55 @@ fi
|
||||||
chmod 0600 /app/data/sshd/*_key
|
chmod 0600 /app/data/sshd/*_key
|
||||||
chmod 0644 /app/data/sshd/*.pub
|
chmod 0644 /app/data/sshd/*.pub
|
||||||
|
|
||||||
sed -e "s/^Port .*/Port ${SSH_PORT}/" \
|
sed -e "s/^Port .*/Port ${SSH_PORT}/" /etc/ssh/sshd_config > /run/gitea/sshd_config
|
||||||
-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/##DOMAIN/${APP_DOMAIN}/g" \
|
if [[ ! -f /app/data/app.ini ]]; then
|
||||||
-e "s/##SSH_PORT/${SSH_PORT}/g" \
|
echo -e "; Add customizations here - https://docs.gitea.io/en-us/config-cheat-sheet/" > /app/data/app.ini
|
||||||
-e "s/##DISABLE_SSH/${disable_ssh}/g" \
|
|
||||||
-e "s/##MYSQL_HOST/${MYSQL_HOST}/g" \
|
|
||||||
-e "s/##MYSQL_PORT/${MYSQL_PORT}/g" \
|
|
||||||
-e "s/##MYSQL_USERNAME/${MYSQL_USERNAME}/g" \
|
|
||||||
-e "s/##MYSQL_PASSWORD/${MYSQL_PASSWORD}/g" \
|
|
||||||
-e "s/##MYSQL_DATABASE/${MYSQL_DATABASE}/g" \
|
|
||||||
-e "s/##MAIL_SERVER/${MAIL_SMTP_SERVER}/g" \
|
|
||||||
-e "s/##MAIL_PORT/${MAIL_SMTP_PORT}/g" \
|
|
||||||
-e "s/##MAIL_FROM/${MAIL_FROM}/g" \
|
|
||||||
-e "s/##MAIL_SMTP_USERNAME/${MAIL_SMTP_USERNAME}/g" \
|
|
||||||
-e "s/##MAIL_SMTP_PASSWORD/${MAIL_SMTP_PASSWORD}/g" \
|
|
||||||
-e "s/##SECRET_KEY/$(pwgen -1 -s)/g" \
|
|
||||||
/home/git/app.ini.template > "/run/gitea/app.ini"
|
|
||||||
|
|
||||||
# merge any user config file
|
echo "==> Generating new SECRET_KEY"
|
||||||
[[ -f /app/data/app.ini ]] && cat "/app/data/app.ini" >> "/run/gitea/app.ini"
|
crudini --set "/app/data/app.ini" security SECRET_KEY $(pwgen -1 -s)
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p /app/data/repository /app/data/ssh
|
# 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 "${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 "${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"
|
||||||
|
crudini --set "/run/gitea/app.ini" server DISABLE_SSH "${disable_ssh}"
|
||||||
|
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 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"
|
||||||
|
|
||||||
|
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
|
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
|
exec /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf --nodaemon -i Gitea
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,4 @@ stdout_logfile=/dev/stdout
|
||||||
stdout_logfile_maxbytes=0
|
stdout_logfile_maxbytes=0
|
||||||
stderr_logfile=/dev/stderr
|
stderr_logfile=/dev/stderr
|
||||||
stderr_logfile_maxbytes=0
|
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
|
stdout_logfile_maxbytes=0
|
||||||
stderr_logfile=/dev/stderr
|
stderr_logfile=/dev/stderr
|
||||||
stderr_logfile_maxbytes=0
|
stderr_logfile_maxbytes=0
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
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
|
|
3072
test/package-lock.json
generated
Normal file
3072
test/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,17 +8,11 @@
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"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": {
|
"dependencies": {
|
||||||
"selenium-server-standalone-jar": "^3.3.1",
|
"chromedriver": "^128.0.1",
|
||||||
"selenium-webdriver": "^3.3.0",
|
"expect.js": "^0.3.1",
|
||||||
"superagent": "^1.8.5"
|
"mocha": "^10.7.3",
|
||||||
|
"selenium-webdriver": "^4.24.0",
|
||||||
|
"superagent": "^10.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
484
test/test.js
484
test/test.js
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/* jslint node:true */
|
/* jshint esversion: 8 */
|
||||||
/* global it:false */
|
/* global it:false */
|
||||||
/* global xit:false */
|
/* global xit:false */
|
||||||
/* global describe:false */
|
/* global describe:false */
|
||||||
|
@ -9,291 +9,311 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var execSync = require('child_process').execSync,
|
require('chromedriver');
|
||||||
ejs = require('ejs'),
|
|
||||||
|
const execSync = require('child_process').execSync,
|
||||||
expect = require('expect.js'),
|
expect = require('expect.js'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
mkdirp = require('mkdirp'),
|
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
rimraf = require('rimraf'),
|
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
webdriver = require('selenium-webdriver');
|
{ Builder, By, until } = require('selenium-webdriver'),
|
||||||
|
{ Options } = require('selenium-webdriver/chrome');
|
||||||
|
|
||||||
var by = require('selenium-webdriver').By,
|
if (!process.env.USERNAME || !process.env.PASSWORD || !process.env.EMAIL) {
|
||||||
until = require('selenium-webdriver').until,
|
console.log('USERNAME, PASSWORD and EMAIL env vars need to be set');
|
||||||
Builder = require('selenium-webdriver').Builder;
|
process.exit(1);
|
||||||
|
}
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
||||||
|
|
||||||
describe('Application life cycle test', function () {
|
describe('Application life cycle test', function () {
|
||||||
this.timeout(0);
|
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 = process.env.TIMEOUT || 5000;
|
|
||||||
var email, token;
|
|
||||||
|
|
||||||
before(function (done) {
|
const TIMEOUT = parseInt(process.env.TIMEOUT, 10) || 5000;
|
||||||
if (!process.env.USERNAME) return done(new Error('USERNAME env var not set'));
|
const EXEC_ARGS = { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' };
|
||||||
if (!process.env.PASSWORD) return done(new Error('PASSWORD env var not set'));
|
const LOCATION = 'test';
|
||||||
|
const SSH_PORT = 29420;
|
||||||
|
|
||||||
var seleniumJar= require('selenium-server-standalone-jar');
|
let app, browser;
|
||||||
var SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
|
var athenticated_by_oidc = false;
|
||||||
server = new SeleniumServer(seleniumJar.path, { port: 4444 });
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
done();
|
const repodir = '/tmp/testrepo';
|
||||||
|
const reponame = 'testrepo';
|
||||||
|
|
||||||
|
const username = process.env.USERNAME;
|
||||||
|
const password = process.env.PASSWORD;
|
||||||
|
const email = process.env.EMAIL;
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
browser = new Builder().forBrowser('chrome').setChromeOptions(new Options().windowSize({ width: 1280, height: 1024 })).build();
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function () {
|
||||||
browser.quit();
|
browser.quit();
|
||||||
server.stop();
|
fs.rmSync(repodir, { recursive: true, force: true });
|
||||||
rimraf.sync(repodir);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function waitForUrl(url, done) {
|
function getAppInfo() {
|
||||||
browser.wait(function () {
|
|
||||||
return browser.getCurrentUrl().then(function (currentUrl) {
|
|
||||||
return currentUrl === url;
|
|
||||||
});
|
|
||||||
}, TIMEOUT).then(function () { done(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAvatar(done) {
|
|
||||||
browser.get('https://' + app.fqdn + '/user/settings/avatar');
|
|
||||||
|
|
||||||
browser.findElement(by.xpath('//input[@type="file" and @name="avatar"]')).sendKeys(path.resolve(__dirname, '../logo.png')).then(function () {
|
|
||||||
browser.findElement(by.xpath('//button[contains(text(), "Update Avatar Setting")]')).click();
|
|
||||||
|
|
||||||
browser.wait(until.elementLocated(by.xpath('//p[contains(text(),"updated successfully")]')), TIMEOUT).then(function () { done(); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAvatar(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 editFile(done) {
|
|
||||||
browser.get('https://' + app.fqdn + '/' + username + '/' + reponame + '/_edit/master/newfile');
|
|
||||||
|
|
||||||
var cm = browser.findElement(by.xpath('//div[contains(@class,"CodeMirror")]'));
|
|
||||||
var text = 'yo';
|
|
||||||
browser.executeScript('arguments[0].CodeMirror.setValue("' + text + '");', cm).then(function () {
|
|
||||||
browser.findElement(by.xpath('//input[@name="commit_summary"]')).sendKeys('Dummy edit');
|
|
||||||
browser.findElement(by.xpath('//button[contains(text(), "Commit Changes")]')).click();
|
|
||||||
|
|
||||||
waitForUrl('https://' + app.fqdn + '/' + username + '/' + reponame + '/src/master/newfile', done);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
xit('build app', function () {
|
|
||||||
execSync('cloudron build', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can login', function (done) {
|
|
||||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
var inspect = JSON.parse(execSync('cloudron inspect'));
|
||||||
|
app = inspect.apps.filter(function (a) { return a.location.indexOf(LOCATION) === 0; })[0];
|
||||||
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' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can get app information', function () {
|
|
||||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
|
||||||
|
|
||||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0];
|
|
||||||
|
|
||||||
expect(app).to.be.an('object');
|
expect(app).to.be.an('object');
|
||||||
});
|
}
|
||||||
|
|
||||||
it('can get the main page', function (done) {
|
async function waitForElement(elem) {
|
||||||
superagent.get('https://' + app.fqdn).end(function (error, result) {
|
await browser.wait(until.elementLocated(elem), TIMEOUT);
|
||||||
expect(error).to.be(null);
|
await browser.wait(until.elementIsVisible(browser.findElement(elem)), TIMEOUT);
|
||||||
expect(result.status).to.eql(200);
|
}
|
||||||
|
|
||||||
done();
|
function sleep(millis) {
|
||||||
});
|
return new Promise(resolve => setTimeout(resolve, millis));
|
||||||
});
|
}
|
||||||
|
|
||||||
it('can login', function (done) {
|
async function setAvatar() {
|
||||||
browser.get('https://' + app.fqdn + '/user/login');
|
await browser.get('https://' + app.fqdn + '/user/settings');
|
||||||
browser.findElement(by.id('user_name')).sendKeys(username);
|
|
||||||
browser.findElement(by.id('password')).sendKeys(password);
|
|
||||||
browser.findElement(by.tagName('form')).submit();
|
|
||||||
browser.wait(until.elementLocated(by.linkText('Dashboard')), TIMEOUT).then(function () { done(); });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can set avatar', setAvatar);
|
var button = await browser.findElement(By.xpath('//label[contains(text(), "Use Custom Avatar")]'));
|
||||||
it('can get avatar', checkAvatar);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
it('can add public key', function (done) {
|
async function checkAvatar() {
|
||||||
browser.get('https://' + app.fqdn + '/user/settings/ssh');
|
await browser.get(`https://${app.fqdn}/${username}`);
|
||||||
var publicKey = fs.readFileSync(__dirname + '/id_rsa.pub', 'utf8');
|
|
||||||
|
|
||||||
browser.findElement(by.xpath('//div[text()="Add Key"]')).click();
|
const avatarSrc = await browser.findElement(By.xpath('//div[@id="profile-avatar"]/a/img')).getAttribute('src');
|
||||||
browser.findElement(by.id('ssh-key-title')).sendKeys('testkey');
|
|
||||||
browser.findElement(by.id('ssh-key-content')).sendKeys(publicKey.trim()); // #3480
|
|
||||||
browser.findElement(by.xpath('//button[contains(text(), "Add Key")]')).click();
|
|
||||||
browser.wait(until.elementLocated(by.xpath('//p[contains(text(), "added successfully!")]')), TIMEOUT).then(function () { done(); });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can create repo', function (done) {
|
const response = await superagent.get(avatarSrc);
|
||||||
browser.get('https://' + app.fqdn);
|
expect(response.statusCode).to.equal(200);
|
||||||
browser.findElement(by.linkText('New Repository')).click();
|
}
|
||||||
browser.wait(until.elementLocated(by.xpath('//*[contains(text(), "New Repository")]')), TIMEOUT);
|
|
||||||
browser.findElement(by.id('repo_name')).sendKeys(reponame);
|
async function login(username, password) {
|
||||||
browser.findElement(by.id('auto-init')).click();
|
await browser.get('https://' + app.fqdn + '/user/login');
|
||||||
browser.findElement(by.xpath('//button[contains(text(), "Create Repository")]')).click();
|
|
||||||
browser.wait(function () {
|
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) {
|
||||||
|
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 (!athenticated_by_oidc) {
|
||||||
|
await waitForElement(By.xpath('//input[@name="username"]'));
|
||||||
|
await browser.findElement(By.xpath('//input[@name="username"]')).sendKeys(username);
|
||||||
|
await browser.findElement(By.xpath('//input[@name="password"]')).sendKeys(password);
|
||||||
|
await browser.sleep(2000);
|
||||||
|
await browser.findElement(By.id('loginSubmitButton')).click();
|
||||||
|
await browser.sleep(2000);
|
||||||
|
|
||||||
|
athenticated_by_oidc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
await waitForElement(By.xpath('//img[contains(@class, "avatar")]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
var publicKey = fs.readFileSync(__dirname + '/id_ed25519.pub', 'utf8');
|
||||||
|
|
||||||
|
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 addPublicKeyOld() {
|
||||||
|
var publicKey = fs.readFileSync(__dirname + '/id_ed25519.pub', 'utf8');
|
||||||
|
|
||||||
|
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('//button[contains(text(), "Add Key") and contains(@class, "green")]')).click();
|
||||||
|
|
||||||
|
await browser.wait(until.elementLocated(By.xpath('//p[contains(text(), "has been added.")]')), TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createRepo() {
|
||||||
|
var getRepoPage = await browser.get('https://' + app.fqdn + '/repo/create');
|
||||||
|
|
||||||
|
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 browser.getCurrentUrl().then(function (url) {
|
||||||
return url === 'https://' + app.fqdn + '/' + username + '/' + reponame;
|
return url === 'https://' + app.fqdn + '/' + username + '/' + reponame;
|
||||||
});
|
});
|
||||||
}, TIMEOUT).then(function () { done(); });
|
}, TIMEOUT);
|
||||||
});
|
}
|
||||||
|
|
||||||
it('displays correct clone url', function (done) {
|
async function checkCloneUrl() {
|
||||||
browser.get('https://' + app.fqdn + '/' + username + '/' + reponame);
|
await browser.get('https://' + app.fqdn + '/' + username + '/' + reponame);
|
||||||
browser.findElement(by.id('repo-clone-ssh')).click();
|
await browser.findElement(By.id('repo-clone-ssh')).click();
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can clone the url', function (done) {
|
var cloneUrl = await browser.findElement(By.id('repo-clone-url')).getAttribute('value');
|
||||||
|
expect(cloneUrl).to.be(`ssh://git@${app.fqdn}:${SSH_PORT}/${username}/${reponame}.git`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneRepo() {
|
||||||
|
fs.rmSync(repodir, { recursive: true, force: true });
|
||||||
var env = Object.create(process.env);
|
var env = Object.create(process.env);
|
||||||
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
||||||
execSync('git clone ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + '.git ' + repodir, { env: env });
|
execSync(`git clone ssh://git@${app.fqdn}:${SSH_PORT}/${username}/${reponame}.git ${repodir}`, { env: env });
|
||||||
done();
|
}
|
||||||
});
|
|
||||||
|
|
||||||
it('can add and push a file', function (done) {
|
function pushFile() {
|
||||||
var env = Object.create(process.env);
|
const env = Object.create(process.env);
|
||||||
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
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 });
|
{ env: env, cwd: repodir });
|
||||||
rimraf.sync('/tmp/testrepo');
|
fs.rmSync(repodir, { recursive: true, force: true });
|
||||||
done();
|
}
|
||||||
});
|
|
||||||
|
|
||||||
it('can edit file', editFile);
|
function fileExists() {
|
||||||
|
|
||||||
it('can restart app', function (done) {
|
|
||||||
execSync('cloudron restart');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can clone the url', function (done) {
|
|
||||||
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 });
|
|
||||||
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
||||||
rimraf.sync(repodir);
|
}
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('backup app', function () {
|
async function sendMail() {
|
||||||
execSync('cloudron backup create --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
await browser.get(`https://${app.fqdn}/admin/config`);
|
||||||
});
|
|
||||||
|
|
||||||
it('restore app', function () {
|
var button = await browser.findElement(By.xpath('//button[contains(text(), "Send")]'));
|
||||||
execSync('cloudron restore --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
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(text(), "Send")]')).click();
|
||||||
|
await browser.wait(until.elementLocated(By.xpath('//p[contains(text(), "A testing email has been sent")]')), TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 admin login', adminLogin);
|
||||||
|
it('can send mail', sendMail);
|
||||||
|
it('can logout', logout);
|
||||||
|
|
||||||
|
it('can login', loginOIDC.bind(null, username, password));
|
||||||
|
it('can set avatar', setAvatar);
|
||||||
it('can get avatar', checkAvatar);
|
it('can get avatar', checkAvatar);
|
||||||
|
|
||||||
it('can clone the url', function (done) {
|
it('can add public key', addPublicKey);
|
||||||
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 });
|
|
||||||
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
|
||||||
rimraf.sync(repodir);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('move to different location', function () {
|
it('can create repo', createRepo);
|
||||||
browser.manage().deleteAllCookies();
|
|
||||||
execSync('cloudron configure --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('can login', function (done) {
|
it('displays correct clone url', checkCloneUrl);
|
||||||
browser.get('https://' + app.fqdn + '/user/login');
|
|
||||||
browser.findElement(by.id('user_name')).sendKeys(username);
|
|
||||||
browser.findElement(by.id('password')).sendKeys(password);
|
|
||||||
browser.findElement(by.tagName('form')).submit();
|
|
||||||
browser.wait(until.elementLocated(by.linkText('Dashboard')), TIMEOUT).then(function () { done(); });
|
|
||||||
});
|
|
||||||
|
|
||||||
|
it('can clone the url', cloneRepo);
|
||||||
|
|
||||||
|
it('can add and push a file', pushFile);
|
||||||
|
|
||||||
|
it('can restart app', function () { execSync('cloudron restart --app ' + app.id); });
|
||||||
|
|
||||||
|
xit('can login', loginOIDC.bind(null, username, password)); // no need to relogin since session persists
|
||||||
|
it('displays correct clone url', checkCloneUrl);
|
||||||
|
it('can clone the url', cloneRepo);
|
||||||
|
it('file exists in repo', fileExists);
|
||||||
|
|
||||||
|
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('can login', loginOIDC.bind(null, username, password));
|
||||||
it('can get avatar', checkAvatar);
|
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('displays correct clone url', function (done) {
|
it('move to different location', async function () {
|
||||||
browser.get('https://' + app.fqdn + '/' + username + '/' + reponame);
|
//browser.manage().deleteAllCookies(); // commented because of error "'Network.deleteCookie' wasn't found"
|
||||||
browser.findElement(by.id('repo-clone-ssh')).click();
|
// ensure we don't hit NXDOMAIN in the mean time
|
||||||
browser.findElement(by.id('repo-clone-url')).getAttribute('value').then(function (cloneUrl) {
|
await browser.get('about:blank');
|
||||||
expect(cloneUrl).to.be('ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + '.git');
|
|
||||||
done();
|
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', 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);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can clone the url', function (done) {
|
// No SSO
|
||||||
var env = Object.create(process.env);
|
it('install app (no sso)', function () { execSync(`cloudron install --no-sso --location ${LOCATION} -p SSH_PORT=${SSH_PORT}`, EXEC_ARGS); });
|
||||||
env.GIT_SSH = __dirname + '/git_ssh_wrapper.sh';
|
|
||||||
execSync('git clone ssh://git@' + app.fqdn + ':29418/' + username + '/' + reponame + '.git ' + repodir, { env: env });
|
it('can get app information', getAppInfo);
|
||||||
expect(fs.existsSync(repodir + '/newfile')).to.be(true);
|
it('can admin login (no sso)', adminLogin);
|
||||||
rimraf.sync(repodir);
|
it('can logout', logout);
|
||||||
done();
|
|
||||||
|
it('uninstall app (no sso)', async function () {
|
||||||
|
await browser.get('about:blank');
|
||||||
|
execSync('cloudron uninstall --app ' + app.id, EXEC_ARGS);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uninstall app', function () {
|
// test update
|
||||||
execSync('cloudron uninstall --app ' + app.id, { 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); });
|
||||||
});
|
|
||||||
|
|
||||||
// check if the _first_ login via email succeeds
|
it('can get app information', getAppInfo);
|
||||||
it('can login via email', function (done) {
|
it('can login', loginOIDC.bind(null, username, password));
|
||||||
execSync('cloudron install --new --wait --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
it('can set avatar', setAvatar);
|
||||||
var inspect = JSON.parse(execSync('cloudron inspect'));
|
it('can get avatar', checkAvatar);
|
||||||
|
it('can add public key', addPublicKey);
|
||||||
|
it('can create repo', createRepo);
|
||||||
|
it('can clone the url', cloneRepo);
|
||||||
|
it('can add and push a file', pushFile);
|
||||||
|
|
||||||
app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0];
|
it('can update', function () { execSync('cloudron update --app ' + app.id, EXEC_ARGS); });
|
||||||
expect(app).to.be.an('object');
|
it('can get app information', getAppInfo);
|
||||||
|
|
||||||
browser.get('https://' + app.fqdn + '/user/login');
|
it('can admin login', adminLogin);
|
||||||
browser.findElement(by.id('user_name')).sendKeys(email);
|
it('can send mail', sendMail);
|
||||||
browser.findElement(by.id('password')).sendKeys(password);
|
it('can logout', logout);
|
||||||
browser.findElement(by.tagName('form')).submit();
|
|
||||||
browser.wait(until.elementLocated(by.linkText('Dashboard')), TIMEOUT).then(function () {
|
it('can login', loginOIDC.bind(null, username, password));
|
||||||
execSync('cloudron uninstall --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' });
|
it('can get avatar', checkAvatar);
|
||||||
done();
|
it('can clone the url', cloneRepo);
|
||||||
});
|
it('file exists in cloned repo', fileExists);
|
||||||
|
|
||||||
|
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