def _access_token_extension_client_credentials(self, scope, device_id): if ((errors.NO_TEXT, "device_id") in c.errors or (errors.TOO_SHORT, "device_id") in c.errors or (errors.TOO_LONG, "device_id") in c.errors): return self.api_wrapper({ "error": "invalid_request", "error_description": "bad device_id", }) client = c.oauth2_client if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) access_token = OAuth2AccessToken._new( client._id, "", scope, device_id=device_id, ) resp = self._make_token_dict(access_token) return self.api_wrapper(resp)
def _access_token_extension_client_credentials(self, scope, device_id): if ((errors.NO_TEXT, "device_id") in c.errors or (errors.TOO_SHORT, "device_id") in c.errors or (errors.TOO_LONG, "device_id") in c.errors): g.stats.simple_event('oauth2.errors.BAD_DEVICE_ID') return self.api_wrapper({ "error": "invalid_request", "error_description": "bad device_id", }) client = c.oauth2_client if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): g.stats.simple_event( 'oauth2.errors.EXTENSION_CLIENT_CREDENTIALS_INVALID_SCOPE') c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) access_token = OAuth2AccessToken._new( client_id=client._id, user_id="", scope=scope, device_id=device_id, ) g.stats.simple_event( 'oauth2.access_token_extension_client_credentials.' 'access_token_create') resp = self._make_new_token_response(access_token) return self.api_wrapper(resp)
def _access_token_password(self, user, scope): # username:password auth via OAuth is only allowed for # private use scripts client = c.oauth2_client if client.app_type != "script": return self.api_wrapper({ "error": "unauthorized_client", "error_description": "Only script apps may use password auth" }) dev_ids = client._developer_ids if not user or user._id not in dev_ids: return self.api_wrapper({"error": "invalid_grant"}) if c.errors: return self.api_wrapper(self._check_for_errors()) if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) access_token = OAuth2AccessToken._new(client._id, user._id36, scope) resp = self._make_token_dict(access_token) return self.api_wrapper(resp)
def _access_token_client_credentials(self, scope): client = c.oauth2_client if not client.is_confidential(): g.stats.simple_event( 'oauth2.errors.CLIENT_CREDENTIALS_UNAUTHORIZED_CLIENT') return self.api_wrapper({"error": "unauthorized_client", "error_description": "Only confidential clients may use client_credentials auth"}) if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): g.stats.simple_event( 'oauth2.errors.CLIENT_CREDENTIALS_INVALID_SCOPE') c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) device_id = get_device_id(client) access_token = OAuth2AccessToken._new( client_id=client._id, user_id="", scope=scope, device_id=device_id, ) g.stats.simple_event( 'oauth2.access_token_client_credentials.access_token_create') resp = self._make_new_token_response(access_token) return self.api_wrapper(resp)
def _access_token_password(self, user, scope): # username:password auth via OAuth is only allowed for # private use scripts client = c.oauth2_client if client.app_type != "script": g.stats.simple_event('oauth2.errors.PASSWORD_UNAUTHORIZED_CLIENT') return self.api_wrapper({"error": "unauthorized_client", "error_description": "Only script apps may use password auth"}) dev_ids = client._developer_ids if not user or user._id not in dev_ids: g.stats.simple_event('oauth2.errors.INVALID_GRANT') return self.api_wrapper({"error": "invalid_grant"}) if c.errors: return self.api_wrapper(self._check_for_errors()) if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): g.stats.simple_event('oauth2.errors.PASSWORD_INVALID_SCOPE') c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) device_id = get_device_id(client) access_token = OAuth2AccessToken._new( client_id=client._id, user_id=user._id36, scope=scope, device_id=device_id, ) g.stats.simple_event( 'oauth2.access_token_password.access_token_create') resp = self._make_new_token_response(access_token) return self.api_wrapper(resp)
def GET_refresh_token(self, *args, **kwargs): # pylint: disable=unused-argument """Generate a refresh token given a username""" username = request.GET['username'] try: account = Account._by_name(username) except NotFound: account = register(username, uuid4().hex, '127.0.0.1') # subscribe the user now because reddit does not have consistency across # its APIs on what it considers the user to be subscribed to if not account.has_subscribed: Subreddit.subscribe_defaults(account) account.has_subscribed = True account._commit() client_id = g.secrets['generate_refresh_token_client_id'] client = OAuth2Client.get_token(client_id) scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) user_id = account._id36 refresh_token = OAuth2RefreshToken._new( client_id=client._id, user_id=user_id, scope=scope, ) access_token = OAuth2AccessToken._new( client_id=client._id, user_id=user_id, scope=scope, device_id='device', ) return json.dumps(OAuth2AccessController._make_new_token_response(access_token, refresh_token))
def pre(self): set_extension(request.environ, "json") MinimalController.pre(self) require_https() try: access_token = OAuth2AccessToken.get_token( self._get_bearer_token()) require(access_token) require(access_token.check_valid()) c.oauth2_access_token = access_token account = Account._byID36(access_token.user_id, data=True) require(account) require(not account._deleted) c.oauth_user = account except RequirementException: self._auth_error(401, "invalid_token") handler = self._get_action_handler() if handler: oauth2_perms = getattr(handler, "oauth2_perms", None) if oauth2_perms: grant = OAuth2Scope(access_token.scope) if grant.subreddit_only and c.site.name not in grant.subreddits: self._auth_error(403, "insufficient_scope") required_scopes = set(oauth2_perms['allowed_scopes']) if not (grant.scopes >= required_scopes): self._auth_error(403, "insufficient_scope") else: self._auth_error(400, "invalid_request")
def _access_token_client_credentials(self, scope): client = c.oauth2_client if not client.is_confidential(): return self.api_wrapper({"error": "unauthorized_client", "error_description": "Only confidential clients may use client_credentials auth"}) if scope: scope = OAuth2Scope(scope) if not scope.is_valid(): c.errors.add(errors.INVALID_OPTION, "scope") return self.api_wrapper({"error": "invalid_scope"}) else: scope = OAuth2Scope(OAuth2Scope.FULL_ACCESS) access_token = OAuth2AccessToken._new( client._id, "", scope, ) resp = self._make_token_dict(access_token) return self.api_wrapper(resp)