incomplete support to user and project management 42/6342/2
authorlombardofr <lombardo@everyup.it>
Tue, 12 Jun 2018 09:21:02 +0000 (11:21 +0200)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Thu, 19 Jul 2018 12:10:28 +0000 (13:10 +0100)
Change-Id: I9238ec321a292bb23c5c5797681819794dcfd0f0
Signed-off-by: lombardofr <lombardo@everyup.it>
20 files changed:
.gitignore
_.sqlite3 [new file with mode: 0644]
authosm/__init__.py [new file with mode: 0644]
authosm/admin.py [new file with mode: 0644]
authosm/apps.py [new file with mode: 0644]
authosm/backend.py [new file with mode: 0644]
authosm/models.py [new file with mode: 0644]
authosm/tests.py [new file with mode: 0644]
authosm/views.py [new file with mode: 0644]
lib/osm/osmclient/client.py
projecthandler/models.py
projecthandler/osm_model.py
projecthandler/template/project/osm/osm_project_descriptors.html
projecthandler/urls/project.py
projecthandler/views.py
sf_t3d/settings.py
sf_t3d/urls.py
sf_t3d/views.py
template/base.html
template/login.html

index 06fb943..40f146b 100644 (file)
@@ -45,3 +45,5 @@ static/bower_components
 projecthandler/migrations/
 sf_user/migrations/
 instancehandler/migrations
+sdnctrlhandler/migrations
+authosm/migrations
\ No newline at end of file
diff --git a/_.sqlite3 b/_.sqlite3
new file mode 100644 (file)
index 0000000..fe5e621
Binary files /dev/null and b/_.sqlite3 differ
diff --git a/authosm/__init__.py b/authosm/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/authosm/admin.py b/authosm/admin.py
new file mode 100644 (file)
index 0000000..8c38f3f
--- /dev/null
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/authosm/apps.py b/authosm/apps.py
new file mode 100644 (file)
index 0000000..c3d4506
--- /dev/null
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class AuthosmConfig(AppConfig):
+    name = 'authosm'
diff --git a/authosm/backend.py b/authosm/backend.py
new file mode 100644 (file)
index 0000000..1b92156
--- /dev/null
@@ -0,0 +1,51 @@
+#
+#   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.
+#
+from .models import OsmUser
+
+
+class OsmBackend(object):
+
+    def authenticate(self, **kwargs):
+        '''
+        kwargs will receive the python dict that may contain
+        {username, password, project-id}  to authenticate
+        '''
+        if all(k in kwargs for k in ('username', 'password', 'project_id')):
+            username = kwargs['username']
+            password = kwargs['password']
+            project_id = kwargs['project_id']
+
+            print username
+            print password
+            print project_id
+
+            try:
+
+                return OsmUser.objects.get(username=username)
+            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.save()
+                return user
+
+        return None
+
+    def get_user(self, user_id):
+        try:
+            return OsmUser.objects.get(pk=user_id)
+        except OsmUser.DoesNotExist:
+            return None
\ No newline at end of file
diff --git a/authosm/models.py b/authosm/models.py
new file mode 100644 (file)
index 0000000..c48f738
--- /dev/null
@@ -0,0 +1,92 @@
+#
+#   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.
+#
+from __future__ import unicode_literals
+from django.db import models
+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
+
+
+class OsmUserManager(BaseUserManager):
+    """Custom manager for OsmUser."""
+
+    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 OsmUser 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)
+
+
+class AbstractOsmUser(AbstractBaseUser, PermissionsMixin):
+    """Abstract User with the same behaviour as Django's default User.
+
+
+    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)
+    current_project = models.CharField(_('project_id'), max_length=255)
+    token_project = models.CharField(_('token'), max_length=36)
+    is_admin = models.BooleanField(_('admin status'), default=False)
+    is_basic_user = models.BooleanField(_('basic_user status'), default=False)
+
+    objects = OsmUserManager()
+
+    USERNAME_FIELD = 'username'
+    REQUIRED_FIELDS = []
+
+    class Meta:
+        verbose_name = _('custom user')
+        verbose_name_plural = _('custom users')
+        abstract = True
+
+
+
+class OsmUser(AbstractOsmUser):
+    """
+        Concrete class of AbstractCustomUser.
+
+        Use this if you don't need to extend CustomUser.
+
+        """
+
+    class Meta(AbstractOsmUser.Meta):
+        swappable = 'AUTH_USER_MODEL'
+
+    def get_projects(self):
+        client = Client()
+        return []
diff --git a/authosm/tests.py b/authosm/tests.py
new file mode 100644 (file)
index 0000000..7ce503c
--- /dev/null
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/authosm/views.py b/authosm/views.py
new file mode 100644 (file)
index 0000000..f97e8e1
--- /dev/null
@@ -0,0 +1,47 @@
+#
+#   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.
+#
+from django.shortcuts import render
+from django.contrib.auth import login, logout, authenticate
+from django.http import HttpResponseRedirect
+import urllib
+
+
+# Create your views here.
+def user_login(request):
+
+    logout(request)
+
+    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'),
+                            project_id=request.POST.get('project_id'))
+
+        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})
index d91d297..c8b2856 100644 (file)
@@ -14,7 +14,7 @@ log = logging.getLogger('helper.py')
 
 
 class Client(object):
-    def __init__(self, host=os.getenv('OSM_SERVER', "localhost"), so_port=9999, so_project='admin', ro_host=None, ro_port=9090, **kwargs):
+    def __init__(self, host=os.getenv('OSM_SERVER', "localhost"), so_port=9999, so_project='admin', **kwargs):
 
         self._user = 'admin'
         self._password = 'admin'
index 66fb7a5..79381f5 100644 (file)
@@ -42,7 +42,7 @@ class Project(models.Model):
 
 
     """
