From 6d293a08bcb1651377c5cdebebcc54ac5f83ccab Mon Sep 17 00:00:00 2001 From: Dave Pifke Date: Wed, 14 Mar 2012 23:13:27 +0000 Subject: [PATCH] Add API methods for managing apps. --- r2/r2/controllers/api.py | 51 ++++++++++++++++++++++++ r2/r2/controllers/oauth2.py | 21 ++-------- r2/r2/controllers/validator/validator.py | 30 ++++++++++++++ 3 files changed, 84 insertions(+), 18 deletions(-) diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index f75142157..de6e04ea7 100755 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -2810,3 +2810,54 @@ class ApiController(RedditController): }) return sr_results + + @noresponse(VUser(), + VModhash(), + client=VOAuth2ClientID()) + def POST_revokeapp(self, form, jquery, client): + if client: + client.revoke(c.user) + + @validatedForm(VUser(), + VModhash(), + client=VOAuth2ClientDeveloper(), + name=VRequired('name', errors.NO_TEXT), + about_url=VSanitizedUrl(), + icon_url=VSanitizedUrl(), + redirect_uri=VUrl('redirect_uri', allow_self=False)) + def POST_updateapp(self, form, jquery, client, name, description, about_url, icon_url, redirect_uri): + if not form.has_error(): + clinet.name = name + client.description = description + client.about_url = about_url + client.icon_url = icon_url + client.redirect_uri = redirect_uri + client._commit() + form.set_html('.status', _('application updated')) + + @validatedForm(VUser(), + VModhash(), + client=VOAuth2ClientDeveloper(), + account=VExistingUnameNotSelf('name')) + def POST_adddeveloper(self, form, jquery, client, account): + if not form.has_error(): + client.add_developer(account) + form.set_html('.status', _('developer added')) + + @validatedForm(VUser(), + VModhash(), + client=VOAuth2ClientDeveloper(), + account=VExistingUnameNotSelf('name')) + def POST_removedeveloper(self, form, jquery, client, account): + if not form.has_error(): + client.remove_developer(account) + form.set_html('.status', _('developer removed')) + + @noresponse(VUser(), + VModhash(), + client=VOAuth2ClientDeveloper()) + def POST_deleteapp(self, client): + if not client: + abort(403) + client.deleted = True + client._commit() diff --git a/r2/r2/controllers/oauth2.py b/r2/r2/controllers/oauth2.py index dd3be731c..fdb25e940 100644 --- a/r2/r2/controllers/oauth2.py +++ b/r2/r2/controllers/oauth2.py @@ -33,7 +33,7 @@ from r2.lib.db.thing import NotFound from r2.models import Account from r2.models.token import OAuth2Client, OAuth2AuthorizationCode, OAuth2AccessToken from r2.controllers.errors import ForbiddenError, errors -from validator import validate, VRequired, VOneOf, VUser, VModhash +from validator import validate, VRequired, VOneOf, VUser, VModhash, VOAuth2ClientID from r2.lib.pages import OAuth2AuthorizationPage from r2.lib.require import RequirementException, require, require_split @@ -45,21 +45,6 @@ scope_info = { } } -class VClientID(VRequired): - default_param = "client_id" - def __init__(self, param=None, *a, **kw): - VRequired.__init__(self, param, errors.OAUTH2_INVALID_CLIENT, *a, **kw) - - def run(self, client_id): - if not client_id: - return self.error() - - client = OAuth2Client.get_token(client_id) - if client: - return client - else: - return self.error() - class OAuth2FrontendController(RedditController): def pre(self): RedditController.pre(self) @@ -91,7 +76,7 @@ class OAuth2FrontendController(RedditController): @validate(VUser(), response_type = VOneOf("response_type", ("code",)), - client = VClientID(), + client = VOAuth2ClientID(), redirect_uri = VRequired("redirect_uri", errors.OAUTH2_INVALID_REDIRECT_URI), scope = VOneOf("scope", scope_info.keys()), state = VRequired("state", errors.NO_TEXT)) @@ -127,7 +112,7 @@ class OAuth2FrontendController(RedditController): @validate(VUser(), VModhash(fatal=False), - client = VClientID(), + client = VOAuth2ClientID(), redirect_uri = VRequired("redirect_uri", errors.OAUTH2_INVALID_REDIRECT_URI), scope = VOneOf("scope", scope_info.keys()), state = VRequired("state", errors.NO_TEXT), diff --git a/r2/r2/controllers/validator/validator.py b/r2/r2/controllers/validator/validator.py index f92fc4ccd..7bc2a24b1 100644 --- a/r2/r2/controllers/validator/validator.py +++ b/r2/r2/controllers/validator/validator.py @@ -1071,6 +1071,13 @@ class VExistingUname(VRequired): self.param: _('the name of an existing user') } +class VExistingUnameNotSelf(VExistingUname): + def run(self, name): + user = super(VExistingUnameNotSelf, self).run(name) + if not user or user == c.user: + self.error() + return user + class VMessageRecipient(VExistingUname): def run(self, name): if not name: @@ -1820,3 +1827,26 @@ class VOneTimePassword(Validator): # if we got this far, their password was wrong, invalid or already used self.set_error(errors.WRONG_PASSWORD) + +class VOAuth2ClientID(VRequired): + default_param = "client_id" + def __init__(self, param=None, developer=False, *a, **kw): + self.developer = developer + VRequired.__init__(self, param, errors.OAUTH2_INVALID_CLIENT, *a, **kw) + + def run(self, client_id): + if not client_id: + return self.error() + + client = OAuth2Client.get_token(client_id) + if client and not client.deleted: + return client + else: + return self.error() + +class VOAuth2ClientDeveloper(VOAuth2ClientID): + def run(self, client_id): + client = super(VOAuth2ClientDeveloper) + if not client or not client.has_developer(c.user): + return self.error() + return client