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