blob: 74c1f1eb396be5da893f6bbf240784da31816b95 [file] [log] [blame]
lombardofr099364f2018-06-12 11:21:02 +02001#
2# Copyright 2018 EveryUP Srl
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16from __future__ import unicode_literals
17from django.db import models
18from django.utils.translation import ugettext_lazy as _
19from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager, PermissionsMixin
20from django.utils import timezone
lombardofr99f922f2018-07-17 17:27:36 +020021
22from authosm.exceptions import OSMAuthException
23from lib.osm.osmclient.clientv2 import Client
24import utils
lombardofr099364f2018-06-12 11:21:02 +020025
26
27class OsmUserManager(BaseUserManager):
28 """Custom manager for OsmUser."""
29
30 def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
31 """Create and save a CustomUser with the given username and password. """
32 now = timezone.now()
33
34 if not username:
35 raise ValueError('The given username must be set')
36
37 is_active = extra_fields.pop("is_active", True)
38 user = self.model(username=username, is_staff=is_staff, is_active=is_active,
39 is_superuser=is_superuser, last_login=now,
40 date_joined=now, **extra_fields)
41 user.set_password(password)
42 user.save(using=self._db)
43 return user
44
45 """Create and save an OsmUser with the given username and password."""
46 def create_superuser(self, username, password, **extra_fields):
47 return self._create_user(username, password, True, True, is_admin=True,
48 **extra_fields)
49
50
51class AbstractOsmUser(AbstractBaseUser, PermissionsMixin):
52 """Abstract User with the same behaviour as Django's default User.
53
54
55 Inherits from both the AbstractBaseUser and PermissionMixin.
56
57 The following attributes are inherited from the superclasses:
58 * password
59 * last_login
60 * is_superuser
61
62 """
lombardofr99f922f2018-07-17 17:27:36 +020063 username = models.CharField(_('username'), primary_key=True, max_length=255, unique=True, db_index=True)
64
lombardofr099364f2018-06-12 11:21:02 +020065 is_admin = models.BooleanField(_('admin status'), default=False)
66 is_basic_user = models.BooleanField(_('basic_user status'), default=False)
lombardofr99f922f2018-07-17 17:27:36 +020067 current_project = models.CharField(_('project_id'), max_length=255)
68
69 psw = models.CharField(_('psw'), max_length=36)
Eduardo Sousa8efc9232019-06-07 09:35:07 +010070 token = models.CharField(_('token'), max_length=255)
lombardofr99f922f2018-07-17 17:27:36 +020071 project_id = models.CharField(_('project_id'), max_length=36)
lombardofre5a130a2019-07-15 09:17:59 +020072 project_name = models.CharField(_('project_name'), max_length=36, default='')
lombardofr99f922f2018-07-17 17:27:36 +020073 token_expires = models.FloatField(_('token_expires'), max_length=36)
lombardofr099364f2018-06-12 11:21:02 +020074
75 objects = OsmUserManager()
76
77 USERNAME_FIELD = 'username'
78 REQUIRED_FIELDS = []
79
lombardofr99f922f2018-07-17 17:27:36 +020080 @property
81 def is_authenticated(self):
82 """Checks for a valid authentication."""
83 if self.token is not None and utils.is_token_valid({'expires': self.token_expires}):
84 return True
85 else:
86 return False
87
88 def get_token(self):
89 if self.is_authenticated:
90 return {'id': self.token, 'expires': self.token_expires, 'project_id': self.project_id}
91 return None
92
lombardofr835a0b72018-07-18 15:26:16 +020093 def get_projects(self):
94 client = Client()
lombardofre5a130a2019-07-15 09:17:59 +020095 user_info = client.get_user_info(self.get_token(), self.username)
lombardofr5bc5ebb2019-08-19 09:33:56 +020096 if 'error' in user_info and user_info['error'] is True:
lombardofr835a0b72018-07-18 15:26:16 +020097 return []
98 else:
lombardofr5bc5ebb2019-08-19 09:33:56 +020099 return user_info['data']['project_role_mappings']
lombardofr835a0b72018-07-18 15:26:16 +0200100
lombardofr99f922f2018-07-17 17:27:36 +0200101 def switch_project(self, project_id):
102 client = Client()
103 result = client.switch_project({'project_id': project_id, 'username': self.username, 'password': self.psw})
104 if 'error' in result and result['error'] is True:
105 raise OSMAuthException(result['data'])
106 else:
107 self.token = result['data']['id']
108 self.project_id = result['data']['project_id']
lombardofre5a130a2019-07-15 09:17:59 +0200109 self.project_name = result['data']['project_name']
lombardofr99f922f2018-07-17 17:27:36 +0200110 self.token_expires = result['data']['expires']
111 self.save()
112 return True
113 return False
114
lombardofr099364f2018-06-12 11:21:02 +0200115 class Meta:
116 verbose_name = _('custom user')
117 verbose_name_plural = _('custom users')
118 abstract = True
119
120
lombardofr099364f2018-06-12 11:21:02 +0200121class OsmUser(AbstractOsmUser):
122 """
123 Concrete class of AbstractCustomUser.
124
125 Use this if you don't need to extend CustomUser.
126
127 """
128
129 class Meta(AbstractOsmUser.Meta):
130 swappable = 'AUTH_USER_MODEL'
131