示例#1
0
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
示例#2
0
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
示例#3
0
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,
            })
示例#4
0
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,
            })
示例#5
0
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)
示例#6
0
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
示例#7
0
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)
示例#8
0
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)
示例#9
0
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)
示例#10
0
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)