Skip to content

Commit 15f2684

Browse files
committed
Initial commit.
0 parents  commit 15f2684

File tree

8 files changed

+710
-0
lines changed

8 files changed

+710
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build/
2+
dist/
3+
__pycache__/
4+
*.egg-info/

LICENSE

+504
Large diffs are not rendered by default.

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include LICENSE

README.rst

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Django-Auth-GitLab - GitLab authentication support for Django
2+
=============================================================
3+
.. image:: https://badge.fury.io/py/django-auth-gitlab.svg
4+
:target: https://badge.fury.io/py/django-auth-gitlab
5+
6+
This is a Django login view that authenticates against GitLab.
7+
8+
Use it if you own a single GitLab instance that you want to use as
9+
a OAuth Authentication Server between multiple apps.
10+
11+
See also django-auth-oidc_.
12+
13+
Requirements
14+
------------
15+
16+
- Python 3.6+. **Python 2 is not supported, and won’t ever get supported.**
17+
- Django 1.10+
18+
19+
Installation
20+
------------
21+
22+
.. code:: python
23+
24+
pip install django-auth-gitlab
25+
26+
settings.py
27+
~~~~~~~~~~~
28+
29+
.. code:: python
30+
31+
INSTALLED_APPS += ['django_auth_gitlab']
32+
33+
urls.py
34+
~~~~~~~
35+
36+
.. code:: python
37+
38+
urlpatterns += [
39+
url(r'^accounts/login/', include('django_auth_gitlab.urls')),
40+
]
41+
42+
Configuration
43+
-------------
44+
45+
GitLab
46+
~~~~~~
47+
48+
App's redirect URI: http(s)://app-domain/accounts/login/callback
49+
50+
App's environment variables
51+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
52+
53+
* GITLAB_SERVER - Gitlab Server URL - with trailing slash.
54+
* GITLAB_CLIENT_ID - Client ID received from GitLab
55+
* GITLAB_CLIENT_SECRET - Client secret received from GitLab
56+
57+
.. _django-auth-oidc: https://github.com/LEW21/django-auth-oidc

django_auth_gitlab/oidc.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import os
2+
import requests
3+
from requests.auth import HTTPBasicAuth
4+
from urllib.parse import urlencode
5+
6+
class TokenResponse:
7+
def __init__(self, data, server=None):
8+
self._data = data
9+
10+
if server:
11+
r = requests.get(server.url + "api/v3/user", params=dict(
12+
access_token=self.access_token,
13+
))
14+
r.raise_for_status()
15+
data = r.json()
16+
self.id = {
17+
"sub": data["username"]
18+
}
19+
20+
@property
21+
def access_token(self):
22+
return self._data["access_token"]
23+
24+
class AuthorizationServer:
25+
def __init__(self, url, client_id, client_secret):
26+
self.client_id = client_id
27+
self.client_secret = client_secret
28+
29+
self.url = url
30+
31+
@property
32+
def authorization_endpoint(self):
33+
return self.url + "oauth/authorize"
34+
35+
@property
36+
def token_endpoint(self):
37+
return self.url + "oauth/token"
38+
39+
def authorize(self, redirect_uri, state, scope="read_user"):
40+
return self.authorization_endpoint + "?" + urlencode(dict(
41+
client_id=self.client_id,
42+
response_type="code",
43+
redirect_uri=redirect_uri,
44+
state=state,
45+
scope=scope,
46+
))
47+
48+
def request_token(self, redirect_uri, code):
49+
client_auth = HTTPBasicAuth(self.client_id, self.client_secret)
50+
r = requests.post(self.token_endpoint, auth=client_auth, data=dict(
51+
grant_type="authorization_code",
52+
redirect_uri=redirect_uri,
53+
code=code,
54+
))
55+
r.raise_for_status()
56+
return TokenResponse(r.json(), self)
57+
58+
SERVER = os.getenv("GITLAB_SERVER", "https://gitlab.com/")
59+
CLIENT_ID = os.getenv("GITLAB_CLIENT_ID")
60+
CLIENT_SECRET = os.getenv("GITLAB_CLIENT_SECRET")
61+
62+
if SERVER and CLIENT_ID and CLIENT_SECRET:
63+
server = AuthorizationServer(SERVER, CLIENT_ID, CLIENT_SECRET)

django_auth_gitlab/urls.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from django.conf.urls import url
2+
from . import views
3+
4+
app_name = 'django_auth_gitlab'
5+
urlpatterns = [
6+
url(r'^$', views.login, name='login'),
7+
url(r'^callback/$', views.callback, name='callback'),
8+
]

django_auth_gitlab/views.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.conf import settings
2+
from django.contrib import auth
3+
from django.shortcuts import redirect, resolve_url
4+
from django.urls import reverse
5+
from django.utils.http import is_safe_url
6+
7+
from . import oidc
8+
9+
def login(request):
10+
return_path = request.GET.get(auth.REDIRECT_FIELD_NAME, "")
11+
12+
return redirect(oidc.server.authorize(
13+
redirect_uri = request.build_absolute_uri(reverse("django_auth_gitlab:callback")),
14+
state = return_path,
15+
))
16+
17+
def callback(request):
18+
return_path = request.GET.get("state")
19+
20+
res = oidc.server.request_token(
21+
redirect_uri = request.build_absolute_uri(reverse("django_auth_gitlab:callback")),
22+
code = request.GET["code"],
23+
)
24+
25+
User = auth.get_user_model()
26+
user, created = User.objects.get_or_create(username=res.id["sub"])
27+
auth.login(request, user)
28+
29+
url_is_safe = is_safe_url(
30+
url = return_path,
31+
host = request.get_host(),
32+
#allowed_hosts = set(request.get_host()),
33+
#require_https = request.is_secure(),
34+
)
35+
if not url_is_safe:
36+
return redirect(resolve_url(settings.LOGIN_REDIRECT_URL))
37+
return redirect(return_path)

setup.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python3
2+
3+
from setuptools import setup
4+
5+
with open('README.rst') as f:
6+
readme = f.read()
7+
8+
setup(
9+
name = "django-auth-gitlab",
10+
version = "0.1.0",
11+
description = "OpenID Connect authentication support for Django",
12+
long_description = readme,
13+
author = "Linus Lewandowski",
14+
author_email = "[email protected]",
15+
url = "https://github.com/LEW21/django-auth-gitlab",
16+
keywords = "django,auth,oauth,openid,oidc,social,gitlab",
17+
license = "LGPLv2+",
18+
19+
install_requires = ["django>=1.10.0"],
20+
21+
packages = ["django_auth_gitlab"],
22+
package_data = {"": ["LICENSE"]},
23+
package_dir = {"django_auth_gitlab": "django_auth_gitlab"},
24+
zip_safe = True,
25+
classifiers = [
26+
'Development Status :: 4 - Beta',
27+
'Intended Audience :: System Administrators',
28+
'Natural Language :: English',
29+
'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
30+
'Programming Language :: Python',
31+
'Programming Language :: Python :: 3',
32+
'Programming Language :: Python :: 3.5',
33+
'Programming Language :: Python :: 3.6',
34+
'Topic :: System :: Systems Administration :: Authentication/Directory',
35+
]
36+
)

0 commit comments

Comments
 (0)