Merge branch 'lash/404' into 'master'
All checks were successful
continuous-integration/drone/push Build is passing

add 404 handler

See merge request grassrootseconomics/cic-auth-helper!3
This commit is contained in:
Mohamed Sohail 2022-02-02 14:10:10 +00:00
commit 265a14bfd0
16 changed files with 550 additions and 16 deletions

16
.drone.yml Normal file
View File

@ -0,0 +1,16 @@
kind: pipeline
name: default
steps:
- name: docker
image: plugins/docker
environment:
DOCKER_BUILDKIT: 1
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: docker.grassecon.net/cic-auth-helper-gitea
registry: docker.grassecon.net
tags: latest

View File

@ -0,0 +1,3 @@
- "^/user(/.*)?$":
read:
- user

View File

@ -0,0 +1,3 @@
- "^/user(/.*)?$":
read:
- user

193
.well-known/allowed.asc Normal file
View File

@ -0,0 +1,193 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGHxE94BDAC6VRjo9Q2Cq8xdD9nHHhyywgCbh35PnEyZKulpqBC9UBuluxUp
uWxUfB99qczcLU76Y7dXFvezeuIjZr7ntuAQyFgaNTMAbv4MR2oIx95QS5HcdOpq
VVelfEVNSiHVDRZcWyzLQ0+u+jkbN5DSMfF07SWPpamJpW7EU/FQpFYVOdNU94qj
O5fL85H7tlxFsjqIljeV3X+zUu1YwyyT/iWlcnP85yIgoGdnrMlMSd1hC0dW8wuD
hJ0GfhhMtvk7OE5zJLV71qNejOtD3Dubn0gekhi0npC2YwptndIYdMYWjpKd87Hx
3b+BEpi4k10F6nBfpejATUfpNb9pfq4dNnCkXZFJc4DcEA0QUU502cym8LNyZ1L7
ND4x0XJt/z2y/hJDwy/xh6aLBjpUkdugQTcAWTqsfGGCMfPHrz6OLMMQhgE2ocdi
P2jo4plNEd/jcB22SunfAJqE+m2szF5B858M+xJiL696nBcpBPCFpjve9zFdFURn
f5p0uqLZfzT8yV8AEQEAAbQaU3kgU25vb3RsZXMgPHN5QGphYmJhLmNvbT6JAdQE
EwEIAD4WIQQyJJin+RRajM9gs0lQPPjLDyIa3gUCYfET3gIbAwUJA8JnAAULCQgH
AgYVCgkICwIEFgIDAQIeAQIXgAAKCRBQPPjLDyIa3j/qDACEPTHTl+rKTtRC7qG3
olFPN8YaNmlFBv6VsHMVnVoXKsd/wWshJCx9iv7AygFgWtVQ9O/ZACp5r9ADPlOL
rrgIW64hCECOtbCtY4gLgNpx50ZY0lHzLxlpn2D85XSdnay/woG/nCOqmcMnkKl2
hsfHNOOgGYPZe86hhCiCnqix+b7olg6F1my77kfl+KOskWaKTkcMmM3u0tDy+wy8
gT8SIqEtttTyI3eR4e7m4c58uN0h6I+sqAgaoDKlPaJ+48+5Ctr567TgP7s2435p
nqYo//+9ytB6BZD4UPnIpdElg9CD5/KTuRAbnKwZ8DSz0rMuQz4JhCE6xeGSz7zr
XMND3Usz9dwMGJJVdTwJvruquk8YVci5AA32x5MIsNHXsNZQuC6inCYZ5V4oZZoL
EXv5cIZQ7yPFykpoXwzhs/bNXD+D8BlZig5aVmqgbRKEWyCt05r4fJQcbYp9rRiq
L3nWIxTkcIdGxnCfxD2GJpBy3zj10VHFYuv0RHe979O93Y+5AY0EYfET3gEMAKZ8
IVJLbKnKxuJ8ze/2nRv8QBZrxBsPcV1JdhT8choXvvDuYRDhm5F31LVZ5bWEkRKb
NGoQwfCV2xndPqkWVterEcwv/Vra3SUCa1gn5scSu/KRC2OszYDF20lrm+jynRae
SnqQsfxw95xAWYetJD1/pSsD29q4jM7RhMmPkbWQ3bSbnBbGCq8EJGSYieEOsgv1
1ez36ZiwpRl4t93IlukAfpeUvpFD+qSbcrqh+B9g2OFjml7jSwMPIKd9dDxnU/22
tMQ3MvqEHLkr+3QFStcgpi881ADHl03d7T800+LYiuyApigJyFlCkWfUEMVCm490
hxMLVqSFnaixnXvgBCrDDRPE0m6zXNqlEEJaIVAMVhmDuUC8cQlODz4rPqzWUATp
u1zC+4+9wmIMSWQBu1ewBqiOU8yoWhznlv4mRlF7ljzw6POyxtSVa4CnWDvvi8mj
2Nznu+fXHqV4kHty40LH4TwVOKOoaTv2msPR1NEh27FbAfz8Hul7zzRi/9nJnwAR
AQABiQG8BBgBCAAmFiEEMiSYp/kUWozPYLNJUDz4yw8iGt4FAmHxE94CGwwFCQPC
ZwAACgkQUDz4yw8iGt5OeQwAiGLTDC8fzjaTXv2RY3ghVJBihjQ1HbbS1Qzj47wm
QVfci+7nK/hW63zxjTvis+f84qDo4rLEi/pEX3VzcUDMFVXJ//uw2on9FSC4be0j
JtSCGEMm8KPna5tuzqI8Pxy+B5t6x/P//aF/Il7c9ln4CG3suobKTawPu6lQz53d
DG4L9xCR1ZkEoNW+GsCNXAcjFW0P6LHCUVejR6+W/Mett2aldYjyX3oZswHILdKR
gRRRIWz65hElw1oXWI4028GNhT1Y9+E+6Y3P1zmWEW2OTcm8P5QJuvefFnjKDoMf
PaoqWu/IZGPmGTd6wK9mi0Aj+kic66DEHw8nR5TcxubFaifcGrrhKTLYGltQhl0A
XMVZIa5/mviSoDc9PpSMTjaPlt62dQzVMRPZ/O/cq8MKZmFW+SKDCJij5gY7CRmB
6VRzlrI+P8setUJbWyHqkGbdNdEIGRFKARzxMrbiEN8CFDbbDCv8SwgJe0clpt7v
6/jGQ3zHn0aYivqEF4leUM1YmQGNBF+hSOgBDACpkPQEjADjnQtjmAsdPYpx5N+O
MJBYj1DAoIYsDtV6vbcBJQt94Om3xl7RBhv9m2oLgzPsiRwjCEFRWyNSu0BUp5CF
jcXfm0S4K2egx4erFnTnSSC9S6tmVNrVNEXvScE6sKAnmJ7JNX1ExJuEiWPbUDRW
J1hoI9+AR+8EONeJRLo/j0Np+S4IFDn0PsxdT+SB0GY0z2cEgjvjoPr4lW9IAb8F
t9TDYp+mOzejn1Fg7CuIrlBRSAv+sj7bVQw15dh1SpbwtS5xxubCa8ExEGI4ByXm
eXdR0KZJ+EA5ksO0iSsQ/6ipSOdSg+i0niOClFNm1P/OhbUsYAxCUfiX654FMn2z
oxVBEjJ3e7l0pH7ktodaxEctPofQLBA9LSDUIejqJsU0npw/DHDD2uvxG+/A6lgV
9L8ETlvgp8RzeOCf2bHuiKYYz87txvkFwsXgU1+TZxbk+mtCBbngsVPLNarY/KGk
VJL+yhcHRD0Pl4wXUd6auQuY6vQ9AuKiCT1We2sAEQEAAbQeTWVyIE1hbiA8bWVy
bWFuQGdyZXlza3VsbC5jb20+iQHUBBMBCAA+FiEE8/r2aOgu9RJNUYe67yb0aCND
9pIFAl+hSOgCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ7yb0
aCND9pLwiwwAhFJbAyUK05TJKfDz81757N472STtB8sfr0auwmRr8Zs1utHRVM0b
/jkjTuo4uJNr7YVVKTKgE7+rJ+pwhm3wlTQ44LVLjByWAi/7NWg3E9b2elm+qkfg
m/RfFt3vkuOxGSyZyIFFh+/twv6iABPvr6w7MZwrFaS0UP3g1VGa5TFqg6KNxod9
H/gPLxv45lutXf3VvBZTJpr1pxn7aLHlFzEyIgNZbP/N1QF44GSrN/k0DfL631sZ
jauUXaZXbi5xGsKKCYwJ1g3q587pi6mTdTV3n0hKgVuipO8hGy5++YeOv+hXsCxD
wyZ+Shv+qavd/SapxYgCdEueuwONIFfsIsWCd3SCcjKXicTTEFMu8nvBmf7xuo2h
v6vEOxoijlXV+4LkGrskdB8ZMg8PywEx6DLmDokgnAhTLrTc1ShbkOtQ3yNjjyFK
7BDpqobsJal6d8SpbhccUJLepaSmsk0CgJsTjhAl6EwX0EYgTo3kP5fScqrbD8Vw
QaT8CcE4rCV4uQGNBF+hSOgBDADHtpTT1k4x+6FN5OeURpKAaIsoPHghkJ2lb6yW
mESCa+DaR6GXAKlbd0L9UMcXLqnaCn4SpZvbf8hP4fJRgWdRl5uVN/rmyVbZLUVj
M8NcVdFRIrTsNyu4mLBmydc3iA/90sCTEOj9e7DSvxLmmLFjpwM5xXLd6z0l6+9G
+woNmARXVS3V/RryFntyKC3ATCqVlJoQBG45Tj2gMIunpadTJXWmdioooeGW3sLe
Uv5MM98mSB4SjKRlJqGPNjx5lO6MmJbZeXZ/L/aO6EsXUQD2h82Wphll4rpGYWPi
HTCYqZYiqNYr6E3xUpzcvWVp3uCYVJWP6Ds117p7BoyKVz00yxC9ledF3eppktZW
qFVowCMihQE3676L3DDTZsnJf1/8xKUh5U2Mj3lBvjlvCECKi00qo8b1mn/OklQj
J5T4WzTrH6X+/zpez8ZkmtcOayHdUKD/64roZ9dXbXG/hp5A+UWj8oSVYKg2QNAw
AnZ+aiZ2KVRE/Y61DCgFg6Ccx/cAEQEAAYkBvAQYAQgAJhYhBPP69mjoLvUSTVGH
uu8m9GgjQ/aSBQJfoUjoAhsMBQkDwmcAAAoJEO8m9GgjQ/aSIPcL/3jqL2A2SmC+
s0BO4vMPEfCpa2gZ/vo1azzjUieZu5WhIxb5ik0V6T75EW5F0OeZj9qXI06gW+IM
8+C6ImUgaR3l47UjBiBPq+uKO9QuT/nOtbSs2dXoTNCLMQN7MlrdUBix+lnqZZGS
Dgh6n/uVyAYw8Sh4c3/3thHUiR7xzVKGxAKDT8LoVjhHshTzYuQq8MqlfvwVI4eE
SLaryQ+Y+j5+VLDzSLgPAnnIqF/ui2JQjefJxm/VLoYNaPAGdqoz/u/R0Tmz94bZ
UfLjgQaDoUpnxYywK2JGlf3mPZ3PNWjxJzuQTF5Ge5bz/TylnRYIyBT7KD7oaKHO
62fhDbYPJ4f94iZN4B6nnTAeP34zFDlkUbX4AHudXU7bvxT5OUk9x9c2tj7xwxQH
aEhq2+JsYW0EVw27RLhbymnBfLjVVUktNF0nQGvU2TEocw4pr2ZkDHQkSnlbNa4k
ujlL7VzbpnEgyOmi5er9GaIuVSVADovBu+pz/Ov1y/3jUe8hZ/KleZkBjQRgrn8w
AQwA2/mnkRIblVnqqFsnhqLEHg8qQ5xRT5brV1LXxATI6dOYLfs4aqNEwpkulOVy
EU7CophEHqb7mejJls57/ZoUhGBTR3yZK86EErLcO2DW8zEfIYY6lU/cWrpkmzoc
SlyHYqGYvMZP8+DxccQnfFdeqEt/rOv5+NH9WjWs+KJwfAEzaEZd4EJ/m5+BTTqU
FhhCPM16sxUHbrl8A3wSe2bkGJYdKPLyKMJpd8XCYy5Uc9OvJ2EUecl9TEwiZsUw
tNvBKfxHCIuYYLJ16gDAsHmApzAgH7fu2uJVUs4jUHPuJYRuIUGiDszVHK94j7Mh
hHd/z2YvgHRkrV+55x69+G/zOfSxgL7aDBF4uM+lIzBKGAynZvRifNM+QhcBJY9v
EYFYpWsA7n5bsnJn5kU2OQftTquroDd9MRI4DxKBim2R8JvfvVkXpPNWFexoYMDj
u1GG0iuK7IA/wfgrHuwA1w9KPQxr1C2I7w+QaTBtI3UZBQUxRWd1DZG+FGbSCzMj
0AO3ABEBAAG0TFF1ZWVuIE1hcmxlbmEgKFNoZSBpcyB0aGUgcXVlZW4gYW5kIGlz
IHRydXN0ZWQpIDxxdWVlbm1hcmxlbmFAZ3JleXNjdWxsLmNvbT6JAc4EEwEIADgW
IQTM4uHS0ONq3gQF4tCZW7IYFjE71QUCYK5/MAIbAwULCQgHAgYVCgkICwIEFgID
AQIeAQIXgAAKCRCZW7IYFjE71S6kC/45xtmN7mu3fQgvN1RXjpDDlZGbNVZeP9qP
X7HaNiYuGMWqMymrW6Cbm8KTtzYy2hWEMevgv+m7ZiGeZBVQR8QweLMPKyn5Jeeg
6kDCl4wMlmC3Av1DXGXX1eMNPlqI/ioC9bodW8aYlDMuzTZ8bz86NmBjKzoNMW44
cLj7lx79G8sKyUvJBZxxM9qO+Wnx5sCGZps2XIuBcKRQ2MTlrMxURe13ELtLZSY/
3kc6/0/XjpYbUzrOfxY7dNO0zTowQR7BfVN85H9QF8Z95MRXHYG3WFxDKdrkq/rD
EhakrJ5vSgKsAvkVPIhtkr/RX+WJzr4Own6sphhhYni76ZTMaanZTqcsDK4aV6k/
2ueL6s8Xid2sUypIP3N0+BnpND9CALDOp01muN81ZgSoZBTXT907k76kBcuGaixQ
zRwpOEnzUmFtQ3ovoq73MrHRW+vmQ1wGDXZNDfgI5a8MXEEkGgOpmrn4HDv7APm+
3tCTjIDNg6+S6zQ+FM9eszBmIHkEKf65AY0EYK5/MAEMALcGSoCA3spShaMd3ncz
wU0uWReUbOOlqenvjhdXnL320Jj1fLxz2ZC6zWE7eVDgyiSSyTuYaKTYCYoDB5gG
616hUmQf165JMH7mesmNxcsWu6mknshHQ19Eh9+d9xD+7wxa8mRLeWzvYNWlGz3g
WGpkjH65IBnY+zPk6BEbr6VVdi4YAQCXgG55PtmtEvyXMfO95lmsf05hS89sjtk2
RU++IjAtgskDCz246v6+YGjLDM0Y9tIyePpmrU/PFy+Ja9yZMrZFseR/Rvp9JLjV
5quhk5JcDF8le1yLsfYlL6oa+/nEqiRZ4lW4hm1k6M3wZP6yawgnAjfs1IfokFLV
W8OFrKwb6Oz6Prq5cNG23/wabTpoUPmyAgAKcVUfxdLXjXvNi2hR60V3EDpvxeHC
ajD7Wbwc/4jiTvp6hg4EbIFEfIAOPEWXUYGMUuXj0W1hClIZZrco7vdetgj9nNuB
agblG/p2M9Bd750YUQvZ+TDu2Y7TRZEMJejvsCdFAMJ6nQARAQABiQG2BBgBCAAg
FiEEzOLh0tDjat4EBeLQmVuyGBYxO9UFAmCufzACGwwACgkQmVuyGBYxO9X5jgv/
c5ct9z0udIEepHBbTfCgYHzXMHf2M2cyPANqOZwBYXB8Fh/39uYRl8W4d4RqM/DW
ohhRZLYnn2kPvTNlLG9eTko03ik+hyqAcUpJ+uNX5Fe+xHfmtKxrToa3pSr4qkCb
Uv+edPS2yKYmD6X0hMNDsJR32O2XgJdzwjmR5IsjsEf4Zo9oGx6W0qsUiXVn7Uyz
FA2gk86n0pCI5AeqU4CZCzzOHlJ0y8RT+FXJA4W549WvdgIyNAaFFUZUFCg8Iarg
5T+F4zpkUkWYeGIvHEIdDAzd0ke9scD9/ed8WDmGpwATHADaldMD0ZtbS1zkU/5E
AwVbA7GAE0vWuSreEMhehZ0deq3CuZQKl3rdfzta71b2iQ81586EDmtDkYHRXLYv
tqXQm8Dcty2Ni7yQ5fiODwxk6pN9h/x1Lgqa1pHGbtnSwj9E3hFUYPecMghXOAtB
tXi+sniCnB/5eg6eU6C36qWiLei1yx6XyQ9KNHjquOk/iEJThbKi5nqmUzO8EZcD
mQINBFidw/8BEADCvm2pu3s4xHCI4ierG4KhXtZybYRV3A30KLJAtj9DRBM0SxuT
Er5pKFes/idvAKstXPJBpFgkT3k3a+CZUi7SG4SJCHdeukzfgj/dH9pdZ21W8tkz
7H3gXnQRrEQG+ZVeTQroiUPkfuV4axr82vrJ4UpF+Mjr+S34sSt/Gy/jugsyH+0i
lnKuesWRFPC0PGj7v6c1uTL9V1swtXbGv0r4XRl/z53hTy6y3THCECnMNBOqKeNa
xYKrIn6h6QPBwp2HbMlapFMbGoD6cWBG7XExKYPJaBralYZHiKe6ZBGKWmpYel79
NEdUCmYExAHDfsrp6GWqyLueBjEq3uSkF+WG3gYe5XvIoipDJzEGdeyUWK38OkYf
5E0bWaAUTaTDNoAQfuQHbLikIn7tGknOe61JZ1p3QqvZAY9/32fsX/Hm4E/WXnS2
G8yK5XBoT1G3hYv4Q0xO8ZcoQylN89b6hL/GyparF42hxYt8OqsAfk1SxRRQezMw
YNSZVWenOxPwKv56mqN8tJwXyfZ04yZJNGkyVqP5GfsA/pv1/YzLidBfqHLanyDq
ScNVNrkvSr/U2RcAAMOmepSKxxz0rqCsj9OKdHs+6Zcy42iXjKRd7GaAnYgPIPfx
4CbV8i2EYPHCNriKBrQUiduGjW7RWAjofXri7vn6dn8XHxAUpSpuNuFDvQARAQAB
tEJNb2hhbWVkIFNvaGFpbCBBemltIChrYW1pa2F6ZWNoYXNlcikgPG1vaGFtZWRz
b2hhaWxhemltQGdtYWlsLmNvbT6JAlEEEwEKADsCGwMFCwkIBwIGFQoJCAsCBBYC
AwECHgECF4AWIQRDynf2Qa2gMcEmZctHRhwxsAa8DgUCYe/GPwIZAQAKCRBHRhwx
sAa8DuLeEADCpKYRn0lfN4LSI7FO0vG1E06nH9ax37MgTne7LwflKEg2lNhckWf8
as/sm1K0+ASdqHaNEcGM8rcbqNk9zy0peL0ReytvC+TX+wS1L1LpHl8LPsSjM1oG
k9WzOUtWOl77n6PKSoCbCM/1SXc4RdZnnjsiuVnuJy8ABkExqqg/jSrwaZsKT/yY
dGNH0/HjnvOgza89Rp6n0dllXR7l7LhO9LTh2Nhl3CMLGQuYYTjWYAndRJnsqmD3
geKi3TkFOmPqiLm2ThHE0vxT0/XVJMs26lQfw8xc6j/YoWN6AMCXd5xOu7GH3NJE
2zh8ohPtIc0D/Tc9b0cYnzvB17pVytLcVc6Ip9dlDFMwI/U1oqzSzw9UiWKBvzv3
xeDqiUYx6a6/2Ue8faydAyKKL5EgtjadO38s9WiKRZNY9rcDQi+Bn12XfGY2GVn5
42472N1Hcc6Ja6wK1RTPqlu43v4u/TPeHWEpTj62KX+mWqKL8bIGMWMFxBDGi0KE
dqY7st++Ljk5OMjmjkpqJUvvGStuOjT7jHyNotKqprKHRET21kyg6CfFIxryJPxf
z5QOPGfh1mSiWC4jxMg/a8lpYhd5aKzbd4S0RtDMYHrvOs0rv9YFyU7qWJoHEmlK
EWKzbAzX4D3MZn/K26PdVr+YbjI9freXyxrlzngXHwifZZQCeJG2wokBOQQQAQoA
IxYhBJDQZnJzOtfYONzsQX3UVSDAHNhdBQJh78gwBYNrVxsrAAoJEH3UVSDAHNhd
KQUH/jVOnYldtmwun64yaI7wlP15JDq7u3LiTgYL6SlhYbrbvEFV1eTZt+oMCn/w
DURJ2Ri8CNM6WfP+mREQeKZ36T4RtoNaa9Ziv2JeSfE4Nwy4SRYlTjAl5w7cnOdU
2BLiU+w5ZtI84Hoj5/AmA91Kdib/bcjUJYcgXbuh0s0K5ilLc6Pc6mDcMOipQJ9q
wgfaNqV5nmU/BHbvzFv+AbfYudLlFU8o5FTt5iGjAcu5ejgUmhzjLy0e3B6i7gaO
+C+5gzlvHebf6JRQzlU4T7t8q2J9eiCVa6LN5dVg4Cw3jcmpCjGWE/WQ1lWj+DeV
dVYSejpkUOXMnD5J0MXP7CWJQCG0Ok1vaGFtbWVkIFNvaGFpbCAoQGthbWlrYXpl
Y2hhc2VyKSA8c29oYWlsc2FtZWphQGdtYWlsLmNvbT6JAjYEMAEKACAWIQRDynf2
Qa2gMcEmZctHRhwxsAa8DgUCYe/GzwIdIAAKCRBHRhwxsAa8DvU2D/0Ryq07Qb/g
wUPVqEuHKbMmA6K12NPR8P4FIKvWpaKjgfrRPK+lInj1fngcOnnH357ZsA5bG73j
6jRid48oSaFsGMSVjXx9r6Un8EoK3npZV2Y2z/wL8nT07PLhSXba2dA/vFVGD6qA
PVrwqZ4fGXTwNyJQece2BF+sMZKxC90Fq/gEK30sWKYSY9iQZ7Lar7Pn4dnPlG+s
+xvUsG9+QaopV/oaz9gn7yHzqYWjh/Ksud/7nhutFzKCv9FbF9kL+cL93605DU8M
6uy66IQbqBRChAhljZM4eLSf0sLJl7E0T2qVmtFW3nJfUJccvckzhG+DS+E0WLHb
NQRJyi6mW4DMfPPYYykz5nueQZGt1LVnScUqcjNNVZTaglVmFlCai+FgpKcBPxlv
uCGrxJFZ0/5TVkKpn6rnC458DDs9f3f+ivfUHHRwLmvKcqaFGngjX3cS7t3rtAo2
nMlS+uzO0PF+Na01LIOUmda4970ogroF8nNnqIdC1oUn1HdQoKs/aliO1IbIzu6Q
anuR/kbqfIZO9TME2EIVquNuyYrQyq8Wq/SRnBTzHWIPVlSB5Epi8hHZXH4Eqmw0
TGXlxKKnd7+lC8gcc4anqNAZUdjxQ5mgdQOX6UvAhTMKVyIT5v5w3BCBh8mLqTug
AgyxMXaI+akVgIvYDnAZd+6+IrNnMxOcyIkCOQQTAQgAIwUCWJ3D/wIbAwcLCQgH
AwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEEdGHDGwBrwOwBUP/RUvfAL2aJtFp4y/
vf+N5Pg5I/VY2Znrkke8SYoR92azFr5PJw63WkuIt+iWy1FwDrUfp8A1CFrx++aB
83KsSkEznvayppF9Py8lAB8SHiVxKCeKPMmRYwgyZ2HFhac0/t3iPhN6Ce+l+rGV
Rdy6ACuK2lBCExqPLKvSkLSrPWwm6Oy0SFacJQ6LTepEjaMbJIokkT2BwswBpX+a
XP97n6VU6JiJ4Pv0jwRMK2Ty5aGb8i1i89jm8++SxAMJMMLuhlx4pbdJ4ev8RlNK
p1ukwyO/EbZLUJRExNPH/hyjfCOMpU7VPmkTWFFFOK3n6GZ9Z+pcd8aosi+5uIB/
Gj2Bj5Nq9PV6vAgCzV7aoYOrZoQPuh96v5eXmuVssJss7FwDk6ISQhyMmBr98l8G
Xy/jSTugUPzHHz1AS8JqlowcsmbR88DGw5ZJM213aD+Xj8lvBoRYe8Lihz0CgVrE
A0m3a225KgOq66/CfiC3kWwarUbPM4GJdq5a77EMlm+CVWwPRcDS2aiU3WsZE/u2
W0FkWntFeVZFDqQXMRZrPK13VHY/G7vfOlni0+waZ+wdJ9RZJMFGKQ7xUF2He3rx
Qk+MyqZHNey6J1Yhv9UJ89asGtqnIK8I3SDgmkF9ndu/8RQKOAQIF2/Y+UKTobvV
xD9X1t6dpo+UTCSBnUxeT7cL6pnruQINBFidw/8BEADb8OscLHFNJxOwP6llp2kn
L8m0UNwb9xs+sh6jpLfKb3zjrc6ifpzkgWxhsFSfAN1qX4/Ul7PlxOlnpg2KAr3O
tBaAwSCoKaIWB2/vAp38YxZ8T/uyjbIX10CWIUQE+fAzZ5tgId9FFTgBjq8SKTZP
G4DmDwcprUuEGMidDlaqJ0d7j4dkw4/OhcTzbtWCSM0Q63oRXLjpHGINigegHvaI
xZ+50H3n/oyz5keWdHF1mQqJL6GkykV4PxFzCwP7yCsUJ2QMehdlP2UBNSDAbEnn
zkdbVv7g/SkOSs3TEtv444WN93Qo/BF0wZ+r4Lz0D0NAGIzvK04FErr902Cso7el
drH5wcdZERF1DEt2uB9LM5HqBdkVl4ybmyB0WM313ZDvuC5LGkwSNhSW2vOly+Uy
hFmBv/oCUIy8SEYoDqwukcigUdZk5yx51gTvnhxcHOkYAGyf+ugTlaPiG6XSD0sy
bR0YpMDInanTllE+S49gSO0dojKTy1WCurM06QxPOYwu2THxVWHVBTJH3x3A9vfm
kAGi9xVQWgdJophggOnb5Y3BXahGqiZ9Eg60la3zrs/XlUouz7SrC5K8S92UNFJ/
LeJ+YCofVANNCXMk6XOZhcFYu32hVoFc8stBci+OKEMW9ceencLGAL4c4o3mrHia
3qHRylLN+HZybTSrcVdBtwARAQABiQIfBBgBCAAJBQJYncP/AhsMAAoJEEdGHDGw
BrwOIz4QALcHDIDq4gxH/acnxOkEx+xdDr/3K+nVifCReM4GRN6NhSl6c9AGA35H
KHi7FGyw8qF06JKg+xOGsSBKPtmY7XbFU71opM0WvEz+DtW/iObE8lV57QtuGmjF
btrG0cmHe0KGvxRNKmgJVzXk43l0TOBoFnWq3QRovfJ4q0koFPgQQZ3nmIRRpX6i
3uZVW7M3ZfRVw+JtoHbuitKnpamZXGuBjX33AQSHVzbTFc8gmELjXB1Q+XJVt6sW
H29Xu2PIjZvC1NbGL5nOiq4bvAvuCfCo8evHPnFd2LXPHkZ0NMyVgEv/quIsBluh
CGYOkKC50WTBbvIrmo+qUVAP1Z1wykhGbGfrYGIZ5Q9Ct3xZ9ksUcUDAVX6zegTt
jBZzeUOIAOzHWgzLe9gNSCNcpE5BJDeZuIiF037EB9vlNWBaqQjcIdJqxMtgzEex
HI102Dtcmx7uGZ1ZDO0UC3AHUFmKu5pFhcECsbyoas+nzFq8b7YFl/sRcho7FQRW
CmgEC8VXX6R3pkxMlKTNwEJwCxikh32LIPeAd6qar3LU2vbz+ustjXp2oKOe/gaK
dq/D+1NRO1zVJx5Y7TCjZPYsqUrzi9DiDWxG+hbHiO/q3Xg8efb3qYFCODpyP10s
ImFivj6piZnFT5BVj3A2pZI7yzL6iW25zl6pAHycA/pgZx4U8L3c
=b8b1
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -0,0 +1,14 @@
-----BEGIN PGP SIGNATURE-----
iQGzBAABCAAdFiEEzOLh0tDjat4EBeLQmVuyGBYxO9UFAmHxG1wACgkQmVuyGBYx
O9U1MwwAmQtv/FNlEYCjkvJhCgOKRfAuIR1Sro5qguImlaoalHK2lA6LzORnay5L
hRzYpG6hE7bIn18iRujHsEoxD6tK7QXhIsqpWpZ+nuZnsMTffsGUIqxDWmiYz/Tm
rusw1wCI6xyGWgxjQCpLsQGcCT0oGe6aumGMXNYwjhVnjhQj3Whegx6WXhXtOh1L
vh68PLpWxT59RkKy9WBbFmrujs3I0Xcayj6bfFahnFOacQfqJ5FjgbtGuVVr8M8O
q4kb83O1cDI5gso5Q7/dg3kRjGxr76CQy53C7LXt5URRGHAocC7GMM7AvHcXuTwa
wYenYFkOGhYAJPD/cuCKIoinyDAnGuxh1Lv2cOChoARQ461b7Eg624fqlIZxiowd
lR0Kcm4CcSyHz1A2XSl4vsrscif8RRhKRguE6RlovOz3nHM6MBYZeCWaKJ/rkOsF
u7GWW4VBSJHEeQ9HC29bG7gLd8taOIG+EawGmHPBMq1kxivhq3i/huW9TmI+XAjN
Rls2ZgGi
=/0Oi
-----END PGP SIGNATURE-----

