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
=36)
71 project_id
= models
.CharField(_('project_id'), max_length
=36)
72 token_expires
= models
.FloatField(_('token_expires'), max_length
=36)
74 objects
= OsmUserManager()
76 USERNAME_FIELD
= 'username'
80 def is_authenticated(self
):
81 """Checks for a valid authentication."""
82 if self
.token
is not None and utils
.is_token_valid({'expires': self
.token_expires
}):
88 if self
.is_authenticated
:
89 return {'id': self
.token
, 'expires': self
.token_expires
, 'project_id': self
.project_id
}
92 def get_projects(self
):
94 result
= client
.get_user_info(self
.get_token(), self
.username
)
95 if 'error' in result
and result
['error'] is True:
98 return result
['data']['projects']
100 def switch_project(self
, project_id
):
102 result
= client
.switch_project({'project_id': project_id
, 'username': self
.username
, 'password': self
.psw
})
103 if 'error' in result
and result
['error'] is True:
104 raise OSMAuthException(result
['data'])
106 self
.token
= result
['data']['id']
107 self
.project_id
= result
['data']['project_id']
108 self
.token_expires
= result
['data']['expires']
114 verbose_name
= _('custom user')
115 verbose_name_plural
= _('custom users')
119 class OsmUser(AbstractOsmUser
):
121 Concrete class of AbstractCustomUser.
123 Use this if you don't need to extend CustomUser.
127 class Meta(AbstractOsmUser
.Meta
):
128 swappable
= 'AUTH_USER_MODEL'