first commit

Change-Id: I8a65ee5527dd16d81e87c8ac5d4bdb471e5e759d
Signed-off-by: lombardof <flombardo@cnit.it>
diff --git a/sf_user/__init__.py b/sf_user/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sf_user/__init__.py
diff --git a/sf_user/admin.py b/sf_user/admin.py
new file mode 100644
index 0000000..2e9690a
--- /dev/null
+++ b/sf_user/admin.py
@@ -0,0 +1,19 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from django.contrib import admin
+
+# Register your models here.
diff --git a/sf_user/apps.py b/sf_user/apps.py
new file mode 100644
index 0000000..902aa7d
--- /dev/null
+++ b/sf_user/apps.py
@@ -0,0 +1,21 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from django.apps import AppConfig
+
+
+class SfUserConfig(AppConfig):
+    name = 'sf_user'
diff --git a/sf_user/management/__init__.py b/sf_user/management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sf_user/management/__init__.py
diff --git a/sf_user/management/commands/__init__.py b/sf_user/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sf_user/management/commands/__init__.py
diff --git a/sf_user/management/commands/clean_guest_data.py b/sf_user/management/commands/clean_guest_data.py
new file mode 100644
index 0000000..0ff087b
--- /dev/null
+++ b/sf_user/management/commands/clean_guest_data.py
@@ -0,0 +1,19 @@
+from django.core.management.base import BaseCommand, CommandError
+from sf_user.models import CustomSession, CustomUser
+
+
+class Command(BaseCommand):
+    help = 'Clean Guest Users Sessions'
+
+    #def add_arguments(self, parser):
+    #    parser.add_argument('poll_id', nargs='+', type=int)
+
+    def handle(self, *args, **options):
+        #for guest in CustomUser.objects.filter(is_guest_user="True"):
+        #    self.stdout.write(self.style.SUCCESS(guest.username))
+            try:
+                CustomUser.objects.filter(is_guest_user="True").delete()
+            except Exception:
+                raise CommandError('Error unable to clean guest users sessions')
+
+            self.stdout.write(self.style.SUCCESS('Successfully cleaned guest users sessions'))
diff --git a/sf_user/management/commands/clearsessions.py b/sf_user/management/commands/clearsessions.py
new file mode 100644
index 0000000..8717521
--- /dev/null
+++ b/sf_user/management/commands/clearsessions.py
@@ -0,0 +1,17 @@
+from django.core.management.base import BaseCommand, CommandError
+from sf_user.models import CustomSession
+
+
+class Command(BaseCommand):
+    help = 'Clean Users Sessions'
+
+    #def add_arguments(self, parser):
+    #    parser.add_argument('poll_id', nargs='+', type=int)
+
+    def handle(self, *args, **options):
+            try:
+                CustomSession.objects.all().delete()
+            except Exception:
+                raise CommandError('Error unable to clean users sessions')
+
+            self.stdout.write(self.style.SUCCESS('Successfully cleaned users sessions'))
\ No newline at end of file
diff --git a/sf_user/models.py b/sf_user/models.py
new file mode 100644
index 0000000..6485e82
--- /dev/null
+++ b/sf_user/models.py
@@ -0,0 +1,195 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from __future__ import unicode_literals
+
+from django.contrib.auth.models import (
+    AbstractBaseUser, BaseUserManager, PermissionsMixin)
+from django.utils import timezone
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.sessions.base_session import AbstractBaseSession
+from django.db import models
+
+class CustomUserManager(BaseUserManager):
+    """Custom manager for CustomUser."""
+
+    def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
+        """Create and save a CustomUser with the given username and password. """
+        now = timezone.now()
+
+        if not username:
+            raise ValueError('The given username must be set')
+
+        is_active = extra_fields.pop("is_active", True)
+        user = self.model(username=username, is_staff=is_staff, is_active=is_active,
+                          is_superuser=is_superuser, last_login=now,
+                          date_joined=now, **extra_fields)
+        user.set_password(password)
+        user.save(using=self._db)
+        return user
+
+    """Create and save an CustomUser with the given username and password."""
+    def create_superuser(self, username, password, **extra_fields):
+        return self._create_user(username, password, True, True, is_admin=True,
+                                 **extra_fields)
+
+    """Create and save an FullOperator with the given email and password. """
+    def create_full_operator(self, username, password=None, **extra_fields):
+        return self._create_user(username, password, False, False, is_full_operator=True,
+                                 **extra_fields)
+
+    """Create and save an BasicUser with the given email and password. """
+    def create_basic_user(self, username, password=None, **extra_fields):
+        return self._create_user(username, password, False, False, is_basic_user=True,
+                                 **extra_fields)
+
+    """Create and save an GuestUser with the given email and password. """
+    def create_guest_user(self, username, password="guest", **extra_fields):
+        return self._create_user(username, password, False, False, is_guest_user=True,
+                                 **extra_fields)
+
+
+class AbstractCustomUser(AbstractBaseUser, PermissionsMixin):
+    """Abstract User with the same behaviour as Django's default User.
+
+    AbstractCustomUser does not have username field. Uses email as the
+    USERNAME_FIELD for authentication.
+
+    Use this if you need to extend EmailUser.
+
+    Inherits from both the AbstractBaseUser and PermissionMixin.
+
+    The following attributes are inherited from the superclasses:
+        * password
+        * last_login
+        * is_superuser
+
+    """
+    username = models.CharField(_('username'), max_length=255, unique=True, db_index=True)
+
+    email = models.EmailField(_('email address'), max_length=255, unique=True)
+
+    first_name = models.CharField(_('first name'), max_length=255, blank=True)
+    last_name = models.CharField(_('last name'), max_length=255, blank=True)
+    phone = models.CharField(_('phone'), max_length=100, blank=True)
+    # user_groups = models.ManyToManyField(UserGroup, verbose_name=_('user groups'), blank=True)
+
+    is_admin = models.BooleanField(_('admin status'), default=False)
+    is_full_operator = models.BooleanField(_('full_operator status'), default=False)
+    is_basic_user = models.BooleanField(_('basic_user status'), default=False)
+    is_guest_user = models.BooleanField(_('guest_user status'), default=False)
+
+    is_staff = models.BooleanField(
+        _('staff status'), default=False, help_text=_(
+            'Designates whether the user can log into this admin site.'))
+    is_active = models.BooleanField(_('active'), default=True, help_text=_(
+        'Designates whether this user should be treated as '
+        'active. Unselect this instead of deleting accounts.'))
+
+    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
+
+    objects = CustomUserManager()
+
+    USERNAME_FIELD = 'username'
+    REQUIRED_FIELDS = ['email', 'first_name', 'last_name', 'phone', ]
+
+    class Meta:
+        verbose_name = _('custom user')
+        verbose_name_plural = _('custom users')
+        abstract = True
+
+    def get_full_name(self):
+        """Return the fullname."""
+        return "%s %s" % (self.last_name, self.first_name)
+
+    def get_short_name(self):
+        """Return the firstname."""
+        return self.first_name
+
+
+class CustomUser(AbstractCustomUser):
+    """
+    Concrete class of AbstractCustomUser.
+
+    Use this if you don't need to extend CustomUser.
+
+    """
+
+    class Meta(AbstractCustomUser.Meta):
+        swappable = 'AUTH_USER_MODEL'
+
+    def count_admins(self):
+        return CustomUser.objects.filter(is_admin=True).count()
+
+    def count_employee(self):
+        return CustomUser.objects.filter(is_full_operator=True).count()
+
+    def count_basic_users(self):
+        return CustomUser.objects.filter(is_basic_user=True).count()
+
+    def count_inactives(self):
+        return CustomUser.objects.filter(is_active=False).count()
+
+    def is_guest(self):
+        return self.is_guest_user
+
+    def get_avatar(self):
+        if self.is_admin:
+            return "assets/img/employer.png"
+        elif self.is_full_operator:
+            return "assets/img/employer.png"
+        elif self.is_basic_user:
+            return "assets/img/employer.png"
+        elif self.is_guest_user:
+            return "assets/img/account_circle.png"
+
+    def get_user_role(self):
+        if self.is_admin:
+            return 0, "Admin"
+        elif self.is_full_operator:
+            return 1, "Full operator"
+        elif self.is_basic_user:
+            return 2, "Basic user"
+        elif self.is_guest_user:
+            return 3, "Guest user"
+
+    def get_user_role_name(self):
+        if self.is_admin:
+            return "Admin"
+        elif self.is_full_operator:
+            return "Full operator"
+        elif self.is_basic_user:
+            return "Basic user"
+        elif self.is_guest_user:
+            return "Guest user"
+
+    def has_perm(self, perm, obj=None):
+        if perm == 'deploymenthandler':
+            if self.is_guest_user:
+                return False
+            else:
+                return True
+        else:
+            super.has_perm(perm, obj)
+
+
+class CustomSession(AbstractBaseSession):
+    account_id = models.IntegerField(null=True, db_index=True)
+
+    @classmethod
+    def get_session_store_class(cls):
+        return SessionStore
+
diff --git a/sf_user/sessions.py b/sf_user/sessions.py
new file mode 100644
index 0000000..df4ed71
--- /dev/null
+++ b/sf_user/sessions.py
@@ -0,0 +1,32 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from django.contrib.sessions.backends.db import SessionStore as DBStore
+import sf_user
+
+class SessionStore(DBStore):
+    @classmethod
+    def get_model_class(cls):
+        return sf_user.models.CustomSession
+
+    def create_model_instance(self, data):
+        obj = super(SessionStore, self).create_model_instance(data)
+        try:
+            account_id = int(data.get('_auth_user_id'))
+        except (ValueError, TypeError):
+            account_id = None
+        obj.account_id = account_id
+        return obj
\ No newline at end of file
diff --git a/sf_user/tests.py b/sf_user/tests.py
new file mode 100644
index 0000000..79947e6
--- /dev/null
+++ b/sf_user/tests.py
@@ -0,0 +1,19 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/sf_user/views.py b/sf_user/views.py
new file mode 100644
index 0000000..fb33347
--- /dev/null
+++ b/sf_user/views.py
@@ -0,0 +1,89 @@
+#
+#   Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   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.
+#
+
+from django.shortcuts import render
+from django.contrib.auth import login, logout, authenticate
+from django.http import HttpResponseRedirect
+from sf_user.models import CustomUser
+import urllib
+import uuid
+
+
+# Create your views here.
+def login_view(request):
+    if hasattr(request.user, "is_guest_user") and request.user.is_guest_user == True:
+        print "is_guest", request.user.is_guest_user
+        CustomUser.objects.get(id=request.user.id).delete()
+    logout(request)
+    extra_data = {}
+    next_page = ""
+    if request.GET:
+        next_page = request.GET['next']
+    error_message = ''
+    if request.POST:
+        print request.POST.get('username')
+        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'))
+        print "Auth Result: " + str(user) + " -> " + str(user)
+        if user and user.is_active:
+            if user.is_authenticated():
+                login(request, user)
+                print next_page
+                if next_page == "" or next_page is None:
+                    return HttpResponseRedirect('/home')
+                else:
+                    return HttpResponseRedirect(next_page)
+        else:
+            error_message = 'Login failed!'
+    return render(request, 'login.html', {'error_message':error_message, 'collapsed_sidebar': False})
+
+
+def guest_login(request):
+    #user = CustomUser.objects.get(id=request.user.id)
+    if hasattr(request.user, "is_guest_user") and request.user.is_guest_user == True:
+        CustomUser.objects.get(id=request.user.id).delete()
+    logout(request)
+    next = ""
+
+    guest_user_name = "Guest_"+str(uuid.uuid4())
+    guest_user_email = guest_user_name+"@guest.it"
+    guest_user = CustomUser.objects.create(username=guest_user_name, is_guest_user="True", email=guest_user_email, first_name='User', last_name='Guest')
+    print guest_user.username
+
+    if guest_user and guest_user.is_active:
+        if guest_user.is_authenticated():
+            login(request, guest_user)
+            if next == "":
+                return HttpResponseRedirect('/home')
+            else:
+                return HttpResponseRedirect(next)
+
+    return render(request, 'login.html', {'error_message': 'New Guest session failed.'})
+
+
+def register_view(request):
+
+    logout(request)
+    extra_data = {}
+    next = ""
+    if request.GET:
+        next = request.GET['next']
+    error_message = ''
+    if request.POST:
+        print "new user"
+    return render(request, 'register_user.html', {'error_message': error_message, 'collapsed_sidebar': False})
\ No newline at end of file