View File

@ -20,9 +20,10 @@ WORKDIR /home/root/app
RUN apk add --no-cache gnupg RUN apk add --no-cache gnupg
COPY . . COPY . .
COPY ./.well-known /var/lib/cic-auth-helper/pgp
COPY --from=builder /opt/venv /opt/venv COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH" ENV PATH="/opt/venv/bin:$PATH"
EXPOSE 80 EXPOSE 80
CMD uwsgi --wsgi-file cic_auth_helper/runnable/server.py --http :80 --pyargv "-vv" CMD uwsgi --wsgi-file cic_auth_helper/runnable/server.py --http :80 --pyargv "-vv --forward-to http://cic-meta-server:80"

View File

@ -1,5 +1,5 @@
[http] [http]
auth_origin = auth_origin =
cors_origin = cors_origin =
auth_realm = "ge" auth_realm = ge
hoba_cipher_id = 00 hoba_cipher_id = 969

View File

@ -1,6 +1,6 @@
[pgp] [pgp]
trusted_publickey_fingerprint = trusted_publickey_fingerprint = CCE2E1D2D0E36ADE0405E2D0995BB21816313BD5
import_dir = /var/lib/cic-auth-helper/pgp import_dir = /var/lib/cic-auth-helper/pgp
publickey_filename = publickeys.asc publickey_filename = allowed.asc
signature_filename = signature.asc signature_filename = allowed.asc.sig
run_dir = run_dir =