-    owner = models.ForeignKey('sf_user.CustomUser', db_column='owner')
+    owner = models.ForeignKey('authosm.OsmUser', db_column='owner')
     name = models.CharField(max_length=20, default='')
     created_date = models.DateTimeField(default=timezone.now)
     updated_date = models.DateTimeField(default=timezone.now, blank=True, null=True)
@@ -287,47 +287,3 @@ class ProjectStateless(Project):
 
     def get_overview_data(self):
         raise NotImplementedError
-
-class Repository(models.Model):
-    """ Repository
-    """
-    name = models.CharField(max_length=20, default='')
-    base_url = models.TextField(default='')
-    last_update = models.DateTimeField(default=timezone.now)
-    DIR_NAME = "/tmp/git_repo/"
-
-    def fetch_repository(self):
-        """
-        :return: git.remote.FetchInfo object
-        """
-        if os.path.isdir(self.DIR_NAME):
-            shutil.rmtree(self.DIR_NAME)
-
-        os.mkdir(self.DIR_NAME)
-        repo = git.Repo.init(self.DIR_NAME)
-        origin = repo.create_remote('origin', self.base_url)
-        origin.fetch()
-        fetch_info = origin.pull('master')[0]
-        return fetch_info
-
-    def push_repository(self, msg=None):
-        """
-        :param msg: Commit message
-        :return: git.remote.PushInfo object
-        """
-        repo = git.Repo.init(self.DIR_NAME)
-        origin = repo.remote('origin')
-        repo.git.add('--all')
-        repo.git.commit('-m \'[RDCL3D commit] ' + msg + '\'')
-        push_info = origin.push('master')[0]
-        return push_info
-
-    def to_json(self):
-        """
-        :return: JSON data of object
-        """
-        return {
-            'name': self.name,
-            'base_url': self.base_url.rstrip('\/'),
-            'last_update': self.last_update
-        }
index f3daedf..1775797 100644 (file)
@@ -1,5 +1,5 @@
 #
-#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#   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.
 
 from __future__ import unicode_literals
 
-import copy
 import json
 import os.path
 import yaml
 from lib.util import Util
 import logging
-from projecthandler.models import ProjectStateless
 
-from lib.osm.osm_parser import OsmParser
-from lib.osm.osm_rdcl_graph import OsmRdclGraph
 from lib.osm.osmclient.client import Client
 
 logging.basicConfig(level=logging.DEBUG)
 log = logging.getLogger('OsmModel.py')
 
 
-PATH_TO_SCHEMAS = 'lib/osm/schemas/'
-PATH_TO_DESCRIPTORS_TEMPLATES = 'lib/osm/descriptor_template'
-DESCRIPTOR_TEMPLATE_SUFFIX = '.json'
-GRAPH_MODEL_FULL_NAME = 'lib/TopologyModels/osm/osm.yaml'
-EXAMPLES_FOLDER = 'usecases/OSM/'
-
-
-class OsmProject(ProjectStateless):
+class OsmProject(object):
     """Osm Project class
-    The data model has the following descriptors:
-        # descrtiptor list in comment #
-
     """
 
-    def get_descriptors(self, type_descriptor):
+    @staticmethod
+    def get_descriptors( type_descriptor):
         """Returns all descriptors of a given type"""
         log.debug("Get %s descriptors", type_descriptor)
         try:
@@ -62,7 +49,8 @@ class OsmProject(ProjectStateless):
             result = {}
         return result
 
-    def get_descriptor(self, descriptor_id, type_descriptor):
+    @staticmethod
+    def get_descriptor( descriptor_id, type_descriptor):
         """Returns a specific descriptor"""
         try:
             client = Client()
@@ -79,93 +67,36 @@ class OsmProject(ProjectStateless):
 
         return result
 
