Add Django Samples (#636)

Contains two sets of samples - one for the “Google auth” system and one for the “Django
user auth” system.
This commit is contained in:
Bill Prin
2016-09-20 12:28:47 -07:00
committed by Jon Wayne Parrott
parent 8a6e3b2a34
commit 3f9fdbd5a3
19 changed files with 543 additions and 0 deletions

21
samples/django/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Django Samples
These two sample Django apps provide a skeleton for the two main use cases of the
`oauth2client.contrib.django_util` helpers.
Please see the
[core docs](https://oauth2client.readthedocs.io/en/latest/) for more information and usage examples.
## google_user
This is the simpler use case of the library. It assumes you are using Google OAuth as your primary
authorization and authentication mechanism for your application. Users log in with their Google ID
and their OAuth2 credentials are stored inside the session.
## django_user
This is the use case where the application is already using the Django authorization system and
has a Django model with a `django.contrib.auth.models.User` field, and would like to attach
a Google OAuth2 credentials object to that model. Users have to login, and then can login with
their Google account to associate the Google account with the user in the Django system.
Credentials will be stored in the Django ORM backend.

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myoauth.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View File

@@ -0,0 +1,115 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'eiw+mvmua#98n@p2xq+c#liz@r2&#-s07nkgz)+$zcl^o4$-$o'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
'oauth2client.contrib.django_util',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'myoauth.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'myoauth.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
GOOGLE_OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID'
GOOGLE_OAUTH2_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
GOOGLE_OAUTH2_SCOPES = (
'email', 'profile')
GOOGLE_OAUTH2_STORAGE_MODEL = {
'model': 'polls.models.CredentialsModel',
'user_property': 'user_id',
'credentials_property': 'credential',
}
LOGIN_URL = '/login'

View File

@@ -0,0 +1,30 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.conf import urls
from django.contrib import admin
import django.contrib.auth.views
from polls import views
import oauth2client.contrib.django_util.site as django_util_site
urlpatterns = [
urls.url(r'^$', views.index),
urls.url(r'^profile_required$', views.get_profile_required),
urls.url(r'^profile_enabled$', views.get_profile_optional),
urls.url(r'^admin/', urls.include(admin.site.urls)),
urls.url(r'^login', django.contrib.auth.views.login, name="login"),
urls.url(r'^oauth2/', urls.include(django_util_site.urls)),
]

View File

@@ -0,0 +1,21 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myoauth.settings")
application = get_wsgi_application()

View File

@@ -0,0 +1,23 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.contrib.auth.models import User
from django.db import models
from oauth2client.contrib.django_util.models import CredentialsField
class CredentialsModel(models.Model):
user_id = models.OneToOneField(User)
credential = CredentialsField()

View File

@@ -0,0 +1,45 @@
<!--
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-->
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>

View File

@@ -0,0 +1,41 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.http import HttpResponse
from oauth2client.contrib.django_util import decorators
def index(request):
return HttpResponse("Hello world!")
@decorators.oauth_required
def get_profile_required(request):
resp, content = request.oauth.http.request(
'https://www.googleapis.com/plus/v1/people/me')
return HttpResponse(content)
@decorators.oauth_enabled
def get_profile_optional(request):
if request.oauth.has_credentials():
# this could be passed into a view
# request.oauth.http is also initialized
return HttpResponse('User email: {}'.format(
request.oauth.credentials.id_token['email']))
else:
return HttpResponse(
'Here is an OAuth Authorize link:<a href="{}">Authorize</a>'
.format(request.oauth.get_authorize_redirect()))

View File

@@ -0,0 +1,3 @@
Django==1.10.0
oauth2client==3.0.0
jsonpickle==0.9.3

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myoauth.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View File

@@ -0,0 +1,107 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'eiw+mvmua#98n@p2xq+c#liz@r2&#-s07nkgz)+$zcl^o4$-$o'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
'oauth2client.contrib.django_util',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'myoauth.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'myoauth.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
GOOGLE_OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID'
GOOGLE_OAUTH2_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
GOOGLE_OAUTH2_SCOPES = (
'email', 'profile')

View File

@@ -0,0 +1,26 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.conf import urls
from polls import views
import oauth2client.contrib.django_util.site as django_util_site
urlpatterns = [
urls.url(r'^$', views.index),
urls.url(r'^profile_required$', views.get_profile_required),
urls.url(r'^profile_enabled$', views.get_profile_optional),
urls.url(r'^oauth2/', urls.include(django_util_site.urls))
]

View File

@@ -0,0 +1,21 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myoauth.settings")
application = get_wsgi_application()

View File

@@ -0,0 +1,41 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django import http
from oauth2client.contrib.django_util import decorators
def index(request):
return http.HttpResponse("Hello world!")
@decorators.oauth_required
def get_profile_required(request):
resp, content = request.oauth.http.request(
'https://www.googleapis.com/plus/v1/people/me')
return http.HttpResponse(content)
@decorators.oauth_enabled
def get_profile_optional(request):
if request.oauth.has_credentials():
# this could be passed into a view
# request.oauth.http is also initialized
return http.HttpResponse('User email: {}'.format(
request.oauth.credentials.id_token['email']))
else:
return http.HttpResponse(
'Here is an OAuth Authorize link:<a href="{}">Authorize</a>'
.format(request.oauth.get_authorize_redirect()))

View File

@@ -0,0 +1,3 @@
Django==1.10.0
oauth2client==3.0.0
jsonpickle==0.9.3