Skip to content

Commit

Permalink
Merge branch 'release/0-1-2'
Browse files Browse the repository at this point in the history
  • Loading branch information
rszalski committed Nov 23, 2016
2 parents 528260b + afde2ae commit 29991ce
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 54 deletions.
17 changes: 14 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.1.1] - 2015-11-15
## [0.1.2] - 2016-11-23

### Fixed
- Files other than Python source code are now correctly included in bdists.

### Changed
- Various improvements to Django Plugin regarding e.g. templates and URLs.


## [0.1.1] - 2016-11-15

### Added
- Flask plugin.
Expand All @@ -14,6 +23,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- Stripping the PKCS5 padding works correctly on Python2 now.

## [0.1.0] - 2015-10-23

## [0.1.0] - 2016-10-23

### Added
- Initial SDK release
- Initial SDK release.
44 changes: 36 additions & 8 deletions plugins/django_yoti/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ INSTALLED_APPS = [
]
```

* In order to use context tags inside your template (`{{ yoti_site_verification }}`, `{{ yoti_login_button_*}}`),
you should include `django_yoti`'s context processors into your templates configuration like this:
* Django Yoti plugin provides the following template context vars:
- `yoti_site_verification`
- `yoti_application_id`
- `yoti_login_button_*`

* If you're using django template backend that supports context processors
like default DTL (Django Template Language) and want to use context tags
inside your template (e.g. `{{ yoti_login_button_*}}`), then you should
include `django_yoti`'s context processors into your templates
configuration like this:
```python
# your_django_project/settings.py

Expand All @@ -36,6 +44,13 @@ TEMPLATES = [
},
]
```
* Otherwise you'll have to pass yoti context to your templates manually:
```python
from django_yoti import yoti_context

def some_view(request):
return render(request, 'index.html', yoti_context)
```

* And then use the following settings to configure the plugin:

Expand Down Expand Up @@ -104,7 +119,7 @@ YOTI = {
```
* **`YOTI_LOGIN_VIEW`**<br>
If *not* authenticated user is trying to access a view with
`@yoti_authenticated` decorator, he/she will be redirected to this view.
`@yoti_authenticated` decorator, he/she will be redirected to this view.<br>
Example: `login`<br>
In this case you should have something like this in your project's `urls.py` file:
```python
Expand Down Expand Up @@ -160,11 +175,7 @@ you can use a `{{ yoti_site_verification }}` tag inside 'head' tag of that page.
{{ yoti_login_button_md }}
{{ yoti_login_button_lg }}
```
- or with a default one `{{ yoti_login_button }}`, in case you're using DTL
as a template language)
- or with `{{ yoti_login_button(size='small', text='Log In with Yoti')`, in
case you're using Jinja2 as your template language<br>
Available button sizes: `small`, `medium`, `large`
- or with a default one `{{ yoti_login_button }}`<br>

By clicking this button, user will be redirected to the Yoti Authentication page.

Expand All @@ -185,6 +196,23 @@ def profile_view(request):
user_profile = request.yoti_user_profile
return render(request, 'profile.html', user_profile)
```
<br>

To make `yoti_authenticated` decorator work with django class based
views as well as with classic method based views, you can use it while
declaring your project's urls:
```python
# your_django_project/urls.py
from django_yoti import yoti_authenticated