-    @classmethod
-    def data_project_from_files(cls, request):
-
-        file_dict = {}
-        for my_key in request.FILES.keys():
-            file_dict[my_key] = request.FILES.getlist(my_key)
-
-        log.debug(file_dict)
-
-        data_project = OsmParser.importprojectfiles(file_dict)
-
-        return data_project
-
-    @classmethod
-    def data_project_from_example(cls, request):
-        osm_id = request.POST.get('example-osm-id', '')
-        data_project = OsmParser.importprojectdir(EXAMPLES_FOLDER + osm_id + '/JSON', 'yaml')
-        return data_project
-
-    @classmethod
-    def get_example_list(cls):
-        """Returns a list of directories, in each directory there is a project osm"""
-
-        path = EXAMPLES_FOLDER
-        dirs = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
-        return {'osm': dirs}
-
-    @classmethod
-    def get_new_descriptor(cls, descriptor_type, request_id):
-
-        json_template = cls.get_descriptor_template(descriptor_type)
-
-        return json_template
-
-    @classmethod
-    def get_descriptor_template(cls, type_descriptor):
-        """Returns a descriptor template for a given descriptor type"""
-
-        try:
-            schema = Util.loadjsonfile(os.path.join(PATH_TO_DESCRIPTORS_TEMPLATES, type_descriptor + DESCRIPTOR_TEMPLATE_SUFFIX))
-            return schema
-        except Exception as e:
-            log.exception(e)
-            return False
-
-    @classmethod
-    def get_clone_descriptor(cls, descriptor, type_descriptor, new_descriptor_id):
-        new_descriptor = copy.deepcopy(descriptor)
-
-        return new_descriptor
-
-    def get_type(self):
+    @staticmethod
+    def get_type():
         return "osm"
 
     def __str__(self):
         return self.name
 
-    def get_overview_data(self):
-        current_data = json.loads(self.data_project)
+    @staticmethod
+    def get_overview_data():
         client = Client()
         nsd = client.nsd_list()
         vnfd = client.vnfd_list()
         ns = client.ns_list()
         vnf = client.vnf_list()
         result = {
-            'owner': self.owner.__str__(),
-            'name': self.name,
-            'updated_date': self.updated_date.strftime('%Y-%m-%d %H:%M'),
-            'info': self.info,
+            'owner': '-',
+            'name': '-',
+            'updated_date': '-',
+            'info': '-',
             'type': 'osm',
             'nsd': len(nsd) if nsd else 0,
             'vnfd': len(vnfd) if vnfd else 0,
             'ns': len(ns) if ns else 0,
             'vnf': len(vnf) if vnf else 0,
-            #'validated': self.validated
         }
 
         return result
 
