def oauth_make_auth_code(client, scope, redirect_uri): """ Make an auth code for a given client. Caller must commit the database session for this to work. """ authcode = AuthCode(user=g.user, session=g.usersession, client=client, scope=scope, redirect_uri=redirect_uri) authcode.code = newsecret() db.session.add(authcode) return authcode.code
def oauth_make_auth_code(client, scope, redirect_uri): """ Make an auth code for a given client. Caller must commit the database session for this to work. """ authcode = AuthCode(user=g.user, client=client, scope=scope, redirect_uri=redirect_uri) authcode.code = newsecret() db.session.add(authcode) return authcode.code
def oauth_make_auth_code(auth_client, scope, redirect_uri): """ Make an auth code for a given client. Caller must commit the database session for this to work. """ authcode = AuthCode( user=current_auth.user, user_session=current_auth.session, auth_client=auth_client, scope=scope, redirect_uri=redirect_uri[:1024], ) authcode.code = newsecret() db.session.add(authcode) return authcode.code
def oauth_token(): """ OAuth2 server -- token endpoint (confidential clients only) """ # Always required parameters grant_type = request.form.get('grant_type') auth_client = current_auth.auth_client # Provided by @requires_client_login scope = request.form.get('scope', '').split(' ') # if grant_type == 'authorization_code' (POST) code = request.form.get('code') redirect_uri = request.form.get('redirect_uri') # if grant_type == 'password' (POST) username = request.form.get('username') password = request.form.get('password') # if grant_type == 'client_credentials' buid = request.form.get('buid') or request.form.get( 'userid') # XXX: Deprecated userid parameter # Validations 1: Required parameters if not grant_type: return oauth_token_error('invalid_request', _("Missing grant_type")) # grant_type == 'refresh_token' is not supported. All tokens are permanent unless revoked if grant_type not in [ 'authorization_code', 'client_credentials', 'password' ]: return oauth_token_error('unsupported_grant_type') # Validations 2: client scope if grant_type == 'client_credentials': # AuthClient data; user isn't part of it OR trusted client and automatic scope try: # Confirm the client has access to the scope it wants verifyscope(scope, auth_client) except ScopeException as scopeex: return oauth_token_error('invalid_scope', str(scopeex)) if buid: if auth_client.trusted: user = User.get(buid=buid) if user: # This client is trusted and can receive a user access token. # However, don't grant it the scope it wants as the user's # permission was not obtained. Instead, the client's # pre-approved scope will be used for the token's effective scope. token = oauth_make_token(user=user, auth_client=auth_client, scope=[]) return oauth_token_success( token, userinfo=get_userinfo( user=token.user, auth_client=auth_client, scope=token.effective_scope, ), ) else: return oauth_token_error('invalid_grant', _("Unknown user")) else: return oauth_token_error('invalid_grant', _("Untrusted client app")) else: token = oauth_make_token(user=None, auth_client=auth_client, scope=scope) return oauth_token_success(token) # Validations 3: auth code elif grant_type == 'authorization_code': authcode = AuthCode.get_for_client(auth_client=auth_client, code=code) if not authcode: return oauth_token_error('invalid_grant', _("Unknown auth code")) if not authcode.is_valid(): db.session.delete(authcode) db.session.commit() return oauth_token_error('invalid_grant', _("Expired auth code")) # Validations 3.1: scope in authcode if not scope or scope[0] == '': return oauth_token_error('invalid_scope', _("Scope is blank")) if not set(scope).issubset(set(authcode.scope)): return oauth_token_error('invalid_scope', _("Scope expanded")) else: # Scope not provided. Use whatever the authcode allows scope = authcode.scope if redirect_uri != authcode.redirect_uri: return oauth_token_error('invalid_client', _("redirect_uri does not match")) token = oauth_make_token(user=authcode.user, auth_client=auth_client, scope=scope) db.session.delete(authcode) return oauth_token_success( token, userinfo=get_userinfo( user=authcode.user, auth_client=auth_client, scope=token.effective_scope, user_session=authcode.user_session, ), ) elif grant_type == 'password': # Validations 4.1: password grant_type is only for trusted clients if not auth_client.trusted: # Refuse to untrusted clients return oauth_token_error( 'unauthorized_client', _("AuthClient is not trusted for password grant_type"), ) # Validations 4.2: Are username and password provided and correct? if not username or not password: return oauth_token_error('invalid_request', _("Username or password not provided")) user = getuser(username) if not user: return oauth_token_error( 'invalid_client', _("No such user")) # XXX: invalid_client doesn't seem right if not user.password_is(password): return oauth_token_error('invalid_client', _("Password mismatch")) # Validations 4.3: verify scope try: verifyscope(scope, auth_client) except ScopeException as scopeex: return oauth_token_error('invalid_scope', str(scopeex)) # All good. Grant access token = oauth_make_token(user=user, auth_client=auth_client, scope=scope) return oauth_token_success( token, userinfo=get_userinfo(user=user, auth_client=auth_client, scope=scope), )