14
cic_auth_helper/error.py Normal file
View File

@ -0,0 +1,14 @@
class ReverseProxyError(Exception):
def __init__(self, code, msg, headers):
super(ReverseProxyError, self).__init__(msg)
self.code = code
self.msg = msg
self.headers = headers
class NotFoundError(ReverseProxyError):
pass
class BadRequestError(ReverseProxyError):
pass

View File

@ -4,10 +4,18 @@ import urllib.request
import os import os
import logging import logging
# local imports
from cic_auth_helper.error import (
NotFoundError,
BadRequestError,
)
logg = logging.getLogger(__name__) logg = logging.getLogger(__name__)
re_x = r'^HTTP_(X_.+)$' re_x = r'^HTTP_(X_.+)$'
def add_x_headers(env, header_f): def add_x_headers(env, header_f):
for x in env: for x in env:
m = re.match(re_x, x) m = re.match(re_x, x)
@ -16,25 +24,36 @@ def add_x_headers(env, header_f):
header_f(header_orig, env[x]) header_f(header_orig, env[x])
class ReverseProxyHandler(urllib.request.BaseHandler):
def http_error_404(self, request, response, code, msg, hdrs):
raise NotFoundError(code, msg, response.getheaders())
def http_error_400(self, request, response, code, msg, hdrs):
raise BadRequestError(code, msg, response.getheaders())
class ReverseProxy: class ReverseProxy:
def __init__(self, base_url, ignore_proxy_headers=[]): def __init__(self, base_url, ignore_proxy_headers=[]):
self.base_url = base_url self.base_url = base_url
if not isinstance(ignore_proxy_headers, list): if not isinstance(ignore_proxy_headers, list):
raise ValueError('ignore_proxy_headers parameter must be a list of header keys') raise ValueError(
'ignore_proxy_headers parameter must be a list of header keys')
self.ignore_proxy_headers = [] self.ignore_proxy_headers = []
for h in ignore_proxy_headers: for h in ignore_proxy_headers:
self.ignore_proxy_headers.append(h.lower()) self.ignore_proxy_headers.append(h.lower())
self.opener = urllib.request.build_opener(ReverseProxyHandler())
def proxy_pass(self, env, headers=[]): def proxy_pass(self, env, headers=[]):
url = os.path.join(self.base_url, env['REQUEST_URI'][1:]) url = os.path.join(self.base_url, env['REQUEST_URI'][1:])
logg.debug('access ok -> {}'.format(url)) logg.debug('access ok -> {}'.format(url))
req = urllib.request.Request(url, method=env['REQUEST_METHOD']) req = urllib.request.Request(url, method=env['REQUEST_METHOD'])
add_x_headers(env, req.add_header) add_x_headers(env, req.add_header)
req.add_header('Content-Type', env.get('CONTENT_TYPE', 'application/octet-stream')) req.add_header('Content-Type', env.get('CONTENT_TYPE',
'application/octet-stream'))
req.data = env.get('wsgi.input') req.data = env.get('wsgi.input')
res = urllib.request.urlopen(req) res = self.opener.open(req)
logg.debug('headers before reverse proxy {}'.format(headers)) logg.debug('headers before reverse proxy {}'.format(headers))
@ -54,8 +73,6 @@ class ReverseProxy:
logg.debug('headers after reverse proxy {}'.format(headers)) logg.debug('headers after reverse proxy {}'.format(headers))
status = '{} {}'.format(res.status, res.reason) status = '{} {}'.format(res.status, res.reason)
content = res.read() content = res.read()
return (status, headers, content) return (status, headers, content)