-    def get_graph_data_json_topology(self, descriptor_id):
-        rdcl_graph = OsmRdclGraph()
-        project = self.get_dataproject()
-        topology = rdcl_graph.build_graph_from_project(project,
-                                                     model=self.get_graph_model(GRAPH_MODEL_FULL_NAME))
-        return json.dumps(topology)
-
-    def create_descriptor(self, descriptor_name, type_descriptor, new_data, data_type, file_uploaded):
+    @staticmethod
+    def create_descriptor(descriptor_name, type_descriptor, new_data, data_type, file_uploaded):
         """Creates a descriptor of a given type from a json or yaml representation
 
         Returns the descriptor id or False
@@ -188,7 +119,8 @@ class OsmProject(ProjectStateless):
             result = False
         return result
 
-    def delete_descriptor(self, type_descriptor, descriptor_id):
+    @staticmethod
+    def delete_descriptor(type_descriptor, descriptor_id):
         log.debug('Delete descriptor')
         try:
             client = Client()
@@ -206,7 +138,8 @@ class OsmProject(ProjectStateless):
             result = False
         return result
 
-    def edit_descriptor(self, type_descriptor, descriptor_id, new_data, data_type):
+    @staticmethod
+    def edit_descriptor(type_descriptor, descriptor_id, new_data, data_type):
         log.debug("Edit descriptor")
         try:
             client = Client()
@@ -231,7 +164,8 @@ class OsmProject(ProjectStateless):
             result = False
         return result
 
-    def get_package_files_list(self, type_descriptor, descriptor_id):
+    @staticmethod
+    def get_package_files_list(type_descriptor, descriptor_id):
         try:
             client = Client()
             if type_descriptor == 'nsd':
@@ -248,9 +182,6 @@ class OsmProject(ProjectStateless):
         print result
         return result
 
-    def set_validated(self, value):
-        self.validated = True if value is not None and value == True else False
-
     def get_add_element(self, request):
         result = False
 
@@ -272,7 +203,8 @@ class OsmProject(ProjectStateless):
 
         return result
 
-    def create_ns(self, descriptor_type, descriptor_id, data_ns):
+    @staticmethod
+    def create_ns(descriptor_type, descriptor_id, data_ns):
         try:
             client = Client()
             if descriptor_type == 'nsd':
@@ -286,7 +218,8 @@ class OsmProject(ProjectStateless):
         print result
         return result
 
-    def download_pkg(self, project, descriptor_id, descriptor_type):
+    @staticmethod
+    def download_pkg(descriptor_id, descriptor_type):
         try:
             client = Client()
             if descriptor_type == 'nsd':
@@ -300,31 +233,4 @@ class OsmProject(ProjectStateless):
             log.exception(e)
             result = False
         print result
-        return result
-
-    def get_available_nodes(self, args):
-        """Returns all available node """
-        log.debug('get_available_nodes')
-        try:
-            result = []
-            #current_data = json.loads(self.data_project)
-            model_graph = self.get_graph_model(GRAPH_MODEL_FULL_NAME)
-            for node in model_graph['layer'][args['layer']]['nodes']:
-
-                current_data = {
-                    "id": node,
-                    "category_name": model_graph['nodes'][node]['label'],
-                    "types": [
-                        {
-                            "name": "generic",
-                            "id": node
-                        }
-                    ]
-                }
-                result.append(current_data)
-
-            #result = current_data[type_descriptor][descriptor_id]
-        except Exception as e:
-            log.debug(e)
-            result = []
-        return result
+        return result
\ No newline at end of file
index 51dc3f5..99b6111 100644 (file)
@@ -22,7 +22,7 @@
 
 {% block breadcrumb_body %}
        {{ block.super }}
-    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_overview_data.name}}</a></li>
+    <li><a href="{% url 'projects:open_project' project_id=project_id %}">{{project_id}}</a></li>
     <li><a> {% if descriptor_type  %}
      {{ descriptor_type }}
   {% else%}
index 452365a..2054656 100644 (file)
@@ -20,36 +20,21 @@ from projecthandler import views
 urlpatterns = [
     url(r'^list/', views.user_projects, name='projects_list'),
     url(r'^new/', views.create_new_project, name='new_project'),
-    url(r'^(?P<project_id>\d+)/$', views.open_project, name='open_project'),
-    url(r'^(?P<project_id>\d+)/sdn/', include('sdnctrlhandler.urls', namespace='sdns'), name='sdns_base'),
-    url(r'^(?P<project_id>\d+)/vims/', include('vimhandler.urls', namespace='vims'), name='vims_base'),
-    url(r'^(?P<project_id>\d+)/instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'),
-    url(r'^(?P<project_id>\d+)/delete$', views.delete_project, name='delete_project'),
-    url(r'^(?P<project_id>\d+)/graph(/$)', views.graph, name='graph_view'),
-    url(r'^(?P<project_id>\d+)/graph/graph_data(/$)', views.graph_data, name='graph_data'),
-    url(r'^(?P<project_id>\d+)/graph/graph_data/(?P<descriptor_id>[-\w]+)(/$)', views.graph_data, name='graph_data'),
-    url(r'^(?P<project_id>\d+)/graph/positions$', views.graph_positions, name='graph_positions'),
-    url(r'^(?P<project_id>\d+)/graph/unusedvnf/(?P<nsd_id>\w+)(/$)', views.unused_vnf, name='unused_vnf'),
-    url(r'^(?P<project_id>\d+)/graph/addelement$', views.add_element, name='addelement'),
-    url(r'^(?P<project_id>\d+)/graph/overviewelement$', views.overviewelement, name='overviewelement'),
-    url(r'^(?P<project_id>\d+)/graph/addnodetovnffg', views.add_node_to_vnffg, name='addnodetovnffg'),
-    url(r'^(?P<project_id>\d+)/graph/removeelement$', views.remove_element, name='removeelement'),
-    url(r'^(?P<project_id>\d+)/graph/addlink$', views.add_link, name='addlink'),
-    url(r'^(?P<project_id>\d+)/graph/removelink$', views.remove_link, name='removelink'),
-    url(r'^(?P<project_id>\d+)/graph/availablenodes', views.get_available_nodes, name='get_available_nodes'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/list$', views.show_descriptors, name='list_descriptors'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)(/$)',
+    url(r'^(?P<project_id>\w+)/$', views.open_project, name='open_project'),
+    url(r'^(?P<project_id>\w+)/sdn/', include('sdnctrlhandler.urls', namespace='sdns'), name='sdns_base'),
+    url(r'^(?P<project_id>\w+)/vims/', include('vimhandler.urls', namespace='vims'), name='vims_base'),
+    url(r'^(?P<project_id>\w+)/instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'),
+    url(r'^(?P<project_id>\w+)/delete$', views.delete_project, name='delete_project'),
+    url(r'^(?P<project_id>\w+)/descriptors/(?P<descriptor_type>\w+)/list$', views.show_descriptors, name='list_descriptors'),
+    url(r'^(?P<project_id>\w+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)(/$)',
         views.edit_descriptor, name='edit_descriptor'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/delete$',
+    url(r'^(?P<project_id>\w+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/delete$',
         views.delete_descriptor,
         name='delete_descriptor'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/clone$',
-        views.clone_descriptor,
-        name='clone_descriptor'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/action/(?P<action_name>[-\w]+)',
+    url(r'^(?P<project_id>\w+)/descriptors/(?P<descriptor_type>\w+)/(?P<descriptor_id>[-\w]+)/action/(?P<action_name>[-\w]+)',
         views.custom_action,
         name='custom_action'),
-    url(r'^(?P<project_id>\d+)/descriptors/(?P<descriptor_type>\w+)/new$', views.new_descriptor,
+    url(r'^(?P<project_id>\w+)/descriptors/(?P<descriptor_type>\w+)/new$', views.new_descriptor,
         name='new_descriptor'),
 
 
index a03ae44..16fb457 100644 (file)
@@ -20,22 +20,13 @@ from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse, JsonResponse
 from django.middleware.csrf import get_token
 from django.shortcuts import render, redirect
-from django.template.loader import render_to_string
 from lib.util import Util
-from sf_user.models import CustomUser
-import tarfile
-
-
 from projecthandler.osm_model import OsmProject
-from projecthandler.models import Project
-
+from lib.osm.osmclient.client import Client
 
-Project.add_project_type('osm', OsmProject)
 
 
 
-from projecthandler.models import Repository
-
 @login_required
 def home(request):
     return render(request, 'home.html', {})
@@ -43,81 +34,14 @@ def home(request):
 
 @login_required
 def create_new_project(request):
-    if request.method == 'POST':
-        error_msgs = []
-        user = CustomUser.objects.get(id=request.user.id)
-        name = request.POST.get('name', 'WithoutName')
-        info = request.POST.get('info', ' ')
-        type = request.POST.get('type', '')
-        start_from = request.POST.get('startfrom', 'scratch')
-
-        project_types = Project.get_project_types()
-        if type in project_types:
-            project_class = project_types[type]
-
-        else:
-            # FIXME this error is not handled
-            error_msgs.append('Project type undefined.')
-            return render(request, 'error.html',
-                          {'error_msg': 'Error creating new project, project type undefined. Please retry.'})
-
-        try:
-
-            if start_from == 'scratch':
-                print 'from scratch'
-                data_project = {}
-
-            elif start_from == 'files':
-                print 'from files'
-                data_project = project_class.data_project_from_files(request)
-
-            elif start_from == 'example':
-                print 'from example'
-                data_project = project_class.data_project_from_example(request)
-
-            project = project_class.create_project(name, user, False, info, data_project)
-            # print project.get_dataproject()
-
-
-        except Exception as e:
-            print 'Error creating ' + type + ' project! Please retry.'
-            print e
-            return render(request, 'error.html', {'error_msg': 'Error creating ' + type + ' project! Please retry.'})
-        return redirect('projects:open_project', project_id=project.id)
-
-    elif request.method == 'GET':
-        csrf_token_value = get_token(request)
-        result = {}
-        data_type_selector = [{
-            'id': '-1',
-            'text': 'Select an option'
-        }]
-        type_example_files = {}
-        type_container_template = ''
-        project_types = Project.get_project_types()
-        print "project_types", project_types.keys()
-        for type in project_types:
-            project_class = project_types[type]
-            type_example_files.update(project_class.get_example_list())
-            data_type_selector.append({
-                'id': type,
-                'text': type,
-                'value': type
-            })
-            type_container_template += render_to_string(type + '/' + type + '_new_project.html')
-
-        result.update({'type_example_files': json.dumps(type_example_files)})
-        result.update({'data_type_selector': json.dumps(data_type_selector)})
-        result.update({'type_container_template': type_container_template})
-        result.update({'csrf_token': csrf_token_value})
-        return render(request, 'new_project.html', result)
+    return render(request, 'home.html', {})
 
 
 @login_required
 def user_projects(request):
     csrf_token_value = get_token(request)
-    user = CustomUser.objects.get(id=request.user.id)
-    projects = Project.objects.filter(owner=user).select_subclasses()
+    user = request.user
+    projects = user.get_projects()
 
     return render(request, 'projectlist.html', {
         'projects': list(projects),
@@ -128,11 +52,25 @@ def user_projects(request):
 @login_required
 def open_project(request, project_id=None):
     try:
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        project_overview = projects[0].get_overview_data()
-        prj_token = project_overview['type']
-        print request.COOKIES.keys()
-        return render(request, prj_token + '/' + prj_token + '_project_details.html',
+        user = request.user
+        client = Client()
+        nsd = client.nsd_list()
+        vnfd = client.vnfd_list()
+        ns = client.ns_list()
+        vnf = client.vnf_list()
+        project_overview = {
+            'owner': user.username,
+            'name': project_id,
+            'updated_date': '-',
+            'created_date': '-',
+            'info': '-',
+            'type': 'osm',
+            'nsd': len(nsd) if nsd else 0,
+            'vnfd': len(vnfd) if vnfd else 0,
+            'ns': len(ns) if ns else 0,
+            'vnf': len(vnf) if vnf else 0,
+        }
+        return render(request, 'osm/osm_project_details.html',
                       {'project_overview': project_overview, 'project_id': project_id})
 
     except Exception as e:
@@ -145,7 +83,7 @@ def delete_project(request, project_id=None):
     if request.method == 'POST':
 
         try:
-            Project.objects.filter(id=project_id).delete()
+            ##TODO delete project
             return redirect('projects:projects_list')
         except Exception as e:
             print e
@@ -153,13 +91,8 @@ def delete_project(request, project_id=None):
 
     elif request.method == 'GET':
         try:
-            projects = Project.objects.filter(id=project_id).select_subclasses()
-            project_overview = projects[0].get_overview_data()
-            prj_token = project_overview['type']
-            #                 example: 'etsi/etsi_project_delete.html'
-            print  prj_token + '/' + prj_token + '_project_delete.html', project_overview['name']
-            return render(request, prj_token + '/' + prj_token + '_project_delete.html',
-                          {'project_id': project_id, 'project_name': project_overview['name']})
+            return render(request, 'osm/osm_project_delete.html',
+                          {'project_id': project_id, 'project_name': project_id})
 
         except Exception as e:
             print e
@@ -169,62 +102,49 @@ def delete_project(request, project_id=None):
 @login_required
 def show_descriptors(request, project_id=None, descriptor_type=None):
     csrf_token_value = get_token(request)
-    projects = Project.objects.filter(id=project_id).select_subclasses()
-    project_overview = projects[0].get_overview_data()
-    prj_token = project_overview['type']
 
-    url = prj_token + '/' + prj_token + '_project_descriptors.html'
+    client = Client()
+    try:
+        if descriptor_type == 'nsd':
+            descriptors = client.nsd_list()
+
+        elif descriptor_type == 'vnfd':
+            descriptors = client.vnfd_list()
+    except Exception as e:
+        descriptors = []
+
+    url = 'osm/osm_project_descriptors.html'
     return __response_handler(request, {
-        'descriptors': projects[0].get_descriptors(descriptor_type),
+        'descriptors': descriptors,
         'project_id': project_id,
-        'project_type': prj_token,
-        'project_overview_data': project_overview,
+        'project_type': 'osm',
         "csrf_token_value": csrf_token_value,
         'descriptor_type': descriptor_type
     },url)
 
 
 @login_required
-def graph(request, project_id=None):
-    if request.method == 'GET':
-        csrf_token_value = get_token(request)
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        project_overview = projects[0].get_overview_data()
-        prj_token = project_overview['type']
-        # example : 'etsi/project_graph.html'
-        return render(request, prj_token + '/project_graph.html', {
-            'project_id': project_id,
-            'project_overview_data': projects[0].get_overview_data(),
-            'collapsed_sidebar': False
-        })
-
-
-@login_required
-def graph_data(request, project_id=None, descriptor_id=None):
-    print 'graph_data', project_id, descriptor_id
-    projects = Project.objects.filter(id=project_id).select_subclasses()
-    project_overview = projects[0].get_overview_data()
-    # data = projects[0].get_overview_data()
-    prj_token = project_overview['type']
-
-    topology = projects[0].get_graph_data_json_topology(descriptor_id)
-    response = HttpResponse(topology, content_type="application/json")
-    response["Access-Control-Allow-Origin"] = "*"
+def delete_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
+    csrf_token_value = get_token(request)
 
-    return response
+    try:
+        client = Client()
+        if descriptor_type == 'nsd':
+            result = client.nsd_delete(descriptor_id)
+        elif descriptor_type == 'vnfd':
+            result = client.vnfd_delete(descriptor_id)
 
+        else:
+            return False
 
-@login_required
-def delete_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
-    csrf_token_value = get_token(request)
-    projects = Project.objects.filter(id=project_id).select_subclasses()
-    result = projects[0].delete_descriptor(descriptor_type, descriptor_id)
-    project_overview = projects[0].get_overview_data()
+    except Exception as e:
+        result = False
+    project_overview = OsmProject.get_overview_data()
     prj_token = project_overview['type']
     page = prj_token + '/' + prj_token + '_project_descriptors.html'
 
     return render(request, page, {
-        'descriptors': projects[0].get_descriptors(descriptor_type),
+        'descriptors': OsmProject.get_descriptors(descriptor_type),
         'project_id': project_id,
         'project_overview_data': project_overview,
         "csrf_token_value": csrf_token_value,
@@ -235,32 +155,10 @@ def delete_descriptor(request, project_id=None, descriptor_type=None, descriptor
     })
 
 
-@login_required
-def clone_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
-    csrf_token_value = get_token(request)
-    projects = Project.objects.filter(id=project_id).select_subclasses()
-    new_id = request.GET.get('newid', '')
-    result = projects[0].clone_descriptor(descriptor_type, descriptor_id, new_id)
-    project_overview = projects[0].get_overview_data()
-    prj_token = project_overview['type']
-    page = prj_token + '/' + prj_token + '_project_descriptors.html'
-
-    return render(request, page, {
-        'descriptors': projects[0].get_descriptors(descriptor_type),
-        'project_id': project_id,
-        'project_overview_data': project_overview,
-        "csrf_token_value": csrf_token_value,
-        'descriptor_type': descriptor_type,
-        'alert_message': {
-            'success': result,
-            'message': "Cloned!" if result else 'Error in cloning'}
-    })
-
-
 @login_required
 def new_descriptor(request, project_id=None, descriptor_type=None):
-    projects = Project.objects.filter(id=project_id).select_subclasses()
-    project_overview = projects[0].get_overview_data()
+
+    project_overview = OsmProject.get_overview_data()
     prj_token = project_overview['type']
     page = prj_token + '/descriptor/descriptor_new.html'
     if request.method == 'GET':
@@ -280,17 +178,17 @@ def new_descriptor(request, project_id=None, descriptor_type=None):
             text = file_uploaded.read()
             data_type = file_uploaded.name.split(".")[-1]
             desc_name = file_uploaded.name.split(".")[0]
-            result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type, file_uploaded)
+            result = OsmProject.create_descriptor(desc_name, descriptor_type, text, data_type, file_uploaded)
         else:
             text = request.POST.get('text')
             desc_name = request.POST.get('id')
-            result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type)
+            result = OsmProject.create_descriptor(desc_name, descriptor_type, text, data_type)
 
 
         response_data = {
             'project_id': project_id,
             'descriptor_type': descriptor_type,
-            'project_overview_data': projects[0].get_overview_data(),
+            'project_overview_data':OsmProject.get_overview_data(),
             'descriptor_id': result,
             'alert_message': {
                 'success': True if result != False else False,
@@ -306,8 +204,7 @@ def new_descriptor(request, project_id=None, descriptor_type=None):
 def edit_descriptor(request, project_id=None, descriptor_id=None, descriptor_type=None):
     if request.method == 'POST':
         print "edit_descriptor"
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].edit_descriptor(descriptor_type, descriptor_id, request.POST.get('text'),
+        result = OsmProject.edit_descriptor(descriptor_type, descriptor_id, request.POST.get('text'),
                                              request.POST.get('type'))
         response_data = {
             'project_id': project_id,
@@ -324,13 +221,12 @@ def edit_descriptor(request, project_id=None, descriptor_id=None, descriptor_typ
 
     elif request.method == 'GET':
         csrf_token_value = get_token(request)
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        project_overview = projects[0].get_overview_data()
+        project_overview = OsmProject.get_overview_data()
         print project_overview
         prj_token = project_overview['type']
         page = prj_token + '/descriptor/descriptor_view.html'
 
-        descriptor = projects[0].get_descriptor(descriptor_id, descriptor_type)
+        descriptor = OsmProject.get_descriptor(descriptor_id, descriptor_type)
 
         descriptor_string_json = json.dumps(descriptor)
         descriptor_string_yaml = Util.json2yaml(descriptor)
@@ -338,130 +234,12 @@ def edit_descriptor(request, project_id=None, descriptor_id=None, descriptor_typ
         return render(request, page, {
             'project_id': project_id,
             'descriptor_id': descriptor_id,
-            'project_overview_data': projects[0].get_overview_data(),
+            'project_overview_data': OsmProject.get_overview_data(),
             'descriptor_type': descriptor_type,
             'descriptor_strings': {'descriptor_string_yaml': descriptor_string_yaml,
                                    'descriptor_string_json': descriptor_string_json}})
 
 
-@login_required
-def graph_positions(request, project_id=None):
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].edit_graph_positions(json.loads(request.POST.get('positions')))
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-
-@login_required
-def add_element(request, project_id=None):
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].get_add_element(request)
-
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-
-@login_required
-def remove_element(request, project_id=None):
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].get_remove_element(request)
-
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-
-@login_required
-def add_link(request, project_id=None):
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].get_add_link(request)
-
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-
-@login_required
-def remove_link(request, project_id=None):
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].get_remove_link(request)
-
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-@login_required
-def get_available_nodes(request, project_id=None):
-    if request.method == 'GET':
-        csrf_token_value = get_token(request)
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        print "get_available_nodes", request.GET.dict()
-        result = projects[0].get_available_nodes(request.GET.dict())
-        status_code = 500 if result == None else 200
-        print json.dumps(result)
-        response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-@login_required
-def overviewelement(request, project_id=None):
-    if request.method == 'GET':
-        result = {}
-        error_msg = None
-        try:
-            projects = Project.objects.filter(id=project_id).select_subclasses()
-            project = projects[0]
-            parameters = request.GET.dict()
-            print "parameters", parameters
-            result = project.get_node_overview(**parameters)
-        except Exception as e:
-            error_msg = str(e)
-
-        if error_msg is not None:
-            return JsonResponse({'error': {'error_msg': str(error_msg)}})
-
-        return JsonResponse({'node_overview': result})
-
-# ETSI specific method #
-@login_required
-def add_node_to_vnffg(request, project_id=None):
-    print "add_node_to_vnffg"  # TODO log
-    if request.method == 'POST':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].add_node_to_vnffg(request)
-
-        status_code = 200 if result else 500
-        response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-
-@login_required
-def unused_vnf(request, project_id=None, nsd_id=None):
-    if request.method == 'GET':
-        print 'in method unused_vnf : ', project_id, nsd_id  # TODO log
-        projects = Project.objects.filter(id=project_id).select_subclasses()
-        result = projects[0].get_unused_vnf(nsd_id)
-        status_code = 500 if result == None else 200
-        response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
-        response["Access-Control-Allow-Origin"] = "*"
-        return response
-
-# end ETSI specific method #
-
-
 # OSM specific method #
 def get_package_files_list(request, project_id, project, descriptor_id, descriptor_type):
     files_list = []
@@ -475,8 +253,8 @@ def get_package_files_list(request, project_id, project, descriptor_id, descript
     return __response_handler(request, result)
 
 
-def download_pkg(request, project_id, project, descriptor_id, descriptor_type):
-    tar_pkg = project.download_pkg(project, descriptor_id, descriptor_type)
+def download_pkg(request, project_id, descriptor_id, descriptor_type):
+    tar_pkg = OsmProject.download_pkg(descriptor_id, descriptor_type)
 
     response = HttpResponse(content_type="application/tgz")
     response["Content-Disposition"] = "attachment; filename=osm_export.tar.gz"
@@ -511,9 +289,8 @@ def create_ns(request, project_id, project, descriptor_id, descriptor_type):
 @login_required
 def custom_action(request, project_id=None, descriptor_id=None, descriptor_type=None, action_name=None):
     if request.method == 'GET':
-        projects = Project.objects.filter(id=project_id).select_subclasses()
         print "Custom action: " + action_name
-        return globals()[action_name](request, project_id, projects[0], descriptor_id, descriptor_type)
+        return globals()[action_name](request, project_id, descriptor_id, descriptor_type)
 
 
 def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
index 658bafd..36de1b6 100644 (file)
@@ -27,7 +27,7 @@ DEBUG = True
 
 ALLOWED_HOSTS = []
 
-AUTH_USER_MODEL = "sf_user.CustomUser"
+AUTH_USER_MODEL = "authosm.OsmUser"
 
 SITE_NAME = "Open Source MANO"
 SHORT_SITE_NAME = "OSM"
@@ -46,10 +46,12 @@ INSTALLED_APPS = [
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'sf_user',
+    'authosm',
     'projecthandler',
     'vimhandler',
     'instancehandler',
-    'sdnctrlhandler'
+    'sdnctrlhandler',
+
 ]
 
 MIDDLEWARE_CLASSES = [
@@ -113,6 +115,8 @@ DATABASES = {
     }
 }
 
+AUTHENTICATION_BACKENDS = ['authosm.backend.OsmBackend']
+
 
 # Password validation
 # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
index 5b82f5a..a213202 100644 (file)
@@ -15,19 +15,17 @@ Including another URLconf
     3. Add a URL to urlpatterns:  url(r'^blog/', include(blog_urls))
 """
 from django.conf.urls import url, include
