Compare commits

..

4 Commits

Author SHA1 Message Date
Cristi Vîjdea 51ec07261d Improve OAuth2 behaviour and documentation (#90)
* Set OAUTH2_REDIRECT_URL to oauth2-redirect.html by default
* Add example SWAGGER_SETTINGS for OAuth
* Add note about redirect URL
2018-03-24 13:05:37 +02:00
Cristi Vîjdea a9cdf6d561 Fix type of properties in Schema docstring
Fixes #87.
2018-03-21 13:39:14 +02:00
Cristi Vîjdea a64ce95e3c Reset testproj migrations
Heroku deployment issues...
2018-03-18 20:35:02 +02:00
Cristi Vîjdea c9147a5746 Fix testproj people app 2018-03-18 20:20:04 +02:00
18 changed files with 89 additions and 98 deletions
+8
View File
@@ -3,6 +3,14 @@ Changelog
#########
*********
**1.6.0**
*********
*Release date: Mar 24, 2018*
- **IMPROVED:** ``OAUTH2_REDIRECT_URL`` will now default to the built in ``oauth2-redirect.html`` file
*********
**1.5.1**
*********
+1 -1
View File
@@ -273,7 +273,7 @@ def role_github_user(name, rawtext, text, lineno, inliner, options=None, content
options = options or {}
content = content or []
if not re.match(r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$", text):
if not re.match(r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$", text, re.IGNORECASE):
return sphinx_err(inliner, lineno, rawtext, '"%s" is not a valid GitHub username.' % text)
ref = gh_user_uri.format(text)
+34
View File
@@ -63,3 +63,37 @@ settings described below were added as a result of discussion in issue :issue:`5
The settings of interest can be found on the :ref:`settings page <oauth2-settings>`. Configuration options are similar
to most OAuth client setups like web or mobile applications. Reading the relevant ``swagger-ui`` docmentation linked
will also probably help.
Example
^^^^^^^
A very simple working configuration was provided by :ghuser:`Vigrond`, originally at
`https://github.com/Vigrond/django_oauth2_example <https://github.com/Vigrond/django_oauth2_example>`_.
.. code-block:: python
SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': False,
'SECURITY_DEFINITIONS': {
'Your App API - Swagger': {
'type': 'oauth2',
'authorizationUrl': '/yourapp/o/authorize',
'tokenUrl': '/yourapp/o/token/',
'flow": "accessCode',
'scopes': {
'read:groups': 'read groups',
}
}
},
'OAUTH2_CONFIG': {
'clientId': 'yourAppClientId',
'clientSecret': 'yourAppClientSecret',
'appName': 'your application name'
},
}
If the OAuth2 provider requires you to provide the full absolute redirect URL, the default value for most
``staticfiles`` configurations will be ``<origin>/static/drf-yasg/swagger-ui-dist/oauth2-redirect.html``. If this is
not suitable for some reason, you can override the ``OAUTH2_REDIRECT_URL`` setting as appropriate.
+4 -1
View File
@@ -259,7 +259,10 @@ Controls how many levels are expaned by default when showing nested models.
OAUTH2_REDIRECT_URL
-------------------
Used when OAuth2 authenitcation of API requests via swagger-ui is desired.
Used when OAuth2 authenitcation of API requests via swagger-ui is desired. If ``None`` is passed, the
``oauth2RedirectUrl`` parameter will be set to ``{% static 'drf-yasg/swagger-ui-dist/oauth2-redirect.html' %}``. This
is the default `https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html <oauth2-redirect>`_
file provided by ``swagger-ui``.
**Default**: :python:`None` |br|
*Maps to parameter*: ``oauth2RedirectUrl``
+1 -1
View File
@@ -425,7 +425,7 @@ class Schema(SwaggerDict):
:param str format: value format, see OpenAPI spec
:param list enum: restrict possible values
:param str pattern: pattern if type is ``string``
:param list[.Schema,.SchemaRef] properties: object properties; required if `type` is ``object``
:param dict[str,(.Schema,.SchemaRef)] properties: object properties; required if `type` is ``object``
:param bool,.Schema,.SchemaRef additional_properties: allow wildcard properties not listed in `properties`
:param list[str] required: list of requried property names
:param .Schema,.SchemaRef items: type of array items, only valid if `type` is ``array``
@@ -38,7 +38,7 @@ function initSwaggerUi() {
],
layout: "StandaloneLayout",
filter: true,
requestInterceptor: function(request) {
requestInterceptor: function (request) {
var headers = request.headers || {};
var csrftoken = document.querySelector("[name=csrfmiddlewaretoken]");
if (csrftoken) {
@@ -49,8 +49,15 @@ function initSwaggerUi() {
};
var swaggerSettings = JSON.parse(document.getElementById('swagger-settings').innerHTML);
console.log(swaggerSettings);
if (!('oauth2RedirectUrl' in swaggerSettings)) {
var oauth2RedirectUrl = document.getElementById('oauth2-redirect-url');
if (oauth2RedirectUrl) {
swaggerSettings['oauth2RedirectUrl'] = oauth2RedirectUrl.href;
oauth2RedirectUrl.parentNode.removeChild(oauth2RedirectUrl);
}
}
console.log(swaggerSettings);
for (var p in swaggerSettings) {
if (swaggerSettings.hasOwnProperty(p)) {
swaggerConfig[p] = swaggerSettings[p];
@@ -67,6 +67,8 @@
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
<script src="{% static 'drf-yasg/swagger-ui-init.js' %}"></script>
<a id="oauth2-redirect-url" href="{% static 'drf-yasg/swagger-ui-dist/oauth2-redirect.html' %}" class="hidden"></a>
<div id="django-session-auth" class="hidden">
{% if USE_SESSION_AUTH %}
{% csrf_token %}
+22 -1
View File
@@ -1,8 +1,9 @@
# Generated by Django 2.0 on 2017-12-23 09:07
# Generated by Django 2.0.1 on 2018-03-18 18:32
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
@@ -23,8 +24,28 @@ class Migration(migrations.Migration):
('slug', models.SlugField(blank=True, help_text='slug model help_text', unique=True)),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_modified', models.DateTimeField(auto_now=True)),
('article_type', models.PositiveSmallIntegerField(choices=[(1, 'first'), (2, 'second'), (3, 'third'), (7, 'seven'), (8, 'eight')], help_text='IntegerField declared on model with choices=(...) and exposed via ModelSerializer', null=True)),
('cover', models.ImageField(blank=True, upload_to='article/original/')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='ArticleGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('title', models.CharField(help_text='title model help_text', max_length=255, unique=True)),
('slug', models.SlugField(blank=True, help_text='slug model help_text', unique=True)),
],
),
migrations.AddField(
model_name='article',
name='group',
field=models.ForeignKey(blank=True, default=None, on_delete=django.db.models.deletion.PROTECT, related_name='articles_as_main', to='articles.ArticleGroup'),
),
migrations.AddField(
model_name='article',
name='original_group',
field=models.ForeignKey(blank=True, default=None, on_delete=django.db.models.deletion.PROTECT, related_name='articles_as_original', to='articles.ArticleGroup'),
),
]
@@ -1,18 +0,0 @@
# Generated by Django 2.0.1 on 2018-02-26 18:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('articles', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='article',
name='article_type',
field=models.PositiveSmallIntegerField(choices=[(1, 'first'), (2, 'second'), (3, 'third'), (7, 'seven'), (8, 'eight')], help_text='IntegerField declared on model with choices=(...) and exposed via ModelSerializer', null=True),
),
]
@@ -1,36 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-03-10 01:42
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('articles', '0002_article_article_type'),
]
operations = [
migrations.CreateModel(
name='ArticleGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('title', models.CharField(help_text='title model help_text', max_length=255, unique=True)),
('slug', models.SlugField(blank=True, help_text='slug model help_text', unique=True)),
],
),
migrations.AddField(
model_name='article',
name='group',
field=models.ForeignKey(blank=True, default=None, on_delete=django.db.models.deletion.PROTECT, related_name='articles_as_main', to='articles.ArticleGroup'),
),
migrations.AddField(
model_name='article',
name='original_group',
field=models.ForeignKey(blank=True, default=None, on_delete=django.db.models.deletion.PROTECT, related_name='articles_as_original', to='articles.ArticleGroup'),
),
]
+2 -4
View File
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.10 on 2018-03-18 16:22
from __future__ import unicode_literals
# Generated by Django 2.0.1 on 2018-03-18 18:32
from django.db import migrations, models
import django.db.models.deletion
@@ -26,7 +24,7 @@ class Migration(migrations.Migration):
name='Person',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('Identity', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='person', to='people.Identity')),
('identity', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='person', to='people.Identity')),
],
),
]
@@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.10 on 2018-03-18 17:04
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('people', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='person',
name='Identity',
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='person', to='people.Identity'),
),
]
+1 -2
View File
@@ -7,5 +7,4 @@ class Identity(models.Model):
class Person(models.Model):
Identity = models.OneToOneField(Identity, related_name='person',
on_delete=models.PROTECT)
identity = models.OneToOneField(Identity, related_name='person', on_delete=models.PROTECT)
+1 -1
View File
@@ -10,7 +10,7 @@ class IdentitySerializer(serializers.ModelSerializer):
class PersonSerializer(serializers.ModelSerializer):
identity = IdentitySerializer(read_only=True)
identity = IdentitySerializer()
class Meta:
model = Person
+1 -1
View File
@@ -1,4 +1,4 @@
# Generated by Django 2.0 on 2017-12-23 09:07
# Generated by Django 2.0.1 on 2018-03-18 18:32
from django.conf import settings
from django.db import migrations, models
+1 -3
View File
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-02-21 23:26
from __future__ import unicode_literals
# Generated by Django 2.0.1 on 2018-03-18 18:32
from django.db import migrations, models
import django.db.models.deletion
+1 -5
View File
@@ -732,10 +732,9 @@ definitions:
title: LastName
type: string
maxLength: 30
readOnly: true
Person:
required:
- Identity
- identity
type: object
properties:
id:
@@ -744,9 +743,6 @@ definitions:
readOnly: true
identity:
$ref: '#/definitions/Identity'
Identity:
title: Identity
type: integer
Project:
required:
- projectName
+1 -1
View File
@@ -66,4 +66,4 @@ known_third_party =
coreapi,coreschema,datadiff,dj_database_url,django,django_filters,djangorestframework_camel_case,flex,gunicorn,
inflection,pygments,pytest,rest_framework,ruamel,setuptools_scm,swagger_spec_validator,uritemplate,user_agents,
whitenoise
known_first_party = drf_yasg,testproj,articles,snippets,users,urlconfs
known_first_party = drf_yasg,testproj,articles,people,snippets,todo,users,urlconfs