From 10b52d1480ad41e7a1d51575f1e5f4ea762b2dd6 Mon Sep 17 00:00:00 2001 From: lombardofr Date: Tue, 17 Jul 2018 23:42:28 +0200 Subject: [PATCH] user: list, create, delete Change-Id: Ie670a45c4f60107b6563b10504b744d13c58b328 Signed-off-by: lombardofr --- lib/osm/osmclient/clientv2.py | 55 +++++++++++ projecthandler/views.py | 5 +- sf_t3d/settings.py | 2 + sf_t3d/urls.py | 1 + static/src/userhandler/user_list.js | 55 +++++++++++ userhandler/__init__.py | 0 userhandler/admin.py | 3 + userhandler/apps.py | 7 ++ userhandler/migrations/__init__.py | 0 userhandler/models.py | 5 + userhandler/templates/modal/user_create.html | 53 ++++++++++ userhandler/templates/modal/user_details.html | 0 userhandler/templates/user_list.html | 98 +++++++++++++++++++ userhandler/tests.py | 3 + userhandler/urls.py | 25 +++++ userhandler/views.py | 57 +++++++++++ 16 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 static/src/userhandler/user_list.js create mode 100644 userhandler/__init__.py create mode 100644 userhandler/admin.py create mode 100644 userhandler/apps.py create mode 100644 userhandler/migrations/__init__.py create mode 100644 userhandler/models.py create mode 100644 userhandler/templates/modal/user_create.html create mode 100644 userhandler/templates/modal/user_details.html create mode 100644 userhandler/templates/user_list.html create mode 100644 userhandler/tests.py create mode 100644 userhandler/urls.py create mode 100644 userhandler/views.py diff --git a/lib/osm/osmclient/clientv2.py b/lib/osm/osmclient/clientv2.py index 6555071..536ef65 100644 --- a/lib/osm/osmclient/clientv2.py +++ b/lib/osm/osmclient/clientv2.py @@ -55,6 +55,61 @@ class Client(object): return result + def user_list(self, token): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/users".format(self._base_path) + try: + r = requests.get(_url, params=None, verify=False, stream=True, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code == requests.codes.ok: + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + + return result + + def user_create(self, token, user_data): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/users".format(self._base_path) + + try: + r = requests.post(_url, json=user_data, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + print r.status_code + if r.status_code == requests.codes.created: + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def user_delete(self, token, id): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/yaml", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/users/{1}".format(self._base_path, id) + try: + r = requests.delete(_url, params=None, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code == requests.codes.no_content: + result['error'] = False + else: + result['data'] = Util.json_loads_byteified(r.text) + return result + def project_list(self, token): result = {'error': True, 'data': ''} headers = {"Content-Type": "application/yaml", "accept": "application/json", diff --git a/projecthandler/views.py b/projecthandler/views.py index 144aa5b..575d253 100644 --- a/projecthandler/views.py +++ b/projecthandler/views.py @@ -59,9 +59,10 @@ def user_projects(request): user = osmutils.get_user(request) client = Client() result = client.project_list(user.get_token()) - return render(request, 'projectlist.html', { + return __response_handler(request,{ 'projects': result['data'] if result and result['error'] is False else [], - }) + },'projectlist.html') + def open_composer(request): diff --git a/sf_t3d/settings.py b/sf_t3d/settings.py index 53bde44..0649cde 100644 --- a/sf_t3d/settings.py +++ b/sf_t3d/settings.py @@ -51,6 +51,7 @@ INSTALLED_APPS = [ 'vimhandler', 'instancehandler', 'sdnctrlhandler', + 'userhandler' ] @@ -86,6 +87,7 @@ TEMPLATES = [ os.path.join(BASE_DIR, 'vimhandler', 'template'), os.path.join(BASE_DIR, 'instancehandler', 'template'), os.path.join(BASE_DIR, 'sdnctrlhandler', 'template'), + os.path.join(BASE_DIR, 'userhandler', 'templates'), ], 'APP_DIRS': True, 'OPTIONS': { diff --git a/sf_t3d/urls.py b/sf_t3d/urls.py index 3524ebb..4902f8d 100644 --- a/sf_t3d/urls.py +++ b/sf_t3d/urls.py @@ -25,6 +25,7 @@ urlpatterns = [ url(r'^auth/$', user_views.user_login, name='auth_user'), #url(r'^register', user_views.register_view, name='register_user'), url(r'^projects/', include('projecthandler.urls.project', namespace='projects'), name='projects_base'), + url(r'^users/', include('userhandler.urls', namespace='users'), name='users_base'), url(r'^$', views.home, name='home'), url(r'^home', views.home, name='home'), diff --git a/static/src/userhandler/user_list.js b/static/src/userhandler/user_list.js new file mode 100644 index 0000000..196b878 --- /dev/null +++ b/static/src/userhandler/user_list.js @@ -0,0 +1,55 @@ +function openModalCreateUser(args) { + console.log(args) + // load projects list + select2_groups = $('#projects').select2({ + placeholder: 'Select Projects', + width: '100%', + ajax: { + url: args.projects_list_url, + dataType: 'json', + processResults: function (data) { + projects = []; + if (data['projects']) { + for (d in data['projects']) { + var project = data['projects'][d]; + projects.push({id: project['_id'], text: project['name']}) + } + } + + return { + results: projects + }; + } + } + }); + + + + $('#modal_new_user').modal('show'); +} + +function deleteUser(delete_url) { + bootbox.confirm("Are you sure want to delete?", function (confirm) { + if (confirm) { + var dialog = bootbox.dialog({ + message: '
Loading...
', + closeButton: false + }); + $.ajax({ + url: delete_url, + dataType: "json", + contentType: "application/json;charset=utf-8", + success: function (result) { + //$('#modal_show_vim_body').empty(); + dialog.modal('hide'); + location.reload(); + }, + error: function (result) { + dialog.modal('hide'); + bootbox.alert("An error occurred."); + } + }); + } + }) + +} \ No newline at end of file diff --git a/userhandler/__init__.py b/userhandler/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/userhandler/admin.py b/userhandler/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/userhandler/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/userhandler/apps.py b/userhandler/apps.py new file mode 100644 index 0000000..45574cc --- /dev/null +++ b/userhandler/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class UserhandlerConfig(AppConfig): + name = 'userhandler' diff --git a/userhandler/migrations/__init__.py b/userhandler/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/userhandler/models.py b/userhandler/models.py new file mode 100644 index 0000000..bd4b2ab --- /dev/null +++ b/userhandler/models.py @@ -0,0 +1,5 @@ +from __future__ import unicode_literals + +from django.db import models + +# Create your models here. diff --git a/userhandler/templates/modal/user_create.html b/userhandler/templates/modal/user_create.html new file mode 100644 index 0000000..7967cc6 --- /dev/null +++ b/userhandler/templates/modal/user_create.html @@ -0,0 +1,53 @@ + diff --git a/userhandler/templates/modal/user_details.html b/userhandler/templates/modal/user_details.html new file mode 100644 index 0000000..e69de29 diff --git a/userhandler/templates/user_list.html b/userhandler/templates/user_list.html new file mode 100644 index 0000000..03ae70f --- /dev/null +++ b/userhandler/templates/user_list.html @@ -0,0 +1,98 @@ +{% extends "base.html" %} +{% load get %} +{% load date_tag %} +{% load staticfiles %} + + +{% block head_block %} + {{ block.super }} + +{% endblock %} +{% block title_header_big %} + {{ block.super }} +{% endblock %} +{% block left_sidebar %} + {% include 'osm/osm_project_left_sidebar.html' %} +{% endblock %} + + +{% block breadcrumb_body %} + {{ block.super }} +
  • Users
  • +{% endblock %} + +{% block content_body %} + {{ block.super }} + {% include 'modal/user_details.html' %} + {% include 'modal/user_create.html' %} + {% csrf_token %} +
    +
    + +
    +
    +

    Users

    +
    + + +
    +
    +
    + + + + + + + + + + + + + + {% for s in users %} + + + + + + + + + + + + {% endfor %} + +
    NameProjectsIdentifierModifiedCreatedActions
    {{ s|get:"username" }}{{ s|get:"projects" }}{{ s|get:"_id" }}{{ s|get_sub:"_admin,modified"|get_date}}{{ s|get_sub:"_admin,created"|get_date}} +
    + + +
    +
    +
    +
    +
    + +
    +{% endblock %} + +{% block resource_block %} + {{ block.super }} + + + + + +{% endblock %} + +{% block footer %} + {% include "footer.html" %} +{% endblock %} \ No newline at end of file diff --git a/userhandler/tests.py b/userhandler/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/userhandler/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/userhandler/urls.py b/userhandler/urls.py new file mode 100644 index 0000000..05d88f0 --- /dev/null +++ b/userhandler/urls.py @@ -0,0 +1,25 @@ +# +# Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from django.conf.urls import url +from userhandler import views + +urlpatterns = [ + url(r'^list$', views.list, name='list'), + url(r'^create$', views.create, name='create'), + url(r'^(?P[0-9a-zA-Z]+)/delete$', views.delete, name='delete'), + +] \ No newline at end of file diff --git a/userhandler/views.py b/userhandler/views.py new file mode 100644 index 0000000..8e312fa --- /dev/null +++ b/userhandler/views.py @@ -0,0 +1,57 @@ +from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +import json +import logging +import authosm.utils as osmutils +from lib.osm.osmclient.clientv2 import Client + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger(__name__) + + +@login_required +def list(request): + user = osmutils.get_user(request) + client = Client() + result = client.user_list(user.get_token()) + result = { + 'users': result['data'] if result and result['error'] is False else [] + } + return __response_handler(request, result, 'user_list.html') + + +@login_required +def create(request): + user = osmutils.get_user(request) + client = Client() + user_data ={ + "username": request.POST['username'], + "password": request.POST['password'], + "projects": request.POST.getlist('projects') + } + + result = client.user_create(user.get_token(), user_data) + + return __response_handler(request, result, 'users:list', to_redirect=True) + + +@login_required +def delete(request, user_id=None): + user = osmutils.get_user(request) + try: + client = Client() + del_res = client.user_delete(user.get_token(), user_id) + except Exception as e: + log.exception(e) + return __response_handler(request, {}, 'users:list', to_redirect=True, ) + + +def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs): + raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') + if 'application/json' in raw_content_types or url is None: + return HttpResponse(json.dumps(data_res), content_type="application/json", *args, **kwargs) + elif to_redirect: + return redirect(url, *args, **kwargs) + else: + return render(request, url, data_res) -- 2.17.1