fargo/fargo/oauth2/models.py

125 lines
4.0 KiB
Python

# fargo - document box
# Copyright (C) 2016-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid
import datetime
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.db.models.query import QuerySet
from django.utils.timezone import now
from fargo.fargo.models import Document, UserDocument
def generate_uuid():
return uuid.uuid4().hex
def validate_https_url(data):
errors = []
data = data.strip()
if not data:
return
for url in data.split():
try:
URLValidator(schemes=['http', 'https'])(url)
except ValidationError as e:
errors.append(e)
if errors:
raise ValidationError(errors)
@python_2_unicode_compatible
class OAuth2Client(models.Model):
client_name = models.CharField(max_length=255)
redirect_uris = models.TextField(
verbose_name=_('redirect URIs'),
validators=[validate_https_url])
client_id = models.CharField(max_length=255, default=generate_uuid)
client_secret = models.CharField(max_length=255, default=generate_uuid)
def __repr__(self):
return 'OAuth2Client name: %s with id: %s' % (self.client_name, self.client_id)
def get_redirect_uris(self):
return self.redirect_uris.split()
def check_redirect_uri(self, redirect_uri):
return redirect_uri in self.redirect_uris.strip().split()
def __str__(self):
return self.client_name
class Meta:
ordering = ('client_name',)
verbose_name = _('OAUTH2 client')
verbose_name_plural = _('OAUTH2 clients')
class CleanupQuerySet(QuerySet):
def cleanup(self, n=None):
n = n or now()
threshold = n - datetime.timedelta(seconds=2 * self.model.get_lifetime())
self.filter(creation_date__lt=threshold).delete()
class OAuth2Authorize(models.Model):
client = models.ForeignKey(OAuth2Client)
user_document = models.ForeignKey(UserDocument)
access_token = models.CharField(max_length=255, default=generate_uuid)
code = models.CharField(max_length=255, default=generate_uuid)
creation_date = models.DateTimeField(auto_now_add=True)
objects = CleanupQuerySet.as_manager()
class Meta:
ordering = ('creation_date',)
verbose_name = _('OAUTH2 authorization')
verbose_name_plural = _('OAUTH2 authorizations')
@classmethod
def get_lifetime(cls):
return max(
settings.FARGO_CODE_LIFETIME,
settings.FARGO_ACCESS_TOKEN_LIFETIME)
def __repr__(self):
return 'OAuth2Authorize for document %r' % self.user_document
class OAuth2TempFile(models.Model):
uuid = models.CharField(max_length=32, default=generate_uuid, primary_key=True)
client = models.ForeignKey(OAuth2Client)
document = models.ForeignKey(Document, related_name='oauth2_tempfiles')
filename = models.CharField(max_length=512)
creation_date = models.DateTimeField(auto_now_add=True)
objects = CleanupQuerySet.as_manager()
@classmethod
def get_lifetime(cls):
return settings.FARGO_OAUTH2_TEMPFILE_LIFETIME
class Meta:
ordering = ('creation_date',)
verbose_name = _('OAUTH2 temporary file')
verbose_name_plural = _('OAUTH2 temporary files')