User scope objects everywhere. Switch scope objects to namedtuples. Pass the user when validating whether the user has authorized such scopes in the past. Make sure we calculate the scope string using all user scopes form all previously granted tokens.

This commit is contained in:
jakedt 2014-03-19 18:09:09 -04:00
parent c93c62600d
commit 3b7b12085d
6 changed files with 103 additions and 76 deletions

View file

@ -1,49 +1,65 @@
READ_REPO = {
'scope': 'repo:read',
'icon': 'fa-hdd-o',
'title': 'View all visible repositories',
'description': ('This application will be able to view and pull all repositories visible to the '
'granting user or robot account')
}
from collections import namedtuple
WRITE_REPO = {
'scope': 'repo:write',
'icon': 'fa-hdd-o',
'title': 'Read/Write to any accessible repositories',
'description': ('This application will be able to view, push and pull to all repositories to '
'which the granting user or robot account has write access')
}
ADMIN_REPO = {
'scope': 'repo:admin',
'icon': 'fa-hdd-o',
'title': 'Administer Repositories',
'description': ('This application will have administrator access to all repositories to which '
'the granting user or robot account has access')
}
Scope = namedtuple('scope', ['scope', 'icon', 'title', 'description'])
CREATE_REPO = {
'scope': 'repo:create',
'icon': 'fa-plus',
'title': 'Create Repositories',
'description': ('This application will be able to create repositories in to any namespaces that '
'the granting user or robot account is allowed to create repositories')
}
READ_USER = {
'scope': 'user:read',
'icon': 'fa-user',
'title': 'Read User Information',
'description': ('This application will be able to read user information such as username and '
'email address.'),
}
READ_REPO = Scope(scope='repo:read',
icon='fa-hdd-o',
title='View all visible repositories',
description=('This application will be able to view and pull all repositories '
'visible to the granting user or robot account'))
ALL_SCOPES = {scope['scope']:scope for scope in (READ_REPO, WRITE_REPO, ADMIN_REPO, CREATE_REPO,
READ_USER)}
WRITE_REPO = Scope(scope='repo:write',
icon='fa-hdd-o',
title='Read/Write to any accessible repositories',
description=('This application will be able to view, push and pull to all '
'repositories to which the granting user or robot account has '
'write access'))
ADMIN_REPO = Scope(scope='repo:admin',
icon='fa-hdd-o',
title='Administer Repositories',
description=('This application will have administrator access to all '
'repositories to which the granting user or robot account has '
'access'))
CREATE_REPO = Scope(scope='repo:create',
icon='fa-plus',
title='Create Repositories',
description=('This application will be able to create repositories in to any '
'namespaces that the granting user or robot account is allowed to '
'create repositories'))
READ_USER = Scope(scope= 'user:read',
icon='fa-user',
title='Read User Information',
description=('This application will be able to read user information such as '
'username and email address.'))
DIRECT_LOGIN = Scope(scope='direct_user_login',
icon='fa-exclamation-triangle',
title='Full Access',
description=('This scope should not be available to OAuth applications. '
'Never approve a request for this scope!'))
ALL_SCOPES = {scope.scope:scope for scope in (READ_REPO, WRITE_REPO, ADMIN_REPO, CREATE_REPO,
READ_USER)}
IMPLIED_SCOPES = {
ADMIN_REPO: {ADMIN_REPO, WRITE_REPO, READ_REPO},
WRITE_REPO: {WRITE_REPO, READ_REPO},
READ_REPO: {READ_REPO},
CREATE_REPO: {CREATE_REPO},
READ_USER: {READ_USER},
None: set(),
}
def scopes_from_scope_string(scopes):
return {ALL_SCOPES.get(scope, {}).get('scope', None) for scope in scopes.split(',')}
return {ALL_SCOPES.get(scope, None) for scope in scopes.split(',')}
def validate_scope_string(scopes):
@ -56,8 +72,10 @@ def is_subset_string(full_string, expected_string):
in full_string.
"""
full_scopes = scopes_from_scope_string(full_string)
full_implied_scopes = set.union(*[IMPLIED_SCOPES[scope] for scope in full_scopes])
expected_scopes = scopes_from_scope_string(expected_string)
return expected_scopes.issubset(full_scopes)
return expected_scopes.issubset(full_implied_scopes)
def get_scope_information(scopes_string):
scopes = scopes_from_scope_string(scopes_string)
@ -65,10 +83,10 @@ def get_scope_information(scopes_string):
for scope in scopes:
if scope:
scope_info.append({
'title': ALL_SCOPES[scope]['title'],
'scope': ALL_SCOPES[scope]['scope'],
'description': ALL_SCOPES[scope]['description'],
'icon': ALL_SCOPES[scope]['icon'],
})
'title': scope.title,
'scope': scope.scope,
'description': scope.description,
'icon': scope.icon,
})
return scope_info