View File

@ -23,6 +23,12 @@ from usumbufu.retrieve.file import FileFetcher
from usumbufu.adapters.uwsgi import UWSGIHTTPAuthorization from usumbufu.adapters.uwsgi import UWSGIHTTPAuthorization
from usumbufu.adapters.uwsgi import UWSGIAdapter from usumbufu.adapters.uwsgi import UWSGIAdapter
# local imports
from cic_auth_helper.error import (
NotFoundError,
ReverseProxyError,
)
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
@ -98,12 +104,14 @@ def do_auth(env):
http_authenticator.component_id = 'http-hoba' http_authenticator.component_id = 'http-hoba'
bearer_authenticator.component_id = 'http-bearer' bearer_authenticator.component_id = 'http-bearer'
try: try:
logg.debug('registering bearer authenticator with bearer retriever')
authenticator.register(bearer_authenticator) authenticator.register(bearer_authenticator)
authenticator.activate(bearer_authenticator.component_id) authenticator.activate(bearer_authenticator.component_id)
except TypeError as e: except TypeError as e:
logg.debug('not a http bearer request: {}'.format(e)) logg.debug('not a http bearer request: {}'.format(e))
try: try:
logg.debug('registering http authenticator with hoba retriever')
authenticator.register(http_authenticator) authenticator.register(http_authenticator)
authenticator.activate(http_authenticator.component_id) authenticator.activate(http_authenticator.component_id)
except TypeError as e: except TypeError as e:
@ -135,6 +143,7 @@ def application(env, start_response):
# return [b''] # return [b'']
(challenge, expire) = challenger.request(env['REMOTE_ADDR']) (challenge, expire) = challenger.request(env['REMOTE_ADDR'])
headers.append(('WWW-Authenticate', hoba_auth_request_string(challenge, expire.timestamp(), realm=config.get('HTTP_AUTH_REALM'))),) headers.append(('WWW-Authenticate', hoba_auth_request_string(challenge, expire.timestamp(), realm=config.get('HTTP_AUTH_REALM'))),)
logg.debug('headers {}'.format(headers))
start_response('401 authenticate or I will SCREAM_SNAKE_CASE at you', headers) start_response('401 authenticate or I will SCREAM_SNAKE_CASE at you', headers)
return [b''] return [b'']
@ -156,9 +165,19 @@ def application(env, start_response):
response_status = '200 OK' response_status = '200 OK'
content = b'' content = b''
if reverse_proxy != None: if reverse_proxy != None:
(response_status, headers, content) = reverse_proxy.proxy_pass(env, headers) try:
(response_status, headers, content) = reverse_proxy.proxy_pass(env, headers)
except ReverseProxyError as e:
response_status = str(e.code) + ' ' + e.msg
headers = headers + e.headers
logg.debug('headers more {}'.format(headers))
content = b''
# except BadRequestError as e:
# response_status = '400 ' + e.msg
# headers = e.headers
# content = b''
else: else:
content = str(auth_resource).encode('utf-8') content = str(auth_resource).encode('utf-8')
start_response('200 OK', headers) start_response(response_status, headers)
return [content] return [content]