urlpatterns = [
...
url(r'^profile/', yoti_authenticated(views.profile_view), name='yoti_profile'),
# or
url(r'^profile/', yoti_authenticated(views.ProfileView.as_view()), name='yoti_profile'),
...
]
```

4. All *not authenticated* users trying to access endpoint with this decorator,
will be redirected to an endpoint, provided by the `YOTI_LOGIN_VIEW` setting.
Expand Down
14 changes: 7 additions & 7 deletions plugins/django_yoti/django_yoti/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from .settings import YOTI_VERIFICATION_KEY, YOTI_APPLICATION_ID


def yoti_context(request):
context = login_button_context(request)
context.update(site_verification_context(request))
context.update(application_context(request))
def yoti_context(request=None):
context = login_button_context()
context.update(site_verification_context())
context.update(application_context())
return context


def login_button_context(request):
def login_button_context():
return {
'yoti_login_button': get_login_button_html,
'yoti_login_button_sm': get_login_button_html('small'),
Expand All @@ -20,12 +20,12 @@ def login_button_context(request):
}


def site_verification_context(request):
def site_verification_context():
raw_text = '<meta name="yoti-site-verification" content="{0}">'.format(
YOTI_VERIFICATION_KEY
)
return {'yoti_site_verification': format_html(raw_text)}


def application_context(request):
def application_context():
return {'yoti_application_id': YOTI_APPLICATION_ID}
4 changes: 3 additions & 1 deletion plugins/django_yoti/django_yoti/decorators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from functools import wraps
from django.shortcuts import redirect
from django.urls import reverse

from .settings import YOTI_LOGIN_VIEW


Expand All @@ -8,7 +10,7 @@ def yoti_authenticated(view_func):
def _decorated(request, *args, **kwargs):
activity_details = request.session.get('activity_details')
if not activity_details or activity_details.get('outcome') != 'SUCCESS':
return redirect(YOTI_LOGIN_VIEW)
return redirect(reverse(YOTI_LOGIN_VIEW))

yoti_user_id = activity_details.get('user_id')
yoti_user_profile = activity_details.get('user_profile')
Expand Down
15 changes: 8 additions & 7 deletions plugins/django_yoti/django_yoti/login_button.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from django.utils.html import format_html
from django.template.loader import render_to_string

from .settings import YOTI_APPLICATION_ID, YOTI_LOGIN_BUTTON_LABEL

LOGIN_BUTTON_SIZES = ('small', 'medium', 'large')


def get_login_button_html(size=None, text=YOTI_LOGIN_BUTTON_LABEL):
if size and size not in LOGIN_BUTTON_SIZES:
size = None
data_size = 'data-size="{0}"'.format(size) if size else ''
raw_text = '<span data-yoti-application-id="{0}" {1}>' \
'{2}</span>'.format(YOTI_APPLICATION_ID, data_size, text)
return format_html(raw_text)
size = size if size in LOGIN_BUTTON_SIZES else None
return render_to_string('login_button.html', {
'app_id': YOTI_APPLICATION_ID,
'size': size,
'text': text,
})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<span data-yoti-application-id="{{ app_id }}" {% if size %}data-size="{{ size }}"{% endif %}>{{ text }}</span>
16 changes: 8 additions & 8 deletions plugins/django_yoti/django_yoti/tests/test_context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ def test_yoti_context(self):
keys = ('yoti_application_id', 'yoti_site_verification',
'yoti_login_button', 'yoti_login_button_sm',
'yoti_login_button_md', 'yoti_login_button_lg')
assert set(self.context.keys()) == set(keys)
self.assertEqual(set(self.context.keys()), set(keys))

def test_application_id(self):
app_id = self.context.get('yoti_application_id')
expected_app_id = self.defaults.get('YOTI_APPLICATION_ID')
assert app_id == expected_app_id
self.assertEqual(app_id, expected_app_id)

def test_verification_key(self):
context_tag = self.context.get('yoti_site_verification')
Expand All @@ -36,21 +36,21 @@ def test_verification_key(self):

def test_predefined_login_buttons(self):
context = self.context
assert 'data-size="small"' in context.get('yoti_login_button_sm')
assert 'data-size="medium"' in context.get('yoti_login_button_md')
assert 'data-size="large"' in context.get('yoti_login_button_lg')
self.assertIn('data-size="small"', context.get('yoti_login_button_sm'))
self.assertIn('data-size="medium"', context.get('yoti_login_button_md'))
self.assertIn('data-size="large"', context.get('yoti_login_button_lg'))

def test_login_button_func(self):
app_id = self.defaults.get('YOTI_APPLICATION_ID')
button_label = self.defaults.get('YOTI_LOGIN_BUTTON_LABEL')
login_button_func = self.context.get('yoti_login_button')
assert hasattr(login_button_func, '__call__')
self.assertTrue(hasattr(login_button_func, '__call__'))
button_html = login_button_func(text=button_label)
expected = '<span data-yoti-application-id="{0}" >' \
'{1}</span>'.format(app_id, button_label)
assert button_html == expected
self.assertEqual(button_html, expected)

def test_context_login_button_func_with_different_sizes(self):
for size in ('small', 'medium', 'large'):
button_html = get_login_button_html(size)
assert 'data-size="{0}"'.format(size) in button_html
self.assertIn('data-size="{0}"'.format(size), button_html)
28 changes: 13 additions & 15 deletions plugins/django_yoti/django_yoti/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import re

from django.test import TestCase, Client, RequestFactory
from django.http.response import HttpResponse, HttpResponseRedirectBase
from django.contrib.sessions.middleware import SessionMiddleware
Expand All @@ -17,21 +15,21 @@ def setUp(self):

def test_auth_view(self):
response = self.client.get('/auth/')
assert isinstance(response, HttpResponse)
assert response.status_code == 200
assert 'meta name="yoti-site-verification"' in str(response.content)
self.assertIsInstance(response, HttpResponse)
self.assertEqual(response.status_code, 200)
self.assertIn('meta name="yoti-site-verification"', str(response.content))

def test_login_view(self):
response = self.client.get('/login/')
assert isinstance(response, HttpResponse)
assert response.status_code == 200
self.assertIsInstance(response, HttpResponse)
self.assertEqual(response.status_code, 200)

def test_profile_not_logged_in(self):
request = self.factory.get('/profile')
self._update_session(request)
response = profile(request)
assert isinstance(response, HttpResponseRedirectBase)
assert response.url == '/login/'
self.assertIsInstance(response, HttpResponseRedirectBase)
self.assertEqual(response.url, '/login/')

def test_profile_outcome_is_failure(self):
receipt = {'remember_me_id': 'some_id',
Expand All @@ -42,8 +40,8 @@ def test_profile_outcome_is_failure(self):
self._update_session(request, activity_details=dict(activity_details))
response = profile(request)

assert isinstance(response, HttpResponseRedirectBase)
assert response.url == '/login/'
self.assertIsInstance(response, HttpResponseRedirectBase)
self.assertEqual(response.url, '/login/')

def test_profile_outcome_is_success(self):
user_id = 'some_id'
Expand All @@ -57,10 +55,10 @@ def test_profile_outcome_is_success(self):
self._update_session(request, activity_details=dict(activity_details))
response = profile(request)

assert isinstance(response, HttpResponse)
assert response.status_code == 200
assert getattr(request, 'yoti_user_id', None) == user_id
assert getattr(request, 'yoti_user_profile', None) == user_profile
self.assertIsInstance(response, HttpResponse)
self.assertEqual(response.status_code, 200)
self.assertEqual(getattr(request, 'yoti_user_id', None), user_id)
self.assertEqual(getattr(request, 'yoti_user_profile', None), user_profile)

@staticmethod
def _update_session(request, **params):
Expand Down
3 changes: 2 additions & 1 deletion plugins/django_yoti/django_yoti/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from yoti import Client
from django.shortcuts import render, redirect
from django.urls import reverse

from .decorators import yoti_authenticated
from .settings import (
Expand All @@ -21,7 +22,7 @@ def auth(request):
client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH)
activity_details = client.get_activity_details(token)
request.session['activity_details'] = dict(activity_details)
return redirect(YOTI_REDIRECT_TO)
return redirect(reverse(YOTI_REDIRECT_TO))


@yoti_authenticated
Expand Down
1 change: 0 additions & 1 deletion plugins/django_yoti/example/yoti_example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,5 @@
STATIC_URL = '/static/'

YOTI = {
'YOTI_REDIRECT_TO': 'profile',
'YOTI_LOGIN_VIEW': 'login',
}
2 changes: 1 addition & 1 deletion plugins/django_yoti/example/yoti_example/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
urlpatterns = [
url(r'^yoti/', include('django_yoti.urls')),
url(r'^login/', views.login, name='login'),
url(r'^profile/', views.profile, name='profile'),
url(r'^profile/', views.profile, name='yoti_profile'),
url(r'^admin/', admin.site.urls),
]
3 changes: 2 additions & 1 deletion plugins/django_yoti/setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages

VERSION = '0.1.0'
VERSION = '0.1.1'
long_description = 'Long description'

setup(
name='django_yoti',
version=VERSION,
packages=find_packages(),
include_package_data=True,
license='MIT',
description='Yoti Django plugin for back-end integration.',
long_description=long_description,
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages

VERSION = '0.1.1'
VERSION = '0.1.2'
long_description = 'This package contains the tools you need to quickly ' \
'integrate your Python back-end with Yoti, so that your ' \
'users can share their identity details with your ' \
Expand Down

0 comments on commit 29991ce

Please sign in to comment.