mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
OAuth2: Add extension grant for app-only auth
Grant URI: https://oauth.reddit.com/grants/installed_client This minor extension grant allows non-confidential OAuth2 clients to request user-less OAuth2 tokens. Consumers should provide a unique ID, and re-use that ID for subsequent token requests from the same device. ID generation is left up to the client. This is separate from client_credentials so that the client_credentials grant can conform to the official spec.
This commit is contained in:
committed by
Neil Williams
parent
9c50a08c65
commit
63dd2f0c94
@@ -51,6 +51,7 @@ from r2.lib.validator import (
|
||||
VOAuth2Scope,
|
||||
VOAuth2RefreshToken,
|
||||
VRatelimit,
|
||||
VLength,
|
||||
)
|
||||
|
||||
|
||||
@@ -187,6 +188,7 @@ class OAuth2AccessController(MinimalController):
|
||||
"refresh_token",
|
||||
"password",
|
||||
"client_credentials",
|
||||
"https://oauth.reddit.com/grants/installed_client",
|
||||
)
|
||||
),
|
||||
)
|
||||
@@ -212,7 +214,9 @@ class OAuth2AccessController(MinimalController):
|
||||
* ``authorization_code`` for the initial access token ("standard" OAuth2 flow)
|
||||
* ``refresh_token`` for renewing the access token.
|
||||
* ``password`` for script-type apps using password auth
|
||||
* ``client_credentials`` for application-only (logged out) access
|
||||
* ``client_credentials`` for application-only (logged out) access - confidential clients
|
||||
* ``https://oauth.reddit.com/grants/installed_client`` extension grant for application-only (logged out)
|
||||
access - non-confidential (installed) clients
|
||||
|
||||
**redirect_uri** must exactly match the value that was used in the call
|
||||
to [/api/v1/authorize](#api_method_authorize) that created this grant.
|
||||
@@ -229,6 +233,8 @@ class OAuth2AccessController(MinimalController):
|
||||
return self._access_token_password()
|
||||
elif grant_type == "client_credentials":
|
||||
return self._access_token_client_credentials()
|
||||
elif grant_type == "https://oauth.reddit.com/grants/installed_client":
|
||||
return self._access_token_extension_client_credentials()
|
||||
else:
|
||||
resp = {"error": "unsupported_grant_type"}
|
||||
return self.api_wrapper(resp)
|
||||
@@ -356,6 +362,29 @@ class OAuth2AccessController(MinimalController):
|
||||
resp = self._make_token_dict(access_token)
|
||||
return self.api_wrapper(resp)
|
||||
|
||||
@validate(
|
||||
scope=nop("scope"),
|
||||
device_id=VLength("device_id", 30),
|
||||
)
|
||||
def _access_token_extension_client_credentials(self, scope, 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)
|
||||
|
||||
@validate(
|
||||
VRatelimit(rate_user=False, rate_ip=True, prefix="rate_revoke_token_"),
|
||||
token_id=nop("token"),
|
||||
|
||||
@@ -571,12 +571,14 @@ class OAuth2AccessToken(Token):
|
||||
_connection_pool = "main"
|
||||
|
||||
@classmethod
|
||||
def _new(cls, client_id, user_id, scope, refresh_token=None):
|
||||
def _new(cls, client_id, user_id, scope, refresh_token=None, device_id=None):
|
||||
return super(OAuth2AccessToken, cls)._new(
|
||||
client_id=client_id,
|
||||
user_id=user_id,
|
||||
scope=str(scope),
|
||||
refresh_token=refresh_token)
|
||||
refresh_token=refresh_token,
|
||||
device_id=device_id,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _by_user_view(cls):
|
||||
|
||||
Reference in New Issue
Block a user