2
tests/.env Normal file
View File

@ -0,0 +1,2 @@
export PGP_TRUSTED_PUBLICKEY_FINGERPRINT=CCE2E1D2D0E36ADE0405E2D0995BB21816313BD5
export PGP_IMPORT_DIR=tests/pgp/dev

View File

@ -0,0 +1,3 @@
- "^/user(/.*)?$":
read:
- user

View File

@ -0,0 +1,84 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
HpfJD0o0eOq46T+IQlOFsqLmeqZTM7wRlwM=
=8eSx
-----END PGP PRIVATE KEY BLOCK-----

View File

@ -0,0 +1,151 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
tcsel8kPSjR46rjpP4hCU4WyouZ6plMzvBGXAw==
=Mjei
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -0,0 +1,14 @@
-----BEGIN PGP SIGNATURE-----
iQGzBAABCAAdFiEEzOLh0tDjat4EBeLQmVuyGBYxO9UFAmC4Be8ACgkQmVuyGBYx
O9W36Qv/amj4XpRAZfa5VAGKWWQq7RKtAsD7cIsygenG1BYUXFWSSQc4wnnbdmZF
vizM7j9ibWwhXIJuslA9oZaH2V+8Lt+69xUhN1EEKbYKZ45Amxm5Hi23Y9myUIFF
+uvgkayLHKIFH8vy5snVsll8QmmZvwPtu/+VuUWMHMeVqSbWQmAwz1+rwTAqGbbO
bVt2cqVYPO1HQWGzc6E2S4TDUR6HZUuSSDUDL17bejMEy0cFgySxBji5p9UQXmfN
7I82QdAB5wEuUE5zFr/GdvzBpbeAiLNz7rn0uhW5zbzZVMnaRfMmVl8fR7vgveXE
ILii5JYjJ0FJbO9xRoDhOlnqvMzfLCrHtwcnUd82b9iFvlt5NiiZQDrleIqvDC9S
ntY3ZrxhhaVh6qa59hJkEASzU06i120w+1hMc+6DU1e2DjwUCbEtWaDDG6iVdD2S
13QIXmo9EgCSVsrYRGv3k8LcdZFQQ2sypP1PvktFoqPz144nw8RIqLBUFS60mj5m
JBGF3FnI
=M69r
-----END PGP SIGNATURE-----