From 88a9662be4f97da5b04a3842c8d0caa2652be355 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 21 Sep 2012 13:02:35 +0200 Subject: Added client registration caps to OAuth plugin THE MIGRATIONS SUPPLIED WITH THIS COMMIT WILL DROP AND RE-CREATE YOUR oauth__tokens AND oauth__codes TABLES. ALL YOUR OAUTH CODES AND TOKENS WILL BE LOST. - Fixed pylint issues in db/sql/migrations. - Added __repr__ to the User model. - Added _disable_cors option to json_response. - Added crude error handling to the api.tools.api_auth decorator - Updated the OAuth README. - Added client registration, client overview, connection overview, client authorization views and templates. - Added error handling to the OAuthAuth Auth object. - Added AuthorizationForm, ClientRegistrationForm in oauth/forms. - Added migrations for OAuth, added client registration migration. - Added OAuthClient, OAuthUserClient models. - Added oauth/tools with require_client_auth decorator method. --- mediagoblin/plugins/oauth/models.py | 99 ++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) (limited to 'mediagoblin/plugins/oauth/models.py') diff --git a/mediagoblin/plugins/oauth/models.py b/mediagoblin/plugins/oauth/models.py index 295987c8..91bd0fc6 100644 --- a/mediagoblin/plugins/oauth/models.py +++ b/mediagoblin/plugins/oauth/models.py @@ -14,15 +14,84 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import uuid +import bcrypt + from datetime import datetime, timedelta from mediagoblin.db.sql.base import Base from mediagoblin.db.sql.models import User from sqlalchemy import ( - Column, Unicode, Integer, DateTime, ForeignKey) + Column, Unicode, Integer, DateTime, ForeignKey, Enum) from sqlalchemy.orm import relationship +# Don't remove this, I *think* it applies sqlalchemy-migrate functionality onto +# the models. +from migrate import changeset + + +class OAuthClient(Base): + __tablename__ = 'oauth__client' + + id = Column(Integer, primary_key=True) + created = Column(DateTime, nullable=False, + default=datetime.now) + + name = Column(Unicode) + description = Column(Unicode) + + identifier = Column(Unicode, unique=True, index=True) + secret = Column(Unicode, index=True) + + owner_id = Column(Integer, ForeignKey(User.id)) + owner = relationship(User, backref='registered_clients') + + redirect_uri = Column(Unicode) + + type = Column(Enum( + u'confidential', + u'public')) + + def generate_identifier(self): + self.identifier = unicode(uuid.uuid4()) + + def generate_secret(self): + self.secret = unicode( + bcrypt.hashpw( + unicode(uuid.uuid4()), + bcrypt.gensalt())) + + def __repr__(self): + return '<{0} {1}:{2} ({3})>'.format( + self.__class__.__name__, + self.id, + self.name.encode('ascii', 'replace'), + self.owner.username.encode('ascii', 'replace')) + + +class OAuthUserClient(Base): + __tablename__ = 'oauth__user_client' + id = Column(Integer, primary_key=True) + + user_id = Column(Integer, ForeignKey(User.id)) + user = relationship(User, backref='oauth_clients') + + client_id = Column(Integer, ForeignKey(OAuthClient.id)) + client = relationship(OAuthClient, backref='users') + + state = Column(Enum( + u'approved', + u'rejected')) + + def __repr__(self): + return '<{0} #{1} {2} [{3}, {4}]>'.format( + self.__class__.__name__, + self.id, + self.state.encode('ascii', 'replace'), + self.user, + self.client) + class OAuthToken(Base): __tablename__ = 'oauth__tokens' @@ -39,6 +108,17 @@ class OAuthToken(Base): index=True) user = relationship(User) + client_id = Column(Integer, ForeignKey(OAuthClient.id), nullable=False) + client = relationship(OAuthClient) + + def __repr__(self): + return '<{0} #{1} expires {2} [{3}, {4}]>'.format( + self.__class__.__name__, + self.id, + self.expires.isoformat(), + self.user, + self.client) + class OAuthCode(Base): __tablename__ = 'oauth__codes' @@ -54,5 +134,20 @@ class OAuthCode(Base): index=True) user = relationship(User) + client_id = Column(Integer, ForeignKey(OAuthClient.id), nullable=False) + client = relationship(OAuthClient) + + def __repr__(self): + return '<{0} #{1} expires {2} [{3}, {4}]>'.format( + self.__class__.__name__, + self.id, + self.expires.isoformat(), + self.user, + self.client) + -MODELS = [OAuthToken, OAuthCode] +MODELS = [ + OAuthToken, + OAuthCode, + OAuthClient, + OAuthUserClient] -- cgit v1.2.3