From: lombardofr Date: Tue, 12 Jun 2018 09:21:02 +0000 (+0200) Subject: incomplete support to user and project management X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=refs%2Fchanges%2F42%2F6342%2F2;p=osm%2FLW-UI.git incomplete support to user and project management Change-Id: I9238ec321a292bb23c5c5797681819794dcfd0f0 Signed-off-by: lombardofr --- diff --git a/.gitignore b/.gitignore index 06fb943..40f146b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 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 index 0000000..e69de29 diff --git a/authosm/admin.py b/authosm/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/authosm/admin.py @@ -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 index 0000000..c3d4506 --- /dev/null +++ b/authosm/apps.py @@ -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 index 0000000..1b92156 --- /dev/null +++ b/authosm/backend.py @@ -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 index 0000000..c48f738 --- /dev/null +++ b/authosm/models.py @@ -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 index 0000000..7ce503c --- /dev/null +++ b/authosm/tests.py @@ -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 index 0000000..f97e8e1 --- /dev/null +++ b/authosm/views.py @@ -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}) diff --git a/lib/osm/osmclient/client.py b/lib/osm/osmclient/client.py index d91d297..c8b2856 100644 --- a/lib/osm/osmclient/client.py +++ b/lib/osm/osmclient/client.py @@ -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' diff --git a/projecthandler/models.py b/projecthandler/models.py index 66fb7a5..79381f5 100644 --- a/projecthandler/models.py +++ b/projecthandler/models.py @@ -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 - } diff --git a/projecthandler/osm_model.py b/projecthandler/osm_model.py index f3daedf..1775797 100644 --- a/projecthandler/osm_model.py +++ b/projecthandler/osm_model.py @@ -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. @@ -16,37 +16,24 @@ 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 diff --git a/projecthandler/template/project/osm/osm_project_descriptors.html b/projecthandler/template/project/osm/osm_project_descriptors.html index 51dc3f5..99b6111 100644 --- a/projecthandler/template/project/osm/osm_project_descriptors.html +++ b/projecthandler/template/project/osm/osm_project_descriptors.html @@ -22,7 +22,7 @@ {% block breadcrumb_body %} {{ block.super }} -
  • {{project_overview_data.name}}
  • +
  • {{project_id}}
  • {% if descriptor_type %} {{ descriptor_type }} {% else%} diff --git a/projecthandler/urls/project.py b/projecthandler/urls/project.py index 452365a..2054656 100644 --- a/projecthandler/urls/project.py +++ b/projecthandler/urls/project.py @@ -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\d+)/$', views.open_project, name='open_project'), - url(r'^(?P\d+)/sdn/', include('sdnctrlhandler.urls', namespace='sdns'), name='sdns_base'), - url(r'^(?P\d+)/vims/', include('vimhandler.urls', namespace='vims'), name='vims_base'), - url(r'^(?P\d+)/instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'), - url(r'^(?P\d+)/delete$', views.delete_project, name='delete_project'), - url(r'^(?P\d+)/graph(/$)', views.graph, name='graph_view'), - url(r'^(?P\d+)/graph/graph_data(/$)', views.graph_data, name='graph_data'), - url(r'^(?P\d+)/graph/graph_data/(?P[-\w]+)(/$)', views.graph_data, name='graph_data'), - url(r'^(?P\d+)/graph/positions$', views.graph_positions, name='graph_positions'), - url(r'^(?P\d+)/graph/unusedvnf/(?P\w+)(/$)', views.unused_vnf, name='unused_vnf'), - url(r'^(?P\d+)/graph/addelement$', views.add_element, name='addelement'), - url(r'^(?P\d+)/graph/overviewelement$', views.overviewelement, name='overviewelement'), - url(r'^(?P\d+)/graph/addnodetovnffg', views.add_node_to_vnffg, name='addnodetovnffg'), - url(r'^(?P\d+)/graph/removeelement$', views.remove_element, name='removeelement'), - url(r'^(?P\d+)/graph/addlink$', views.add_link, name='addlink'), - url(r'^(?P\d+)/graph/removelink$', views.remove_link, name='removelink'), - url(r'^(?P\d+)/graph/availablenodes', views.get_available_nodes, name='get_available_nodes'), - url(r'^(?P\d+)/descriptors/(?P\w+)/list$', views.show_descriptors, name='list_descriptors'), - url(r'^(?P\d+)/descriptors/(?P\w+)/(?P[-\w]+)(/$)', + url(r'^(?P\w+)/$', views.open_project, name='open_project'), + url(r'^(?P\w+)/sdn/', include('sdnctrlhandler.urls', namespace='sdns'), name='sdns_base'), + url(r'^(?P\w+)/vims/', include('vimhandler.urls', namespace='vims'), name='vims_base'), + url(r'^(?P\w+)/instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'), + url(r'^(?P\w+)/delete$', views.delete_project, name='delete_project'), + url(r'^(?P\w+)/descriptors/(?P\w+)/list$', views.show_descriptors, name='list_descriptors'), + url(r'^(?P\w+)/descriptors/(?P\w+)/(?P[-\w]+)(/$)', views.edit_descriptor, name='edit_descriptor'), - url(r'^(?P\d+)/descriptors/(?P\w+)/(?P[-\w]+)/delete$', + url(r'^(?P\w+)/descriptors/(?P\w+)/(?P[-\w]+)/delete$', views.delete_descriptor, name='delete_descriptor'), - url(r'^(?P\d+)/descriptors/(?P\w+)/(?P[-\w]+)/clone$', - views.clone_descriptor, - name='clone_descriptor'), - url(r'^(?P\d+)/descriptors/(?P\w+)/(?P[-\w]+)/action/(?P[-\w]+)', + url(r'^(?P\w+)/descriptors/(?P\w+)/(?P[-\w]+)/action/(?P[-\w]+)', views.custom_action, name='custom_action'), - url(r'^(?P\d+)/descriptors/(?P\w+)/new$', views.new_descriptor, + url(r'^(?P\w+)/descriptors/(?P\w+)/new$', views.new_descriptor, name='new_descriptor'), diff --git a/projecthandler/views.py b/projecthandler/views.py index a03ae44..16fb457 100644 --- a/projecthandler/views.py +++ b/projecthandler/views.py @@ -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): diff --git a/sf_t3d/settings.py b/sf_t3d/settings.py index 658bafd..36de1b6 100644 --- a/sf_t3d/settings.py +++ b/sf_t3d/settings.py @@ -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 diff --git a/sf_t3d/urls.py b/sf_t3d/urls.py index 5b82f5a..a213202 100644 --- a/sf_t3d/urls.py +++ b/sf_t3d/urls.py @@ -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'), diff --git a/sf_t3d/views.py b/sf_t3d/views.py index 91590f0..810373f 100644 --- a/sf_t3d/views.py +++ b/sf_t3d/views.py @@ -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): diff --git a/template/base.html b/template/base.html index 60576d1..0932c59 100644 --- a/template/base.html +++ b/template/base.html @@ -48,19 +48,19 @@ +
    + + +