several changes on auth flow

Change-Id: I49ddbb074a9bc018b9e5becafbe5956fa5860333
Signed-off-by: lombardofr <lombardo@everyup.it>
diff --git a/authosm/backend.py b/authosm/backend.py
index 4bf9e72..6c23e91 100644
--- a/authosm/backend.py
+++ b/authosm/backend.py
@@ -13,8 +13,11 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 #
+from django.core.exceptions import PermissionDenied
+
 from .models import OsmUser
 from lib.osm.osmclient.clientv2 import Client
+from .exceptions import OSMAuthException
 
 class OsmBackend(object):
 
@@ -26,27 +29,31 @@
         if all(k in kwargs for k in ('username', 'password', 'project_id')):
             username = kwargs['username']
             password = kwargs['password']
-            project_id = kwargs['project_id']
 
             client = Client()
             result = client.auth(kwargs)
-            print "######"
-            print result
 
-            if 'error' in result and result['error'] == True:
-                return None
+            if 'error' in result and result['error'] is True:
+                raise OSMAuthException(result['data'])
             else:
 
                 try:
                     user = OsmUser.objects.get(username=username)
+                    user.psw = password
+                    user.token=result['data']['id']
+                    user.project_id=result['data']['project_id']
+                    user.token_expires=result['data']['expires']
+                    user.session = result['data']
+                    user.save()
 
                 except OsmUser.DoesNotExist:
-                    # Create a new user. There's no need to set a password
-                    # we will keep just some preferences
-                    user = OsmUser(username=username)
-
+                    user = OsmUser(username=username, psw=password, token=result['data']['id'],
+                                                       project_id=result['data']['project_id'],
+                                                       token_expires=result['data']['expires'])
+                    user.session = result['data']
                     user.save()
-                user.session = result['data']
+
+
                 return user
 
         return None
diff --git a/authosm/exceptions.py b/authosm/exceptions.py
new file mode 100644
index 0000000..c0b061d
--- /dev/null
+++ b/authosm/exceptions.py
@@ -0,0 +1,19 @@
+#
+#   Copyright 2018 EveryUP Srl
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+class OSMAuthException(Exception):
+    pass
diff --git a/authosm/models.py b/authosm/models.py
index c48f738..36a7b1b 100644
--- a/authosm/models.py
+++ b/authosm/models.py
@@ -18,8 +18,10 @@
 from django.utils.translation import ugettext_lazy as _
 from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager, PermissionsMixin
 from django.utils import timezone
-from lib.osm.osmclient.client import Client
-import uuid
+
+from authosm.exceptions import OSMAuthException
+from lib.osm.osmclient.clientv2 import Client
+import utils
 
 
 class OsmUserManager(BaseUserManager):
@@ -58,24 +60,54 @@
         * is_superuser
 
     """
-    username = models.CharField(_('username'), max_length=255, unique=True, db_index=True)
-    current_project = models.CharField(_('project_id'), max_length=255)
-    token_project = models.CharField(_('token'), max_length=36)
+    username = models.CharField(_('username'), primary_key=True, max_length=255, unique=True, db_index=True)
+
     is_admin = models.BooleanField(_('admin status'), default=False)
     is_basic_user = models.BooleanField(_('basic_user status'), default=False)
+    current_project = models.CharField(_('project_id'), max_length=255)
+
+    psw = models.CharField(_('psw'), max_length=36)
+    token = models.CharField(_('token'), max_length=36)
+    project_id = models.CharField(_('project_id'), max_length=36)
+    token_expires = models.FloatField(_('token_expires'), max_length=36)
 
     objects = OsmUserManager()
 
     USERNAME_FIELD = 'username'
     REQUIRED_FIELDS = []
 
+    @property
+    def is_authenticated(self):
+        """Checks for a valid authentication."""
+        if self.token is not None and utils.is_token_valid({'expires': self.token_expires}):
+            return True
+        else:
+            return False
+
+    def get_token(self):
+        if self.is_authenticated:
+            return {'id': self.token, 'expires': self.token_expires, 'project_id': self.project_id}
+        return None
+
+    def switch_project(self, project_id):
+        client = Client()
+        result = client.switch_project({'project_id': project_id, 'username': self.username, 'password': self.psw})
+        if 'error' in result and result['error'] is True:
+            raise OSMAuthException(result['data'])
+        else:
+            self.token = result['data']['id']
+            self.project_id = result['data']['project_id']
+            self.token_expires = result['data']['expires']
+            self.save()
+            return True
+        return False
+
     class Meta:
         verbose_name = _('custom user')
         verbose_name_plural = _('custom users')
         abstract = True
 
 
-
 class OsmUser(AbstractOsmUser):
     """
         Concrete class of AbstractCustomUser.
@@ -87,6 +119,3 @@
     class Meta(AbstractOsmUser.Meta):
         swappable = 'AUTH_USER_MODEL'
 
-    def get_projects(self):
-        client = Client()
-        return []
diff --git a/authosm/utils.py b/authosm/utils.py
new file mode 100644
index 0000000..c1a5d50
--- /dev/null
+++ b/authosm/utils.py
@@ -0,0 +1,33 @@
+#
+#   Copyright 2018 EveryUP Srl
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import time
+import authosm.models
+
+
+def get_user(request):
+    user = authosm.models.OsmUser.objects.get(username=request.session['_auth_user_id'])
+    return user
+
+
+def is_token_valid(token):
+
+    expiration = token['expires'] if 'expires' in token \
+                                     and isinstance(token['expires'], (int, long, float, complex)) else None
+    if expiration is None:
+        return False
+
+    return expiration > time.time()
diff --git a/authosm/views.py b/authosm/views.py
index 5ce8765..65b1ed6 100644
--- a/authosm/views.py
+++ b/authosm/views.py
@@ -30,14 +30,20 @@
         print request.POST.get('password')
         next_page = request.POST.get('next')
         next_page = urllib.unquote(next_page).decode('iso-8859-2')
-        user = authenticate(username=request.POST.get('username'),
-                            password=request.POST.get('password'),
-                            project_id=request.POST.get('project_id'))
+        try:
+            user = authenticate(username=request.POST.get('username'),
+                                password=request.POST.get('password'),
+                                project_id=request.POST.get('project_id'))
+        except Exception as e:
+            print e
+            res = HttpResponseRedirect('/auth')
+            res.set_cookie('logout_reason', '', max_age=10)
+            return res
+
         if user and user.is_active:
-            if user.is_authenticated():
+            if user.is_authenticated:
                 login(request, user)
                 request.session['token'] = user.session
-                print request.session['token']
                 if next_page == "" or next_page is None:
                     return HttpResponseRedirect('/home')
                 else: