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",
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):
'vimhandler',
'instancehandler',
'sdnctrlhandler',
+ 'userhandler'
]
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': {
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'),
--- /dev/null
+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: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+ 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
--- /dev/null
+from django.contrib import admin
+
+# Register your models here.
--- /dev/null
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class UserhandlerConfig(AppConfig):
+ name = 'userhandler'
--- /dev/null
+from __future__ import unicode_literals
+
+from django.db import models
+
+# Create your models here.
--- /dev/null
+<div class="modal" id="modal_new_user" xmlns="http://www.w3.org/1999/html">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">×</span></button>
+ <h4 class="modal-title">New User</h4>
+ </div>
+ <form id="formCreateNS" action='{% url "users:create" %}'
+ class="form-horizontal"
+ method="post" enctype="multipart/form-data">
+ {% csrf_token %}
+ <div class="modal-body" id="modal_new_user_body">
+ <div class="form-group">
+ <label for="username" class="col-sm-3 control-label">Username *</label>
+ <div class="col-sm-6">
+ <input class="form-control" id="username" name="username"
+ placeholder="Username" required>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="password" class="col-sm-3 control-label">Password *</label>
+ <div class="col-sm-6">
+ <input class="form-control" id="password" name="password" type="password"
+ placeholder="Password" required>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for=projects" class="col-sm-3 control-label">Projects *</label>
+ <div class="col-sm-6">
+ <select required id="projects" class="js-example-basic-multiple form-control" name="projects"
+ multiple="multiple">
+ </select>
+ </div>
+ </div>
+
+
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
+ <button class="btn btn-primary"
+ data-loading-text="<i class='fa fa-circle-o-notch fa-spin'></i> Creating..."
+ id="create_new_user">Create
+ </button>
+
+ </div>
+ </form>
+ </div>
+ <!-- /.modal-content -->
+ </div>
+ <!-- /.modal-dialog -->
+</div>
--- /dev/null
+{% extends "base.html" %}
+{% load get %}
+{% load date_tag %}
+{% load staticfiles %}
+
+
+{% block head_block %}
+ {{ block.super }}
+ <link rel="stylesheet" href="/static/bower_components/select2/dist/css/select2.min.css">
+{% endblock %}
+{% block title_header_big %}
+ {{ block.super }}
+{% endblock %}
+{% block left_sidebar %}
+ {% include 'osm/osm_project_left_sidebar.html' %}
+{% endblock %}
+
+
+{% block breadcrumb_body %}
+ {{ block.super }}
+ <li><a href="#">Users</a></li>
+{% endblock %}
+
+{% block content_body %}
+ {{ block.super }}
+ {% include 'modal/user_details.html' %}
+ {% include 'modal/user_create.html' %}
+ {% csrf_token %}
+ <div class="row">
+ <div class="col-md-12">
+
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title">Users</h3>
+ <div class="box-tools">
+ <button type="button" class="btn btn-default" data-container="body"
+ onclick="javascript:openModalCreateUser({'projects_list_url': '{% url "projects:projects_list" %}'})"
+ data-toggle="tooltip" data-placement="top" title="New User">
+
+ <i class="fa fa-plus"></i> Create User</button>
+
+ </div>
+ </div>
+ <div class="box-body">
+ <table id="users_table" class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Projects</th>
+ <th>Identifier</th>
+ <th>Modified</th>
+ <th>Created</th>
+ <th>Actions</th>
+
+ </tr>
+ </thead>
+ <tbody>
+ {% for s in users %}
+ <tr>
+
+ <td>{{ s|get:"username" }}</td>
+ <td>{{ s|get:"projects" }}</td>
+ <td>{{ s|get:"_id" }}</td>
+ <td>{{ s|get_sub:"_admin,modified"|get_date}}</td>
+ <td>{{ s|get_sub:"_admin,created"|get_date}}</td>
+
+ <td>
+ <div class="btn-group">
+
+ <button type="button" class="btn btn-default"
+ onclick="javascript:deleteUser('{% url "users:delete" user_id=s|get:"_id" %}')" data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i
+ class="far fa-trash-alt" ></i></button>
+ </div>
+ </td>
+
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ </div>
+{% endblock %}
+
+{% block resource_block %}
+ {{ block.super }}
+ <!-- moment JS -->
+ <script src="/static/bower_components/select2/dist/js/select2.js"></script>
+ <script src="/static/src/userhandler/user_list.js"></script>
+
+
+{% endblock %}
+
+{% block footer %}
+ {% include "footer.html" %}
+{% endblock %}
\ No newline at end of file
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+#
+# 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<user_id>[0-9a-zA-Z]+)/delete$', views.delete, name='delete'),
+
+]
\ No newline at end of file
--- /dev/null
+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)