-from django.contrib import admin
 from sf_user import views as user_views
+from authosm import views as user_views
 from sf_t3d import views
 
 app_name = 'base'
 urlpatterns = [
-    url(r'^admin/', admin.site.urls),
-    url(r'^auth/$', user_views.login_view, name='auth_user'),
-    url(r'^auth_guest/$', user_views.guest_login, name='auth_user_guest'),
-    url(r'^register', user_views.register_view, name='register_user'),
+    #url(r'^admin/', admin.site.urls),
+    url(r'^auth/$', user_views.user_login, name='auth_user'),
+    #url(r'^auth_guest/$', user_views.guest_login, name='auth_user_guest'),
+    #url(r'^register', user_views.register_view, name='register_user'),
     url(r'^projects/', include('projecthandler.urls.project', namespace='projects'), name='projects_base'),
-    #url(r'^vims/', include('vimhandler.urls', namespace='vim'), name='vims_base'),
-    #url(r'^sdn/', include('sdnctrlhandler.urls', namespace='sdn'), name='sdns_base'),
 
     url(r'^$', views.home, name='home'),
     url(r'^home', views.home, name='home'),
index 91590f0..810373f 100644 (file)
@@ -1,18 +1,20 @@
-from django.shortcuts import render
+from django.shortcuts import render, redirect
 from django.contrib.auth.decorators import login_required
 
 from projecthandler.models import Project
-from sf_user.models import CustomUser
+from authosm.models import OsmUser
 
 
 @login_required
 def home(request):
-    user = CustomUser.objects.get(id=request.user.id)
+    user = OsmUser.objects.get(id=request.user.id)
+
     projects = Project.objects.filter(owner=user).select_subclasses()
     result = {
         'projects': len(projects) if projects else 0,
     }
-    return render(request, 'home.html', result)
+    return redirect('projects:open_project', project_id='admin')
+    #return render(request, 'home.html', result)
 
 
 def forbidden(request):
index 60576d1..0932c59 100644 (file)
 
       <div class="navbar-custom-menu">
         <ul class="nav navbar-nav">
-            {% if user.get_full_name %}
+            {% if user.get_username %}
           <!-- User Account: style can be found in dropdown.less -->
           <li class="dropdown user user-menu">
             <a href="#" class="dropdown-toggle" data-toggle="dropdown">
-              <img src="{% static  user.get_avatar  %}" class="user-image" alt="User Image">
+              <img src="/static/assets/img/account_circle.png" class="user-image" alt="User Image">
                         <span class="hidden-xs">{{ user.username }}</span>
             </a>
             <ul class="dropdown-menu">
                         <!-- User image -->
                         <li class="user-header">
-                            <img src="{% static  user.get_avatar  %}" class="img-circle" alt="User Image">
+                            <img src="/static/assets/img/account_circle.png" class="img-circle" alt="User Image">
                             <p id="user_menu_name_role">
-                                {{ user.get_full_name }}
+                                {{ user.get_username }}
                                 <small id="user_menu_role">{{ user.get_user_role_name }}</small>
                             </p>
                         </li>
index 2323200..01019a4 100644 (file)
                 <input type="password" name="password" class="form-control" placeholder="Password">
                 <span class="glyphicon glyphicon-lock form-control-feedback"></span>
             </div>
+            <div class="form-group has-feedback">
+                <input name="project_id" class="form-control" placeholder="Project">
+                <span class="glyphicon glyphicon-lock form-control-feedback"></span>
+            </div>
             <div class="row">
                 <div class="col-xs-8">