2 # Copyright 2018 EveryUP Srl
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 from __future__
import unicode_literals
17 from django
.db
import models
18 from django
.utils
.translation
import ugettext_lazy
as _
19 from django
.contrib
.auth
.models
import User
, AbstractBaseUser
, BaseUserManager
, PermissionsMixin
20 from django
.utils
import timezone
22 from authosm
.exceptions
import OSMAuthException
23 from lib
.osm
.osmclient
.clientv2
import Client
27 class OsmUserManager(BaseUserManager
):
28 """Custom manager for OsmUser."""
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. """
35 raise ValueError('The given username must be set')
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
)
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,
51 class AbstractOsmUser(AbstractBaseUser
, PermissionsMixin
):
52 """Abstract User with the same behaviour as Django's default User.
55 Inherits from both the AbstractBaseUser and PermissionMixin.
57 The following attributes are inherited from the superclasses:
63 username
= models
.CharField(_('username'), primary_key
=True, max_length
=255, unique
=True, db_index
=True)
65 is_admin
= models
.BooleanField(_('admin status'), default
=False)
66 is_basic_user
= models
.BooleanField(_('basic_user status'), default
=False)
67 current_project
= models
.CharField(_('project_id'), max_length
=255)
69 psw
= models
.CharField(_('psw'), max_length
=36)
70 token
= models
.CharField(_('token'), max_length
=512)
71 project_id
= models
.CharField(_('project_id'), max_length
=36)
72 project_name
= models
.CharField(_('project_name'), max_length
=36, default
='')
73 token_expires
= models
.FloatField(_('token_expires'), max_length
=36)
75 objects
= OsmUserManager()
77 USERNAME_FIELD
= 'username'
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
}):
89 if self
.is_authenticated
:
90 return {'id': self
.token
, 'expires': self
.token_expires
, 'project_id': self
.project_id
}
93 def get_projects(self
):
95 user_info
= client
.get_user_info(self
.get_token(), self
.username
)
96 if 'error' in user_info
and user_info
['error'] is True:
99 return user_info
['data']['project_role_mappings']
101 def switch_project(self
, project_id
):
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'])
107 self
.token
= result
['data']['id']
108 self
.project_id
= result
['data']['project_id']
109 self
.project_name
= result
['data']['project_name']
110 self
.token_expires
= result
['data']['expires']
116 verbose_name
= _('custom user')
117 verbose_name_plural
= _('custom users')
121 class OsmUser(AbstractOsmUser
):
123 Concrete class of AbstractCustomUser.
125 Use this if you don't need to extend CustomUser.
129 class Meta(AbstractOsmUser
.Meta
):
130 swappable
= 'AUTH_USER_MODEL'