Add verbose name and description for scopes.

This commit is contained in:
Ignacio Fiorentino 2016-06-16 17:18:39 -03:00
parent d4f25c3dd2
commit 4cc7474c19
5 changed files with 73 additions and 12 deletions

View file

@ -54,12 +54,23 @@ OpenID Connect Clients will use scope values to specify what access privileges a
`Here <http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims>`_ you have the standard scopes defined by the protocol.
You can create or modify scopes using:
* ``info_scopename`` class property for setting the verbose name and description.
* ``scope_scopename`` method for returning some information related.
Check out an example of how to implement it::
from django.utils.translation import ugettext as _
from oidc_provider.lib.claims import ScopeClaims
class MyAppScopeClaims(ScopeClaims):
info_books = (
_(u'Books'), # Verbose name of the scope.
_(u'Access to your books.'), # Description of the scope.
)
def scope_books(self):
# Here, for example, you can search books for this user.
# self.user - Django user instance.
@ -72,11 +83,14 @@ Check out an example of how to implement it::
return dic
You can create our own scopes using the convention:
# If you want to change the description of the profile scope, you can redefine it.
info_profile = (
_(u'Profile'),
_(u'Another description.'),
)
``def scope_somename(self):``
If a field is empty or ``None`` will be cleaned from the response.
.. note::
If a field is empty or ``None`` inside the dictionary your return on ``scope_scopename`` method, it will be cleaned from the response.
OIDC_IDTOKEN_EXPIRE
===================
@ -93,9 +107,9 @@ OPTIONAL. ``str`` or ``(list, tuple)``.
A string with the location of your function hook or ``list`` or ``tuple`` with hook functions.
Here you can add extra dictionary values specific for your app into id_token.
The ``list`` or ``tuple`` is useful when You want to set multiple hooks, i.e. one for permissions and second for some special field.
The ``list`` or ``tuple`` is useful when you want to set multiple hooks, i.e. one for permissions and second for some special field.
The function receives a ``id_token`` dictionary and ``user`` instance
The function receives a ``id_token`` dictionary and ``user`` instance
and returns it with additional fields.
Default is::

View file

@ -35,7 +35,6 @@ class ScopeClaims(object):
scopes = []
for name in self.__class__.__dict__:
if name.startswith('scope_'):
scope = name.split('scope_')[1]
scopes.append(scope)
@ -56,13 +55,34 @@ class ScopeClaims(object):
return aux_dic
@classmethod
def get_scopes_info(cls, scopes=[]):
scopes_info = []
for name in cls.__dict__:
if name.startswith('info_'):
scope_name = name.split('info_')[1]
if scope_name in scopes:
touple_info = getattr(cls, name)
scopes_info.append({
'scope': scope_name,
'name': touple_info[0],
'description': touple_info[1],
})
return scopes_info
class StandardScopeClaims(ScopeClaims):
"""
Based on OpenID Standard Claims.
See: http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
"""
info_profile = (
_(u'Basic profile'),
_(u'Access to your basic information. Includes names, gender, birthdate and other information.'),
)
def scope_profile(self):
dic = {
'name': getattr(self.userinfo, 'name', None),
@ -83,6 +103,10 @@ class StandardScopeClaims(ScopeClaims):
return dic
info_email = (
_(u'Email'),
_(u'Access to your email address.'),
)
def scope_email(self):
dic = {
'email': getattr(self.user, 'email', None),
@ -91,6 +115,10 @@ class StandardScopeClaims(ScopeClaims):
return dic
info_phone = (
_(u'Phone number'),
_(u'Access to your phone number.'),
)
def scope_phone(self):
dic = {
'phone_number': getattr(self.userinfo, 'phone_number', None),
@ -99,6 +127,10 @@ class StandardScopeClaims(ScopeClaims):
return dic
info_address = (
_(u'Address information'),
_(u'Access to your address. Includes country, locality, street and other information.'),
)
def scope_address(self):
dic = {
'address': {

View file

@ -7,6 +7,7 @@ except ImportError:
from django.utils import timezone
from oidc_provider.lib.claims import StandardScopeClaims
from oidc_provider.lib.errors import *
from oidc_provider.lib.utils.params import *
from oidc_provider.lib.utils.token import *
@ -207,3 +208,16 @@ class AuthorizeEndpoint(object):
pass
return value
def get_scopes_information(self):
"""
Return a list with the description of all the scopes requested.
"""
scopes = StandardScopeClaims.get_scopes_info(self.params.scope)
scopes_extra = settings.get('OIDC_EXTRA_SCOPE_CLAIMS', import_str=True).get_scopes_info(self.params.scope)
for index_extra, scope_extra in enumerate(scopes_extra):
for index, scope in enumerate(scopes[:]):
if scope_extra['scope'] == scope['scope']:
del scopes[index]
return scopes + scopes_extra

View file

@ -3,15 +3,15 @@
<p>Client <strong>{{ client.name }}</strong> would like to access this information of you ...</p>
<form method="post" action="{% url 'oidc_provider:authorize' %}">
{% csrf_token %}
{{ hidden_inputs }}
<ul>
{% for scope in params.scope %}
<li>{{ scope | capfirst }}</li>
{% endfor %}
{% for scope in scopes %}
<li><strong>{{ scope.name }}</strong> <br><i>{{ scope.description }}</i></li>
{% endfor %}
</ul>
<input type="submit" value="Decline" />

View file

@ -73,6 +73,7 @@ class AuthorizeView(View):
'client': authorize.client,
'hidden_inputs': hidden_inputs,
'params': authorize.params,
'scopes': authorize.get_scopes_information(),
}
return render(request, 'oidc_provider/authorize.html', context)