Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Gepetto
dashboard
Commits
1aca9ebb
Commit
1aca9ebb
authored
Aug 05, 2020
by
Tom Pillot
Committed by
Guilhem Saurel
Aug 05, 2020
Browse files
Sync GitHub and GitLab projects
parent
efa76df3
Changes
14
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
1aca9ebb
.env
db.sqlite3
__pycache__/
.idea
\ No newline at end of file
.gitlab-ci.yml
View file @
1aca9ebb
...
...
@@ -21,6 +21,6 @@ build:
image
:
docker
script
:
-
docker build -t ${DOCKER_TAG} .
-
docker run --rm -e SECRET_KEY -e GITHUB_WEBHOOK_KEY -e GITLAB_WEBHOOK_KEY -e PYTHONWARNINGS ${DOCKER_TAG} ./manage.py migrate
-
docker run --rm -e SECRET_KEY -e GITHUB_WEBHOOK_KEY -e GITLAB_WEBHOOK_KEY -e PYTHONWARNINGS ${DOCKER_TAG} ./manage.py test
-
docker run --rm -e SECRET_KEY -e GITHUB_WEBHOOK_KEY -e GITLAB_WEBHOOK_KEY -e
GITHUB_PIPELINE_TOKEN -e GITLAB_PIPELINE_TOKEN -e
PYTHONWARNINGS ${DOCKER_TAG} ./manage.py migrate
-
docker run --rm -e SECRET_KEY -e GITHUB_WEBHOOK_KEY -e GITLAB_WEBHOOK_KEY -e
GITHUB_PIPELINE_TOKEN -e GITLAB_PIPELINE_TOKEN -e
PYTHONWARNINGS ${DOCKER_TAG} ./manage.py test
-
docker push ${DOCKER_TAG}
Pipfile
View file @
1aca9ebb
...
...
@@ -16,3 +16,5 @@ requests = "*"
GitPython
=
"*"
djangorestframework
=
"<3.12"
django-auth-ldap
=
"*"
python-gitlab
=
"*"
pygithub
=
"*"
Pipfile.lock
View file @
1aca9ebb
{
"_meta"
:
{
"hash"
:
{
"sha256"
:
"
ebc0e3256d27ac65f467c43f53c16fc14ff58f693d277ee43b17892592d33474
"
"sha256"
:
"
8f167f313807117a90141a02ab8a2b9c7af2afa7f69bde38c3cae894ffda51e7
"
},
"pipfile-spec"
:
6
,
"requires"
:
{},
...
...
@@ -16,11 +16,11 @@
"default"
:
{
"asgiref"
:
{
"hashes"
:
[
"sha256:
8036f90603c54e93521e5777b2b9a39ba1bad05773fcf2d208f0299d1df58ce5
"
,
"sha256:9
ca8b952a0a9afa61d30aa6d3d9b570bb3fd6bafcf7ec9e6bed43b936133db1c
"
"sha256:
7e51911ee147dd685c3c8b805c0ad0cb58d360987b56953878f8c06d2d1c6f1a
"
,
"sha256:9
fc6fb5d39b8af147ba40765234fa822b39818b12cc80b35ad9b0cef3a476aed
"
],
"markers"
:
"python_version >= '3.5'"
,
"version"
:
"==3.2.
7
"
"version"
:
"==3.2.
10
"
},
"beautifulsoup4"
:
{
"hashes"
:
[
...
...
@@ -32,10 +32,10 @@
},
"certifi"
:
{
"hashes"
:
[
"sha256:5
ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1
"
,
"sha256:
9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc
"
"sha256:5
930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3
"
,
"sha256:
8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41
"
],
"version"
:
"==2020.
4.5
.2"
"version"
:
"==2020.
6
.2
0
"
},
"chardet"
:
{
"hashes"
:
[
...
...
@@ -44,13 +44,21 @@
],
"version"
:
"==3.0.4"
},
"deprecated"
:
{
"hashes"
:
[
"sha256:525ba66fb5f90b07169fdd48b6373c18f1ee12728ca277ca44567a367d9d7f74"
,
"sha256:a766c1dccb30c5f6eb2b203f87edd1d8588847709c78589e1521d769addc8218"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'"
,
"version"
:
"==1.2.10"
},
"django"
:
{
"hashes"
:
[
"sha256:
5052b34b34b3425233c682e0e11d658fd6efd587d11335a0203d827224ada8f
2"
,
"sha256:
e1630333248c9b3d4e38f02093a26f1e07b271ca896d73097457996e0fae12e8
"
"sha256:
31a5fbbea5fc71c99e288ec0b2f00302a0a92c44b13ede80b73a6a4d6d20558
2"
,
"sha256:
5457fc953ec560c5521b41fad9e6734a4668b7ba205832191bbdff40ec61073c
"
],
"index"
:
"pypi"
,
"version"
:
"==3.0.
7
"
"version"
:
"==3.0.
8
"
},
"django-auth-ldap"
:
{
"hashes"
:
[
...
...
@@ -62,18 +70,18 @@
},
"django-autoslug"
:
{
"hashes"
:
[
"sha256:
0
26
b525beed3e259532d23f2bff768c1e5f4d238caa4e99db223f9d5d232cb57
"
,
"sha256:
08065b662e05fa5ad8b9cff2b54d17481bd31672ea2a4e7e607267f692384b83
"
"sha256:26
459eeddec207e307c55777a10fc25d17f4978753695340b16a17ed248a6f70
"
,
"sha256:
bae66c27d35615f472865b99c4d107f3b3add3d22ee337e84960fc07694abd45
"
],
"version"
:
"==1.9.
7
"
"version"
:
"==1.9.
8
"
},
"django-bootstrap4"
:
{
"hashes"
:
[
"sha256:
7baf22ab8570b5147b566b3431738c4f3558604ad7a8140f69d784a04c9eb1c8
"
,
"sha256:
f1fbe0ab1e6357072642b25c0e7473b3bfe31d9f28eaacad237474a94f8df792
"
"sha256:
1c0a931b4245a0dcd5051ea1b244ac130a328374ce8e85254c75eb072a737201
"
,
"sha256:
32cc0f914ace4cef935c0d3f786dde2a52f0ea1be72153f6e356c0aa8f3925e1
"
],
"markers"
:
"python_version
>= '3.6
' and python_version
< '4
.0'"
,
"version"
:
"==2.
0.1
"
"markers"
:
"python_version
< '4.0
' and python_
full_
version
>= '3.6
.0'"
,
"version"
:
"==2.
2.0
"
},
"django-filter"
:
{
"hashes"
:
[
...
...
@@ -109,19 +117,19 @@
},
"gitpython"
:
{
"hashes"
:
[
"sha256:
e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a
"
,
"sha256:
ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac
"
"sha256:
2db287d71a284e22e5c2846042d0602465c7434d910406990d5b74df4afb0858
"
,
"sha256:
fa3b92da728a457dd75d62bb5f3eb2816d99a7fe6c67398e260637a40e3fafb5
"
],
"index"
:
"pypi"
,
"version"
:
"==3.1.
3
"
"version"
:
"==3.1.
7
"
},
"idna"
:
{
"hashes"
:
[
"sha256:
7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb
"
,
"sha256:
a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa
"
"sha256:
b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6
"
,
"sha256:
b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'"
,
"version"
:
"==2.
9
"
"version"
:
"==2.
10
"
},
"ndh"
:
{
"hashes"
:
[
...
...
@@ -133,46 +141,69 @@
},
"pyasn1"
:
{
"hashes"
:
[
"sha256:
aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba
"
,
"sha256:
e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2
"
,
"sha256:
014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359
"
,
"sha256:
03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576
"
,
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"
,
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"
,
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"
,
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"
,
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"
,
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"
,
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"
,
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"
,
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
,
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"
,
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"
,
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"
,
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"
,
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"
,
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"
,
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
],
"version"
:
"==0.4.8"
},
"pyasn1-modules"
:
{
"hashes"
:
[
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"
,
"sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"
,
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"
,
"sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"
,
"sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"
,
"sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"
,
"sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"
,
"sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"
,
"sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"
,
"sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"
,
"sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"
,
"sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"
,
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"
,
"sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"
,
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"
,
"sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"
,
"sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"
,
"sha256:
905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e
"
,
"sha256:
426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed
"
"sha256:
f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d
"
,
"sha256:
fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405
"
],
"version"
:
"==0.2.8"
},
"pygithub"
:
{
"hashes"
:
[
"sha256:8375a058ec651cc0774244a3bc7395cf93617298735934cdd59e5bcd9a1df96e"
,
"sha256:d2d17d1e3f4474e070353f201164685a95b5a92f5ee0897442504e399c7bc249"
],
"index"
:
"pypi"
,
"version"
:
"==1.51"
},
"pyjwt"
:
{
"hashes"
:
[
"sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"
,
"sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"
],
"version"
:
"==1.7.1"
},
"python-gitlab"
:
{
"hashes"
:
[
"sha256:6461e0662cacceb795fb3ffd225391133cc11e0e760d0caf1c998c7ba955c771"
,
"sha256:e240b5c371d9e98c46c980d878c3f03cd83f3da6cda01d533db27fa3e0dd474f"
],
"index"
:
"pypi"
,
"version"
:
"==2.4.0"
},
"python-ldap"
:
{
"hashes"
:
[
"sha256:
7d1c4b15375a533564aad3d3deade789221e450052b21ebb9720fb822eccdb8e
"
"sha256:
4711cacf013e298754abd70058ccc995758177fb425f1c2d30e71adfc1d00aa5
"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'"
,
"version"
:
"==3.
2.0
"
"version"
:
"==3.
3.1
"
},
"pytz"
:
{
"hashes"
:
[
...
...
@@ -183,11 +214,11 @@
},
"requests"
:
{
"hashes"
:
[
"sha256:
43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee
"
,
"sha256:
b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6
"
"sha256:
b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b
"
,
"sha256:
fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898
"
],
"index"
:
"pypi"
,
"version"
:
"==2.2
3
.0"
"version"
:
"==2.2
4
.0"
},
"smmap"
:
{
"hashes"
:
[
...
...
@@ -215,11 +246,17 @@
},
"urllib3"
:
{
"hashes"
:
[
"sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"
,
"sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"
"sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"
,
"sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'"
,
"version"
:
"==1.25.10"
},
"wrapt"
:
{
"hashes"
:
[
"sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'"
,
"version"
:
"==1.25.9"
"version"
:
"==1.12.1"
}
},
"develop"
:
{
...
...
@@ -239,11 +276,11 @@
},
"ipython"
:
{
"hashes"
:
[
"sha256:
0ef1433879816a960cd3ae1ae1dc82c64732ca75cec8dab5a4e29783fb571d0e
"
,
"sha256:
1b85d65632211bf5d3e6f1406f3393c8c429a47d7b947b9a87812aa5bce6595c
"
"sha256:
2dbcc8c27ca7d3cfe4fcdff7f45b27f9a8d3edfa70ff8024a71c7a8eb5f09d64
"
,
"sha256:
9f4fcb31d3b2c533333893b9172264e4821c1ac91839500f31bd43f2c59b3ccf
"
],
"index"
:
"pypi"
,
"version"
:
"==7.1
5.0
"
"version"
:
"==7.1
6.1
"
},
"ipython-genutils"
:
{
"hashes"
:
[
...
...
@@ -254,19 +291,19 @@
},
"jedi"
:
{
"hashes"
:
[
"sha256:
cd60c93b71944d628ccac47df9a60fec53150de53d42dc10a7fc4b5ba6aae798
"
,
"sha256:
df40c97641cb943661d2db4c33c2e1ff75d491189423249e989bcea4464f3030
"
"sha256:
86ed7d9b750603e4ba582ea8edc678657fb4007894a12bcf6f4bb97892f31d20
"
,
"sha256:
98cc583fa0f2f8304968199b01b6b4b94f469a1f4a74c1560506ca2a211378b5
"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'"
,
"version"
:
"==0.17.
0
"
"version"
:
"==0.17.
2
"
},
"parso"
:
{
"hashes"
:
[
"sha256:
158c140fc04112dc45bca311633ae5033c2c2a7b732fa33d0955bad8152a8dd0
"
,
"sha256:
908e9fae2144a076d72ae4e25539143d40b8e3eafbaeae03c1bfe226f4cdf12c
"
"sha256:
97218d9159b2520ff45eb78028ba8b50d2bc61dcc062a9682666f2dc4bd331ea
"
,
"sha256:
caba44724b994a8a5e086460bb212abc5a8bc46951bf4a9a1210745953622eb9
"
],
"markers"
:
"python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'"
,
"version"
:
"==0.7.
0
"
"version"
:
"==0.7.
1
"
},
"pexpect"
:
{
"hashes"
:
[
...
...
@@ -323,10 +360,10 @@
},
"wcwidth"
:
{
"hashes"
:
[
"sha256:
79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f
"
,
"sha256:
8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f
"
"sha256:
beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784
"
,
"sha256:
c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83
"
],
"version"
:
"==0.2.
4
"
"version"
:
"==0.2.
5
"
},
"yapf"
:
{
"hashes"
:
[
...
...
dashboard/middleware.py
View file @
1aca9ebb
...
...
@@ -8,7 +8,7 @@ from rest_framework import permissions
def
ip_laas
(
request
:
HttpRequest
)
->
bool
:
"""check if request comes from settings.LAAS_NETWORKS."""
forwarded_for
=
ip_address
(
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
))
forwarded_for
=
ip_address
(
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
)
.
split
(
', '
)[
0
]
)
return
any
(
forwarded_for
in
ip_network
(
net
)
for
net
in
settings
.
LAAS_NETWORKS
)
...
...
dashboard/settings.py
View file @
1aca9ebb
...
...
@@ -28,6 +28,7 @@ SERVER_EMAIL = f'{EMAIL_USER}+{PROJECT}@{EMAIL_FQDN}'
DEFAULT_FROM_EMAIL
=
f
'
{
PROJECT_VERBOSE
}
<
{
EMAIL_USER
}
@
{
EMAIL_FQDN
}
>'
EMAIL_BACKEND
=
'django.core.mail.backends.%s'
%
(
'filebased.EmailBackend'
if
DEBUG
else
'smtp.EmailBackend'
)
EMAIL_SUBJECT_PREFIX
=
f
'[
{
PROJECT_VERBOSE
}
] '
EMAIL_FILE_PATH
=
'email/'
ADMINS
=
((
os
.
environ
.
get
(
'ADMIN_NAME'
,
f
'
{
PROJECT_VERBOSE
}
webmaster'
),
os
.
environ
.
get
(
'ADMIN_MAIL'
,
f
'webmaster@
{
DOMAIN_NAME
}
'
)),
)
...
...
@@ -141,12 +142,19 @@ LOGGING = {
'level'
:
'DEBUG'
,
'class'
:
'logging.NullHandler'
,
},
'console'
:
{
'class'
:
'logging.StreamHandler'
,
},
},
'loggers'
:
{
'django.security.DisallowedHost'
:
{
'handlers'
:
[
'null'
],
'propagate'
:
False
,
},
'gh'
:
{
'handlers'
:
[
'console'
],
'level'
:
'DEBUG'
,
},
},
}
...
...
gh/tests.py
View file @
1aca9ebb
import
hmac
import
re
import
git
from
hashlib
import
sha1
from
os
import
getenv
from
autoslug.utils
import
slugify
from
django.conf
import
settings
from
django.test
import
TestCase
from
django.urls
import
reverse
from
django.utils.encoding
import
force_bytes
from
rainboard.models
import
Project
,
Namespace
,
Forge
def
redact_token
(
func
):
"""Decorator used to prevent git from leaking tokens in exception messages."""
def
wrapped_function
(
*
args
,
**
kwargs
):
try
:
return
func
(
*
args
,
**
kwargs
)
except
git
.
GitCommandError
as
e
:
e
.
stderr
=
re
.
sub
(
r
'://.*@'
,
'://[REDACTED]@'
,
e
.
stderr
)
raise
e
return
wrapped_function
class
GhTests
(
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
"""Run only once before the tests to avoid getting the objects in each test."""
super
(
GhTests
,
cls
).
setUpClass
()
cls
.
namespace
,
_
=
Namespace
.
objects
.
get_or_create
(
name
=
'gsaurel'
,
slug_gitlab
=
slugify
(
'gsaurel'
),
slug_github
=
slugify
(
'hrp2-14'
))
cls
.
project
,
_
=
Project
.
objects
.
get_or_create
(
name
=
'rainboard-tests'
,
main_namespace
=
Namespace
.
objects
.
get
(
name
=
'gsaurel'
),
main_forge
=
Forge
.
objects
.
get
(
name
=
'Gitlab'
))
cls
.
github
=
cls
.
project
.
github
()
cls
.
gitlab
=
cls
.
project
.
gitlab
()
# Cleanup previous test
for
pr
in
cls
.
github
.
get_pulls
(
state
=
"open"
):
pr
.
edit
(
state
=
"closed"
)
gh_branches
=
[
b
.
name
for
b
in
cls
.
github
.
get_branches
()]
gl_branches
=
[
b
.
name
for
b
in
cls
.
gitlab
.
branches
.
list
()]
for
branch_name
in
gl_branches
:
if
branch_name
.
startswith
(
'pr/'
):
cls
.
gitlab
.
branches
.
delete
(
branch_name
)
for
branch_name
in
[
'test-branch-gitlab'
,
'test-branch-github'
]:
if
branch_name
in
gh_branches
:
cls
.
github
.
get_git_ref
(
f
'heads/
{
branch_name
}
'
).
delete
()
if
branch_name
in
gl_branches
:
cls
.
gitlab
.
branches
.
delete
(
branch_name
)
def
assertSync
(
self
,
branch
):
"""Raise an exception if the branch is not synced between both repos."""
last_commit_github
=
self
.
github
.
get_branch
(
branch
).
commit
.
sha
last_commit_gitlab
=
self
.
gitlab
.
commits
.
list
(
ref_name
=
branch
)[
0
].
id
self
.
assertEqual
(
last_commit_github
,
last_commit_gitlab
)
@
redact_token
def
sync
(
self
):
"""Force both repos to be synced."""
for
branch
in
(
'master'
,
'devel'
):
last_commit_github
=
self
.
github
.
get_branch
(
branch
).
commit
.
sha
last_commit_gitlab
=
self
.
gitlab
.
commits
.
list
(
ref_name
=
branch
)[
0
].
id
if
last_commit_github
!=
last_commit_gitlab
:
print
(
f
'sync:
{
branch
}
is not synced, force pushing commit
{
last_commit_gitlab
}
on github'
)
git_repo
=
self
.
project
.
git
()
# Create the remotes if necessary
gl_remote_name
=
f
'gitlab/
{
self
.
namespace
.
slug
}
'
gh_remote_name
=
f
'github/
{
self
.
namespace
.
slug
}
'
if
gl_remote_name
not
in
git_repo
.
remotes
:
git_repo
.
create_remote
(
gl_remote_name
,
url
=
self
.
project
.
remote_url_gitlab
())
if
gh_remote_name
not
in
git_repo
.
remotes
:
git_repo
.
create_remote
(
gh_remote_name
,
url
=
self
.
project
.
remote_url_github
())
# Force push the latest gitlab commit on github
git_repo
.
remote
(
gl_remote_name
).
fetch
()
git_repo
.
git
.
push
(
'-f'
,
gh_remote_name
,
f
'
{
last_commit_gitlab
}
:
{
branch
}
'
)
self
.
assertSync
(
branch
)
@
redact_token
def
gh_webhook_event
(
self
,
event
,
last_commit
=
''
,
branch
=
'master'
,
pr_action
=
''
,
pr_number
=
''
,
pr_login
=
''
):
"""Simulate receiving an event from a github webhook."""
data
=
{
'repository'
:
{
'name'
:
self
.
project
.
slug
,
'owner'
:
{
'login'
:
self
.
namespace
.
slug_github
}
},
'ref'
:
f
'refs/heads/
{
branch
}
'
,
'after'
:
last_commit
,
'action'
:
pr_action
,
'number'
:
pr_number
,
'pull_request'
:
{
'head'
:
{
'repo'
:
{
'owner'
:
{
'login'
:
pr_login
},
'clone_url'
:
self
.
project
.
remote_url_github
()
},
'sha'
:
last_commit
}
}
}
encoded_data
=
self
.
client
.
_encode_json
({}
if
data
is
None
else
data
,
content_type
=
'application/json'
)
request_body
=
self
.
client
.
_encode_data
(
encoded_data
,
content_type
=
'application/json'
)
msg
=
force_bytes
(
request_body
)
signature
=
'sha1='
+
hmac
.
new
(
force_bytes
(
settings
.
GITHUB_WEBHOOK_KEY
),
msg
,
digestmod
=
sha1
).
hexdigest
()
return
self
.
client
.
post
(
reverse
(
'webhook'
),
data
,
content_type
=
'application/json'
,
HTTP_X_FORWARDED_FOR
=
'140.82.112.1'
,
HTTP_X_HUB_SIGNATURE
=
signature
,
HTTP_X_GITHUB_EVENT
=
event
)
@
redact_token
def
gl_webhook_event
(
self
,
event
,
last_commit
=
''
,
branch
=
'master'
,
status
=
''
):
"""Simulate receiving an event from a gitlab webhook."""
data
=
{
'repository'
:
{
'name'
:
self
.
project
.
slug
,
},
'project'
:
{
'name'
:
self
.
project
.
slug
,
'path_with_namespace'
:
f
'
{
self
.
namespace
.
slug_gitlab
}
/
{
self
.
project
.
slug
}
'
},
'ref'
:
f
'refs/heads/
{
branch
}
'
,
'after'
:
last_commit
,
'object_attributes'
:
{
'ref'
:
branch
,
'sha'
:
last_commit
,
'status'
:
status
,
'id'
:
1
}
}
return
self
.
client
.
post
(
reverse
(
'gl-webhook'
),
data
,
content_type
=
'application/json'
,
HTTP_X_FORWARDED_FOR
=
'140.93.0.1'
,
HTTP_X_GITLAB_TOKEN
=
settings
.
GITLAB_WEBHOOK_KEY
,
HTTP_X_GITLAB_EVENT
=
event
)
def
test_gh_webhook
(
self
):
"""Test the security of the github webhook."""
# Not from github IP
response
=
self
.
client
.
get
(
reverse
(
'webhook'
),
HTTP_X_FORWARDED_FOR
=
'5.5.5.5'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
# No signature
response
=
self
.
client
.
get
(
reverse
(
'webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.82.112.1'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
# Signature not sha1
response
=
self
.
client
.
get
(
reverse
(
'webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.82.112.1'
,
HTTP_X_HUB_SIGNATURE
=
'sha256=foo'
)
self
.
assertEqual
(
response
.
status_code
,
501
)
# Wrong signature
response
=
self
.
client
.
get
(
reverse
(
'webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.82.112.1'
,
HTTP_X_HUB_SIGNATURE
=
'sha1=foo'
)
self
.
assertEqual
(
response
.
status_code
,
403
)
# Ping
response
=
self
.
gh_webhook_event
(
'ping'
)
self
.
assertEqual
(
response
.
status_code
,
200
)
def
test_gl_webhook
(
self
):
"""Test the security of the gitlab webhook."""
# Not from gitlab IP
response
=
self
.
client
.
get
(
reverse
(
'gl-webhook'
),
HTTP_X_FORWARDED_FOR
=
'5.5.5.5'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
# No token
response
=
self
.
client
.
get
(
reverse
(
'gl-webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.93.0.1'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
# Wrong token
response
=
self
.
client
.
get
(
reverse
(
'gl-webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.93.0.1'
,
HTTP_X_GITLAB_TOKEN
=
'foo'
)
self
.
assertEqual
(
response
.
status_code
,
403
)
# Ping
response
=
self
.
client
.
get
(
reverse
(
'gl-webhook'
),
HTTP_X_FORWARDED_FOR
=
'140.93.0.1'
,
HTTP_X_GITLAB_TOKEN
=
settings
.
GITLAB_WEBHOOK_KEY
,
HTTP_X_GITLAB_EVENT
=
'ping'
)
self
.
assertEqual
(
response
.
status_code
,
200
)
def
test_push_already_synced
(
self
):
"""Test push when both repos are already synced."""
self
.
sync
()
last_commit
=
self
.
github
.
get_branch
(
'master'
).
commit
.
sha
response
=
self
.
gh_webhook_event
(
'push'
,
last_commit
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
content
.
decode
(),
'already synced'
)
def
push_github
(
self
,
branch
):
"""Test sync after pushing to the given branch on github."""
self
.
sync
()
last_commit
=
self
.
github
.
get_branch
(
branch
).
commit
.
sha
file
=
self
.
github
.
get_contents
(
'README.md'
,
branch
)
self
.
github
.
update_file
(
'README.md'
,
message
=
f
'Test push on github
{
branch
}
'
,
content
=
last_commit
[:
8
],
sha
=
file
.
sha
,
branch
=
branch
)
last_commit_github
=
self
.
github
.
get_branch
(
branch
).
commit
.
sha
self
.
assertNotEqual
(
last_commit
,
last_commit_github
)
response
=
self
.
gh_webhook_event
(
'push'
,
last_commit_github
,
branch
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
content
.
decode
(),
'push event detected'
)
last_commit_gitlab
=
self
.
gitlab
.
commits
.
list
(
ref_name
=
branch
)[
0
].
id
self
.
assertEqual
(
last_commit_github
,
last_commit_gitlab
)
def
test_push_github_master
(
self
):
"""Test sync after pushing to github on master."""
self
.
push_github
(
'master'
)
def
test_push_github_devel
(
self
):
"""Test sync after pushing to github on devel."""
self
.
push_github
(
'devel'
)
def
push_gitlab
(
self
,
branch
):
"""Test sync after pushing to the given branch on gitlab."""
self
.
sync
()
last_commit
=
self
.
gitlab
.
commits
.
list
(
ref_name
=
branch
)[
0
].
id
# Push a new commit to gitlab
file
=
self
.
gitlab
.
files
.
get
(
file_path
=
'README.md'
,
ref
=
branch
)
file
.
content
=
last_commit
[:
8
]
file
.
save
(
branch
=
branch
,
commit_message
=
f
'Test push on gitlab
{
branch
}
'
)
last_commit_gitlab
=
self
.
gitlab
.
commits
.
list
(
ref_name
=
branch
)[
0
].
id
self
.
assertNotEqual
(
last_commit
,
last_commit_gitlab
)
response
=
self
.
gl_webhook_event
(
'Push Hook'
,
last_commit_gitlab
,
branch
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
content
.
decode
(),
'push event detected'
)
last_commit_github
=
self
.
github
.
get_branch
(
branch
).
commit
.
sha
self
.
assertEqual
(
last_commit_github
,
last_commit_gitlab
)
def
test_push_gitlab_master
(
self
):
"""Test sync after pushing to gitlab on master."""
self
.
push_gitlab
(
'master'
)