Skip to content
Snippets Groups Projects
Commit 8473d4dc authored by Julian's avatar Julian
Browse files

Refactoring of OAuth2 models

parent 306c8502
No related branches found
No related tags found
No related merge requests found
from collections import OrderedDict
from sqlalchemy import MetaData, event
from sqlalchemy.types import TypeDecorator, Text
from sqlalchemy.ext.mutable import MutableList
from flask_sqlalchemy import SQLAlchemy
from flask.json import JSONEncoder
......@@ -40,3 +42,24 @@ class SQLAlchemyJSON(JSONEncoder):
result[key] = getattr(o, key)
return result
return JSONEncoder.default(self, o)
class CommaSeparatedList(TypeDecorator):
# For some reason TypeDecorator.process_literal_param and
# TypeEngine.python_type are abstract but not actually required
# pylint: disable=abstract-method
impl = Text
cache_ok = True
def process_bind_param(self, value, dialect):
if value is None:
return None
for item in value:
if ',' in item:
raise ValueError('Items of comma-separated list must not contain commas')
return ','.join(value)
def process_result_value(self, value, dialect):
if value is None:
return None
return MutableList(value.split(','))
......@@ -2,11 +2,11 @@ import datetime
from flask import current_app
from flask_babel import get_locale, gettext as _
from sqlalchemy import Column, Integer, String, DateTime, Text, ForeignKey
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.hybrid import hybrid_property
from uffd.database import db
from uffd.database import db, CommaSeparatedList
from uffd.tasks import cleanup_task
from uffd.session.models import DeviceLoginInitiation, DeviceLoginType
......@@ -64,18 +64,7 @@ class OAuth2Grant(db.Model):
code = Column(String(255), index=True, nullable=False)
redirect_uri = Column(String(255), nullable=False)
expires = Column(DateTime, nullable=False, default=lambda: datetime.datetime.utcnow() + datetime.timedelta(seconds=100))
_scopes = Column(Text, nullable=False, default='')
@property
def scopes(self):
if self._scopes:
return self._scopes.split()
return []
def delete(self):
db.session.delete(self)
db.session.commit()
return self
scopes = Column('_scopes', CommaSeparatedList(), nullable=False, default=tuple())
@hybrid_property
def expired(self):
......@@ -106,18 +95,7 @@ class OAuth2Token(db.Model):
access_token = Column(String(255), unique=True, nullable=False)
refresh_token = Column(String(255), unique=True, nullable=False)
expires = Column(DateTime, nullable=False)
_scopes = Column(Text, nullable=False, default='')
@property
def scopes(self):
if self._scopes:
return self._scopes.split()
return []
def delete(self):
db.session.delete(self)
db.session.commit()
return self
scopes = Column('_scopes', CommaSeparatedList(), nullable=False, default=tuple())
@hybrid_property
def expired(self):
......
......@@ -66,7 +66,7 @@ class UffdRequestValidator(oauthlib.oauth2.RequestValidator):
def save_authorization_code(self, client_id, code, oauthreq, *args, **kwargs):
grant = OAuth2Grant(user=oauthreq.user, client_id=client_id, code=code['code'],
redirect_uri=oauthreq.redirect_uri, _scopes=' '.join(oauthreq.scopes))
redirect_uri=oauthreq.redirect_uri, scopes=oauthreq.scopes)
db.session.add(grant)
db.session.commit()
# Oauthlib does not really provide a way to customize grant code generation.
......@@ -95,7 +95,6 @@ class UffdRequestValidator(oauthlib.oauth2.RequestValidator):
db.session.commit()
def save_bearer_token(self, token_data, oauthreq, *args, **kwargs):
OAuth2Token.query.filter_by(client_id=oauthreq.client.client_id, user=oauthreq.user).delete()
tok = OAuth2Token(
user=oauthreq.user,
client_id=oauthreq.client.client_id,
......@@ -103,7 +102,7 @@ class UffdRequestValidator(oauthlib.oauth2.RequestValidator):
access_token=token_data['access_token'],
refresh_token=token_data['refresh_token'],
expires_in_seconds=token_data['expires_in'],
_scopes=' '.join(oauthreq.scopes)
scopes=oauthreq.scopes
)
db.session.add(tok)
db.session.commit()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment