def oauth_make_token(user, auth_client, scope, user_session=None): # Look for an existing token token = auth_client.authtoken_for(user, user_session) # If token exists, add to the existing scope if token: token.add_scope(scope) else: # If there's no existing token, create one if auth_client.confidential: token = AuthToken(user=user, auth_client=auth_client, scope=scope, token_type='bearer') token = failsafe_add(db.session, token, user=user, auth_client=auth_client) elif user_session: token = AuthToken( user_session=user_session, auth_client=auth_client, scope=scope, token_type='bearer', ) token = failsafe_add(db.session, token, user_session=user_session, auth_client=auth_client) else: raise ValueError("user_session not provided") return token
def oauth_make_token(user, client, scope, user_session=None): # Look for an existing token if client.confidential: token = AuthToken.query.filter_by(user=user, client=client).first() elif user_session: token = AuthToken.query.filter_by(user_session=user_session, client=client).first() else: raise ValueError("user_session not provided") # If token exists, add to the existing scope if token: token.add_scope(scope) else: # If there's no existing token, create one if client.confidential: token = AuthToken(user=user, client=client, scope=scope, token_type='bearer') token = failsafe_add(db.session, token, user=user, client=client) elif user_session: token = AuthToken(user_session=user_session, client=client, scope=scope, token_type='bearer') token = failsafe_add(db.session, token, user_session=user_session, client=client) # TODO: Look up Resources for items in scope; look up their providing clients apps, # and notify each client app of this token return token
def notify_org_data_changed(org, user, changes, team=None): """ Like :func:`notify_user_data_changed`, except we'll also look at all other owners of this org to find apps that need to be notified. """ client_users = {} if team is not None: team_access = set(org.clients_with_team_access()) | (set( user.clients_with_team_access()) if user else set()) else: team_access = [] for token in AuthToken.all(users=org.owners.users): if ('organizations' in token.effective_scope or 'organizations/*' in token.effective_scope ) and token.client.notification_uri and token.is_valid(): if team is not None: if token.client not in team_access: continue client_users.setdefault(token.client, []).append(token.user) # Now we have a list of clients to notify and a list of users to notify them with for client, users in client_users.items(): if user is not None and user in users: notify_user = user else: notify_user = users[0] # First user available send_notice.delay( client.notification_uri, data={ 'userid': notify_user.buid, # XXX: Deprecated parameter 'buid': notify_user.buid, 'type': 'org' if team is None else 'team', 'orgid': org.buid, 'teamid': team.buid if team is not None else None, 'changes': changes, })
def notify_org_data_changed(org, user, changes, team=None): """ Like :func:`notify_user_data_changed`, except we'll also look at all other owners of this org to find apps that need to be notified. """ client_users = {} if team is not None: team_access = set(org.clients_with_team_access()) | (set(user.clients_with_team_access()) if user else set()) else: team_access = [] for token in AuthToken.all(users=org.owners.users): if ('organizations' in token.effective_scope or 'organizations/*' in token.effective_scope) and token.client.notification_uri and token.is_valid(): if team is not None: if token.client not in team_access: continue client_users.setdefault(token.client, []).append(token.user) # Now we have a list of clients to notify and a list of users to notify them with for client, users in client_users.items(): if user is not None and user in users: notify_user = user else: notify_user = users[0] # First user available send_notice.delay(client.notification_uri, data={ 'userid': notify_user.buid, # XXX: Deprecated parameter 'buid': notify_user.buid, 'type': 'org' if team is None else 'team', 'orgid': org.buid, 'teamid': team.buid if team is not None else None, 'changes': changes, })
def token_verify(): token = request.form.get('access_token') client_resource = request.form.get('resource') # Can only be a single resource if not client_resource: # No resource specified by caller return resource_error('no_resource') if not token: # No token specified by caller return resource_error('no_token') if not current_auth.client.namespace: # This client has not defined any resources return api_result('error', error='client_no_resources') authtoken = AuthToken.get(token=token) if not authtoken: # No such auth token return api_result('error', error='no_token') if (current_auth.client.namespace + ':' + client_resource not in authtoken.effective_scope) and ( current_auth.client.namespace + ':*' not in authtoken.effective_scope): # Token does not grant access to this resource return api_result('error', error='access_denied') if '/' in client_resource: parts = client_resource.split('/') if len(parts) != 2: return api_result('error', error='invalid_scope') resource_name, action_name = parts else: resource_name = client_resource action_name = None if resource_name != '*': resource = Resource.get(resource_name, client=current_auth.client) if not resource: # Resource does not exist or does not belong to this client return api_result('error', error='access_denied') if action_name and action_name != '*': action = ResourceAction.query.filter_by(name=action_name, resource=resource).first() if not action: return api_result('error', error='access_denied') # All validations passed. Token is valid for this client and scope. Return with information on the token # TODO: Don't return validity. Set the HTTP cache headers instead. params = {'validity': 120} # Period (in seconds) for which this assertion may be cached. if authtoken.user: params['userinfo'] = get_userinfo(authtoken.user, current_auth.client, scope=authtoken.effective_scope) params['clientinfo'] = { 'title': authtoken.client.title, 'userid': authtoken.client.owner.buid, 'buid': authtoken.client.owner.buid, 'uuid': authtoken.client.owner.uuid, 'owner_title': authtoken.client.owner.pickername, 'website': authtoken.client.website, 'key': authtoken.client.key, 'trusted': authtoken.client.trusted, } return api_result('ok', **params)
def oauth_make_token(user, client, scope): token = AuthToken.query.filter_by(user=user, client=client).first() if token: token.add_scope(scope) else: token = AuthToken(user=user, client=client, scope=scope, token_type='bearer') db.session.add(token) # TODO: Look up Resources for items in scope; look up their providing clients apps, # and notify each client app of this token return token
def token_verify(): token = request.form.get('access_token') client_resource = request.form.get( 'resource') # Can only be a single resource if not client_resource: # No resource specified by caller return resource_error('no_resource') if client_resource != '*': # Client resources are no longer supported; only the '*' resource is return resource_error('unknown_resource') if not token: # No token specified by caller return resource_error('no_token') if not current_auth.auth_client.namespace: # This client has not defined any resources return api_result('error', error='client_no_resources') authtoken = AuthToken.get(token=token) if not authtoken: # No such auth token return api_result('error', error='no_token') if (current_auth.auth_client.namespace + ':' + client_resource not in authtoken.effective_scope) and ( current_auth.auth_client.namespace + ':*' not in authtoken.effective_scope): # Token does not grant access to this resource return api_result('error', error='access_denied') # All validations passed. Token is valid for this client and scope. Return with information on the token # TODO: Don't return validity. Set the HTTP cache headers instead. params = { 'validity': 120 } # Period (in seconds) for which this assertion may be cached. if authtoken.user: params['userinfo'] = get_userinfo(authtoken.user, current_auth.auth_client, scope=authtoken.effective_scope) params['clientinfo'] = { 'title': authtoken.auth_client.title, 'userid': authtoken.auth_client.owner.buid, 'buid': authtoken.auth_client.owner.buid, 'uuid': authtoken.auth_client.owner.uuid, 'owner_title': authtoken.auth_client.owner.pickername, 'website': authtoken.auth_client.website, 'key': authtoken.auth_client.buid, 'trusted': authtoken.auth_client.trusted, } return api_result('ok', **params)
def token_get_scope(): token = request.form.get('access_token') if not token: # No token specified by caller return resource_error('no_token') if not current_auth.auth_client.namespace: # This client has not defined any resources return api_result('error', error='client_no_resources') authtoken = AuthToken.get(token=token) if not authtoken: # No such auth token return api_result('error', error='no_token') client_resources = [] nsprefix = current_auth.auth_client.namespace + ':' for item in authtoken.effective_scope: if item.startswith(nsprefix): client_resources.append(item[len(nsprefix):]) if not client_resources: return api_result('error', error='no_access') # All validations passed. Token is valid for this client. Return with information on the token # TODO: Don't return validity. Set the HTTP cache headers instead. params = { 'validity': 120 } # Period (in seconds) for which this assertion may be cached. if authtoken.user: params['userinfo'] = get_userinfo(authtoken.user, current_auth.auth_client, scope=authtoken.effective_scope) params['clientinfo'] = { 'title': authtoken.auth_client.title, 'userid': authtoken.auth_client.owner.buid, 'buid': authtoken.auth_client.owner.buid, 'uuid': authtoken.auth_client.owner.uuid, 'owner_title': authtoken.auth_client.owner.pickername, 'website': authtoken.auth_client.website, 'key': authtoken.auth_client.buid, 'trusted': authtoken.auth_client.trusted, 'scope': client_resources, } return api_result('ok', **params)
def token_get_scope(): token = request.form.get('access_token') if not token: # No token specified by caller return resource_error('no_token') if not current_auth.client.namespace: # This client has not defined any resources return api_result('error', error='client_no_resources') authtoken = AuthToken.get(token=token) if not authtoken: # No such auth token return api_result('error', error='no_token') client_resources = [] nsprefix = current_auth.client.namespace + ':' for item in authtoken.effective_scope: if item.startswith(nsprefix): client_resources.append(item[len(nsprefix):]) if not client_resources: return api_result('error', error='no_access') # All validations passed. Token is valid for this client. Return with information on the token # TODO: Don't return validity. Set the HTTP cache headers instead. params = {'validity': 120} # Period (in seconds) for which this assertion may be cached. if authtoken.user: params['userinfo'] = get_userinfo(authtoken.user, current_auth.client, scope=authtoken.effective_scope) params['clientinfo'] = { 'title': authtoken.client.title, 'userid': authtoken.client.owner.buid, 'buid': authtoken.client.owner.buid, 'uuid': authtoken.client.owner.uuid, 'owner_title': authtoken.client.owner.pickername, 'website': authtoken.client.website, 'key': authtoken.client.key, 'trusted': authtoken.client.trusted, 'scope': client_resources, } return api_result('ok', **params)
def token_verify(): token = request.form.get('access_token') client_resource = request.form.get( 'resource') # Can only be a single resource if not client_resource: # No resource specified by caller return resource_error('no_resource') if not token: # No token specified by caller return resource_error('no_token') if not current_auth.client.namespace: # This client has not defined any resources return api_result('error', error='client_no_resources') authtoken = AuthToken.get(token=token) if not authtoken: # No such auth token return api_result('error', error='no_token') if (current_auth.client.namespace + ':' + client_resource not in authtoken.effective_scope) and ( current_auth.client.namespace + ':*' not in authtoken.effective_scope): # Token does not grant access to this resource return api_result('error', error='access_denied') if '/' in client_resource: parts = client_resource.split('/') if len(parts) != 2: return api_result('error', error='invalid_scope') resource_name, action_name = parts else: resource_name = client_resource action_name = None if resource_name != '*': resource = Resource.get(resource_name, client=current_auth.client) if not resource: # Resource does not exist or does not belong to this client return api_result('error', error='access_denied') if action_name and action_name != '*': action = ResourceAction.query.filter_by(name=action_name, resource=resource).first() if not action: return api_result('error', error='access_denied') # All validations passed. Token is valid for this client and scope. Return with information on the token # TODO: Don't return validity. Set the HTTP cache headers instead. params = { 'validity': 120 } # Period (in seconds) for which this assertion may be cached. if authtoken.user: params['userinfo'] = get_userinfo(authtoken.user, current_auth.client, scope=authtoken.effective_scope) params['clientinfo'] = { 'title': authtoken.client.title, 'userid': authtoken.client.owner.buid, 'buid': authtoken.client.owner.buid, 'uuid': authtoken.client.owner.uuid, 'owner_title': authtoken.client.owner.pickername, 'website': authtoken.client.website, 'key': authtoken.client.key, 'trusted': authtoken.client.trusted, } return api_result('ok', **params)