diff --git a/admin/docker/Dockerfile b/admin/docker/Dockerfile index d534cd7..aba1d63 100644 --- a/admin/docker/Dockerfile +++ b/admin/docker/Dockerfile @@ -12,7 +12,7 @@ COPY admin/docker/requirements.pip3 /requirements.pip3 RUN pip3 install --no-cache-dir -r requirements.pip3 RUN apk del .build_deps -RUN apk add curl +RUN apk add curl py3-yaml # SSH configuration ARG SSH_ROOT_PWD diff --git a/admin/src/api/__init__.py b/admin/src/admin/__init__.py similarity index 93% rename from admin/src/api/__init__.py rename to admin/src/admin/__init__.py index 1abe5ec..672bb99 100644 --- a/admin/src/api/__init__.py +++ b/admin/src/admin/__init__.py @@ -20,13 +20,14 @@ app.secret_key = "Change this key!//\xf7\x83\xbe\x17\xfa\xa3zT\n\\]m\xa6\x8bF\xd print('Starting isard-sso api...') -from api.lib.load_config import loadConfig +from admin.lib.load_config import loadConfig try: loadConfig(app) except: print('Could not get environment variables...') - +from admin.lib.admin import Admin +app.admin=Admin() ''' Debug should be removed on production! diff --git a/admin/src/admin/__pycache__/__init__.cpython-38.pyc b/admin/src/admin/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..8ffb775 Binary files /dev/null and b/admin/src/admin/__pycache__/__init__.cpython-38.pyc differ diff --git a/admin/src/admin/lib/__pycache__/admin.cpython-38.pyc b/admin/src/admin/lib/__pycache__/admin.cpython-38.pyc new file mode 100644 index 0000000..71cb8d5 Binary files /dev/null and b/admin/src/admin/lib/__pycache__/admin.cpython-38.pyc differ diff --git a/admin/src/admin/lib/__pycache__/keycloak.cpython-38.pyc b/admin/src/admin/lib/__pycache__/keycloak.cpython-38.pyc new file mode 100644 index 0000000..3d889a6 Binary files /dev/null and b/admin/src/admin/lib/__pycache__/keycloak.cpython-38.pyc differ diff --git a/admin/src/api/lib/__pycache__/load_config.cpython-38.pyc b/admin/src/admin/lib/__pycache__/load_config.cpython-38.pyc similarity index 62% rename from admin/src/api/lib/__pycache__/load_config.cpython-38.pyc rename to admin/src/admin/lib/__pycache__/load_config.cpython-38.pyc index 3383d33..f16472e 100644 Binary files a/admin/src/api/lib/__pycache__/load_config.cpython-38.pyc and b/admin/src/admin/lib/__pycache__/load_config.cpython-38.pyc differ diff --git a/admin/src/api/lib/__pycache__/menu.cpython-38.pyc b/admin/src/admin/lib/__pycache__/menu.cpython-38.pyc similarity index 100% rename from admin/src/api/lib/__pycache__/menu.cpython-38.pyc rename to admin/src/admin/lib/__pycache__/menu.cpython-38.pyc diff --git a/admin/src/admin/lib/__pycache__/moodle.cpython-38.pyc b/admin/src/admin/lib/__pycache__/moodle.cpython-38.pyc new file mode 100644 index 0000000..df413a4 Binary files /dev/null and b/admin/src/admin/lib/__pycache__/moodle.cpython-38.pyc differ diff --git a/admin/src/admin/lib/__pycache__/nextcloud.cpython-38.pyc b/admin/src/admin/lib/__pycache__/nextcloud.cpython-38.pyc new file mode 100644 index 0000000..86c6e38 Binary files /dev/null and b/admin/src/admin/lib/__pycache__/nextcloud.cpython-38.pyc differ diff --git a/admin/src/admin/lib/__pycache__/nextcloud_exc.cpython-38.pyc b/admin/src/admin/lib/__pycache__/nextcloud_exc.cpython-38.pyc new file mode 100644 index 0000000..52dac4f Binary files /dev/null and b/admin/src/admin/lib/__pycache__/nextcloud_exc.cpython-38.pyc differ diff --git a/admin/src/admin/lib/admin.py b/admin/src/admin/lib/admin.py new file mode 100644 index 0000000..4d902cf --- /dev/null +++ b/admin/src/admin/lib/admin.py @@ -0,0 +1,58 @@ +from .keycloak import Keycloak +from .moodle import Moodle +from .nextcloud import Nextcloud + +from pprint import pprint +class Admin(): + def __init__(self): + URL="http://isard-sso-keycloak:8080/auth/" + USERNAME='admin' + PASSWORD='keycloakkeycloak' + REALM="master" + VERIFY_CERT=True + self.keycloak=Keycloak(URL,USERNAME,PASSWORD,REALM,VERIFY_CERT) + + KEY = "a1d8b3248e1a3e3b839645503df0e3a5" + URL = "https://moodle.santantoni.duckdns.org" + ENDPOINT="/webservice/rest/server.php" + self.moodle=Moodle(KEY,URL,ENDPOINT) + + URL="https://nextcloud.santantoni.duckdns.org" + USERNAME='admin' + PASSWORD='N3xtcl0ud' + VERIFY_CERT=False + self.nextcloud=Nextcloud(URL,USERNAME,PASSWORD,VERIFY_CERT) + + pprint(self.get_moodle_users()) + pprint(self.get_keycloak_users()) + pprint(self.get_nextcloud_users()) + + def get_moodle_users(self): + users = self.moodle.get_user_by('email','%%')['users'] + return [{"id":u['id'], + "username":u['username'], + "first": u['firstname'], + "last": u['lastname'], + "email": u['email']} + for u in users] + + def get_keycloak_users(self): + users = self.keycloak.get_users() + return [{"id":u['id'], + "username":u['username'], + "first": u.get('firstName',None), + "last": u.get('lastName',None), + "email": u.get('email','')} + for u in users] + + def get_nextcloud_users(self): + users = self.nextcloud.get_users_list() + users_list=[] + for user in users: + u=self.nextcloud.get_user(user) + users_list.append({"id":u['id'], + "username":u['id'], + "first": u['displayname'], + "last": None, + "email": u['email']}) + return users_list \ No newline at end of file diff --git a/admin/src/admin/lib/keycloak.py b/admin/src/admin/lib/keycloak.py new file mode 100644 index 0000000..70e9a6e --- /dev/null +++ b/admin/src/admin/lib/keycloak.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# coding=utf-8 +import time +from admin import app as application +from datetime import datetime, timedelta +import pprint + +import logging +import traceback +import yaml, json + +from jinja2 import Environment, FileSystemLoader + +from keycloak import KeycloakAdmin + +class Keycloak(): + """https://www.keycloak.org/docs-api/13.0/rest-api/index.html + https://github.com/marcospereirampj/python-keycloak + """ + def __init__(self,url,username,password,realm,verify=True): + self.keycloak_admin = KeycloakAdmin(server_url=url, + username=username, + password=password, + realm_name=realm, + verify=verify) + + ## USERS + + def get_user_id(self,username): + return self.keycloak_admin.get_user_id(username) + + def get_users(self): + return self.keycloak_admin.get_users({}) + + def add_user(self,username,first,last,email,password): + # Returns user id + return self.keycloak_admin.create_user({"email": email, + "username": username, + "enabled": True, + "firstName": first, + "lastName": last, + "credentials":[{"type":"password", + "value":password, + "temporary":False}]}) + + def add_user_role(self,client_id,user_id,role_id,role_name): + return self.keycloak_admin.assign_client_role(client_id="client_id", user_id="user_id", role_id="role_id", role_name="test") + + def delete_user(self,userid): + return self.keycloak_admin.delete_user(user_id=userid) + + ## SYSTEM + def get_server_info(self): + return self.keycloak_admin.get_server_info() + + def get_server_clients(self): + return self.keycloak_admin.get_clients() + + ## CLIENTS + + def get_client_roles(self,client_id): + return self.keycloak_admin.get_client_roles(client_id=client_id) + + # def add_client_role(self,client_id,roleName): + # return self.keycloak_admin.create_client_role(client_id=client_id, {'name': roleName, 'clientRole': True}) diff --git a/admin/src/api/lib/load_config.py b/admin/src/admin/lib/load_config.py similarity index 93% rename from admin/src/api/lib/load_config.py rename to admin/src/admin/lib/load_config.py index a3f2640..a4de719 100644 --- a/admin/src/api/lib/load_config.py +++ b/admin/src/admin/lib/load_config.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding=utf-8 -from api import app +from admin import app import os, sys import logging as log diff --git a/admin/src/admin/lib/moodle.py b/admin/src/admin/lib/moodle.py new file mode 100644 index 0000000..9b473ec --- /dev/null +++ b/admin/src/admin/lib/moodle.py @@ -0,0 +1,73 @@ +from requests import get, post +# Module variables to connect to moodle api + +class Moodle(): + """https://github.com/mrcinv/moodle_api.py + https://docs.moodle.org/dev/Web_service_API_functions + https://docs.moodle.org/311/en/Using_web_services + """ + + def __init__(self, key, url, endpoint): + self.key = key + self.url = url + self.endpoint = endpoint + + def rest_api_parameters(self, in_args, prefix='', out_dict=None): + """Transform dictionary/array structure to a flat dictionary, with key names + defining the structure. + Example usage: + >>> rest_api_parameters({'courses':[{'id':1,'name': 'course1'}]}) + {'courses[0][id]':1, + 'courses[0][name]':'course1'} + """ + if out_dict==None: + out_dict = {} + if not type(in_args) in (list,dict): + out_dict[prefix] = in_args + return out_dict + if prefix == '': + prefix = prefix + '{0}' + else: + prefix = prefix + '[{0}]' + if type(in_args)==list: + for idx, item in enumerate(in_args): + self.rest_api_parameters(item, prefix.format(idx), out_dict) + elif type(in_args)==dict: + for key, item in in_args.items(): + self.rest_api_parameters(item, prefix.format(key), out_dict) + return out_dict + + def call(self, fname, **kwargs): + """Calls moodle API function with function name fname and keyword arguments. + Example: + >>> call_mdl_function('core_course_update_courses', + courses = [{'id': 1, 'fullname': 'My favorite course'}]) + """ + parameters = self.rest_api_parameters(kwargs) + parameters.update({"wstoken": self.key, 'moodlewsrestformat': 'json', "wsfunction": fname}) + response = post(self.url+self.endpoint, parameters, verify=False) + response = response.json() + if type(response) == dict and response.get('exception'): + raise SystemError("Error calling Moodle API\n", response) + return response + + def create_user(self, email, username, password, first_name='-', last_name='-'): + data = [{'username': username, 'email':email, + 'password': password, 'firstname':first_name, 'lastname':last_name}] + user = self.call('core_user_create_users', users=data) + return user + + def get_user_by(self, key, value): + criteria = [{'key': key, 'value': value}] + user = self.call('core_user_get_users', criteria=criteria) + return user + + def enroll_user_to_course(self, user_id, course_id, role_id=5): + # 5 is student + data = [{'roleid': role_id, 'userid': user_id, 'courseid': course_id}] + enrolment = self.call('enrol_manual_enrol_users', enrolments=data) + return enrolment + + def get_quiz_attempt(self, quiz_id, user_id): + attempts = self.call('mod_quiz_get_user_attempts', quizid=quiz_id, userid=user_id) + return attempts \ No newline at end of file diff --git a/admin/src/admin/lib/nextcloud.py b/admin/src/admin/lib/nextcloud.py new file mode 100644 index 0000000..d731f24 --- /dev/null +++ b/admin/src/admin/lib/nextcloud.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +# coding=utf-8 + +#from ..lib.log import * +import time,requests,json,pprint +import traceback +import logging as log +from .nextcloud_exc import * + +class Nextcloud(): + def __init__(self,url,username,password,verify): + self.verify_cert=verify + self.apiurl=url+'/ocs/v1.php/cloud/' + self.shareurl=url+'/ocs/v2.php/apps/files_sharing/api/v1/' + self.davurl=url+'/remote.php/dav/files/' + self.auth=(username,password) + self.user=username + + def _request(self,method,url,data={},headers={'OCS-APIRequest':'true'},auth=False): + if auth == False: auth=self.auth + try: + return requests.request(method, url, data=data, auth=auth, verify=self.verify_cert, headers=headers).text + + ## At least the ProviderSslError is not being catched or not raised correctly + except requests.exceptions.HTTPError as errh: + raise ProviderConnError + except requests.exceptions.Timeout as errt: + raise ProviderConnTimeout + except requests.exceptions.SSLError as err: + raise ProviderSslError + except requests.exceptions.ConnectionError as errc: + raise ProviderConnError + # except requests.exceptions.RequestException as err: + # raise ProviderError + except Exception as e: + if str(e) == 'an integer is required (got type bytes)': + raise ProviderConnError + raise ProviderError + + def check_connection(self): + url = self.apiurl + "users/"+self.user+"?format=json" + try: + result = self._request('GET',url) + if json.loads(result)['ocs']['meta']['statuscode'] == 100: return True + raise ProviderError + except requests.exceptions.HTTPError as errh: + raise ProviderConnError + except requests.exceptions.ConnectionError as errc: + raise ProviderConnError + except requests.exceptions.Timeout as errt: + raise ProviderConnTimeout + except requests.exceptions.SSLError as err: + raise ProviderSslError + except requests.exceptions.RequestException as err: + raise ProviderError + except Exception as e: + if str(e) == 'an integer is required (got type bytes)': + raise ProviderConnError + raise ProviderError + + def get_user(self,userid): + url = self.apiurl + "users/"+userid+"?format=json" + try: + result = json.loads(self._request('GET',url)) + if result['ocs']['meta']['statuscode'] == 100: return result['ocs']['data'] + raise ProviderItemNotExists + except: + log.error(traceback.format_exc()) + raise + # 100 - successful + + def get_users_list(self): + url = self.apiurl + "users?format=json" + try: + result = json.loads(self._request('GET',url)) + if result['ocs']['meta']['statuscode'] == 100: return result['ocs']['data']['users'] + log.error('Get Nextcloud provider users list error: '+str(result)) + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + + def add_user(self,userid,userpassword,quota,group='',email='',displayname=''): + data={'userid':userid,'password':userpassword,'quota':quota,'groups[]':group,'email':email,'displayname':displayname} + url = self.apiurl + "users?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = json.loads(self._request('POST',url,data=data,headers=headers)) + if result['ocs']['meta']['statuscode'] == 100: return True + if result['ocs']['meta']['statuscode'] == 102: raise ProviderItemExists + if result['ocs']['meta']['statuscode'] == 104: raise ProviderGroupNotExists + log.error('Get Nextcloud provider user add error: '+str(result)) + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + # 100 - successful + # 101 - invalid input data + # 102 - username already exists + # 103 - unknown error occurred whilst adding the user + # 104 - group does not exist + # 105 - insufficient privileges for group + # 106 - no group specified (required for subadmins) + # 107 - all errors that contain a hint - for example “Password is among the 1,000,000 most common ones. Please make it unique.” (this code was added in 12.0.6 & 13.0.1) + + def delete_user(self,userid): + url = self.apiurl + "users/"+userid+"?format=json" + try: + result = json.loads(self._request('DELETE',url)) + if result['ocs']['meta']['statuscode'] == 100: return True + if result['ocs']['meta']['statuscode'] == 101: raise ProviderUserNotExists + log.error(traceback.format_exc()) + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + # 100 - successful + # 101 - failure + + def enable_user(self,userid): + None + + def disable_user(self,userid): + None + + def exists_user_folder(self,userid,userpassword,folder='IsardVDI'): + auth=(userid,userpassword) + url = self.davurl + userid +"/" + folder+"?format=json" + headers = { + 'Depth': '0', + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = self._request('PROPFIND',url,auth=auth,headers=headers) + if 'HTTP/1.1 200 OK' in result: return True + return False + except: + log.error(traceback.format_exc()) + raise + + def add_user_folder(self,userid,userpassword,folder='IsardVDI'): + auth=(userid,userpassword) + url = self.davurl + userid +"/" + folder+"?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = self._request('MKCOL',url,auth=auth,headers=headers) + if result=='': return True + if 'The resource you tried to create already exists' in result: raise ProviderItemExists + log.error(result.split('message>')[1].split('<')[0]) + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + + def exists_user_share_folder(self,userid,userpassword,folder='IsardVDI'): + auth=(userid,userpassword) + url = self.shareurl + "shares?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = json.loads(self._request('GET', url, auth=auth, headers=headers)) + if result['ocs']['meta']['statuscode']==200: + share=[s for s in result['ocs']['data'] if s['path'] == '/'+folder] + if len(share) >= 1: + # Should we delete all but the first (0) one? + return {'token': share[0]['token'], + 'url': share[0]['url']} + raise ProviderItemNotExists + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + + def add_user_share_folder(self,userid,userpassword,folder='IsardVDI'): + auth=(userid,userpassword) + data={'path':'/'+folder,'shareType':3} + url = self.shareurl + "shares?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = json.loads(self._request('POST',url, data=data, auth=auth, headers=headers)) + if result['ocs']['meta']['statuscode'] == 100 or result['ocs']['meta']['statuscode'] == 200: + return {'token': result['ocs']['data']['token'], + 'url': result['ocs']['data']['url']} + log.error('Add user share folder error: '+result['ocs']['meta']['message']) + raise ProviderFolderNotExists + except: + log.error(traceback.format_exc()) + raise + + def get_group(self,userid): + None + + def get_groups_list(self): + url = self.apiurl + "groups?format=json" + try: + result = json.loads(self._request('GET',url)) + if result['ocs']['meta']['statuscode'] == 100: return [g for g in result['ocs']['data']['groups'] if '-' in g] + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + + def add_group(self,groupid): + data={'groupid':groupid} + url = self.apiurl + "groups?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = json.loads(self._request('POST',url, data=data, auth=self.auth, headers=headers)) + if result['ocs']['meta']['statuscode'] == 100: return True + if result['ocs']['meta']['statuscode'] == 102: raise ProviderItemExists + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + # 100 - successful + # 101 - invalid input data + # 102 - group already exists + # 103 - failed to add the group + + def delete_group(self,groupid): + url = self.apiurl + "groups/"+groupid+"?format=json" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'OCS-APIRequest': 'true', + } + try: + result = json.loads(self._request('DELETE',url, auth=self.auth, headers=headers)) + if result['ocs']['meta']['statuscode'] == 100: return True + log.error(traceback.format_exc()) + raise ProviderOpError + except: + log.error(traceback.format_exc()) + raise + # 100 - successful + # 101 - invalid input data + # 102 - group already exists + # 103 - failed to add the group + diff --git a/admin/src/admin/lib/nextcloud_exc.py b/admin/src/admin/lib/nextcloud_exc.py new file mode 100644 index 0000000..32baf33 --- /dev/null +++ b/admin/src/admin/lib/nextcloud_exc.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# coding=utf-8 +class ProviderConnError(Exception): + pass + +class ProviderSslError(Exception): + pass + +class ProviderConnTimeout(Exception): + pass + +class ProviderError(Exception): + pass + +class ProviderItemExists(Exception): + pass + +class ProviderItemNotExists(Exception): + pass + +class ProviderGroupNotExists(Exception): + pass + +class ProviderFolderNotExists(Exception): + pass + + +class ProviderOpError(Exception): + pass diff --git a/admin/src/api/static/_templates/apps.html b/admin/src/admin/static/_templates/apps.html similarity index 100% rename from admin/src/api/static/_templates/apps.html rename to admin/src/admin/static/_templates/apps.html diff --git a/admin/src/api/static/_templates/navbar_nextcloud.html b/admin/src/admin/static/_templates/navbar_nextcloud.html similarity index 100% rename from admin/src/api/static/_templates/navbar_nextcloud.html rename to admin/src/admin/static/_templates/navbar_nextcloud.html diff --git a/admin/src/api/static/_templates/nextcloud.html b/admin/src/admin/static/_templates/nextcloud.html similarity index 100% rename from admin/src/api/static/_templates/nextcloud.html rename to admin/src/admin/static/_templates/nextcloud.html diff --git a/admin/src/api/static/css/bootstrap.min.css b/admin/src/admin/static/css/bootstrap.min.css similarity index 100% rename from admin/src/api/static/css/bootstrap.min.css rename to admin/src/admin/static/css/bootstrap.min.css diff --git a/admin/src/api/static/css/dd.css b/admin/src/admin/static/css/dd.css similarity index 100% rename from admin/src/api/static/css/dd.css rename to admin/src/admin/static/css/dd.css diff --git a/admin/src/api/static/img/background.png b/admin/src/admin/static/img/background.png similarity index 100% rename from admin/src/api/static/img/background.png rename to admin/src/admin/static/img/background.png diff --git a/admin/src/api/static/img/logo.png b/admin/src/admin/static/img/logo.png similarity index 100% rename from admin/src/api/static/img/logo.png rename to admin/src/admin/static/img/logo.png diff --git a/admin/src/api/static/js/navbar.js b/admin/src/admin/static/js/navbar.js similarity index 100% rename from admin/src/api/static/js/navbar.js rename to admin/src/admin/static/js/navbar.js diff --git a/admin/src/api/static/templates/.gitkeep b/admin/src/admin/static/templates/.gitkeep similarity index 100% rename from admin/src/api/static/templates/.gitkeep rename to admin/src/admin/static/templates/.gitkeep diff --git a/admin/src/api/static/templates/header.html b/admin/src/admin/static/templates/header.html similarity index 100% rename from admin/src/api/static/templates/header.html rename to admin/src/admin/static/templates/header.html diff --git a/admin/src/api/static/templates/header.json b/admin/src/admin/static/templates/header.json similarity index 100% rename from admin/src/api/static/templates/header.json rename to admin/src/admin/static/templates/header.json diff --git a/admin/src/api/static/templates/header_nextcloud.html b/admin/src/admin/static/templates/header_nextcloud.html similarity index 100% rename from admin/src/api/static/templates/header_nextcloud.html rename to admin/src/admin/static/templates/header_nextcloud.html diff --git a/admin/src/admin/views/MenuViews.py b/admin/src/admin/views/MenuViews.py new file mode 100644 index 0000000..b858891 --- /dev/null +++ b/admin/src/admin/views/MenuViews.py @@ -0,0 +1,28 @@ +#!flask/bin/python +# coding=utf-8 +from admin import app +import logging as log +import traceback + +from uuid import uuid4 +import time,json +import sys,os +from flask import render_template, Response, request, redirect, url_for, jsonify + +# from ..lib.admin import Admin +# menu = Menu() + +# @app.route('/header/', methods=['GET']) +# @app.route('/header//', methods=['GET']) +# def api_v2_header(format,application=False): +# if application == False: +# if format == 'json': +# if application == False: +# return json.dumps(menu.get_header()), 200, {'Content-Type': 'application/json'} +# if format == 'html': +# if application == False: +# return render_template('header.html') +# if application == 'nextcloud': +# return render_template('header_nextcloud.html') +# if application == 'wordpress': +# return render_template('header_wordpress.html') \ No newline at end of file diff --git a/admin/src/api/views/__init__.py b/admin/src/admin/views/__init__.py similarity index 100% rename from admin/src/api/views/__init__.py rename to admin/src/admin/views/__init__.py diff --git a/admin/src/admin/views/__pycache__/MenuViews.cpython-38.pyc b/admin/src/admin/views/__pycache__/MenuViews.cpython-38.pyc new file mode 100644 index 0000000..c2a7a3e Binary files /dev/null and b/admin/src/admin/views/__pycache__/MenuViews.cpython-38.pyc differ diff --git a/admin/src/api/views/__pycache__/__init__.cpython-38.pyc b/admin/src/admin/views/__pycache__/__init__.cpython-38.pyc similarity index 100% rename from admin/src/api/views/__pycache__/__init__.cpython-38.pyc rename to admin/src/admin/views/__pycache__/__init__.cpython-38.pyc diff --git a/admin/src/api/__pycache__/__init__.cpython-38.pyc b/admin/src/api/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 82ea2c5..0000000 Binary files a/admin/src/api/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/admin/src/api/lib/menu.py b/admin/src/api/lib/menu.py deleted file mode 100644 index b55c2f3..0000000 --- a/admin/src/api/lib/menu.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -# Copyright 2017 the Isard-vdi project authors: -# Josep Maria Viñolas Auquer -# Alberto Larraz Dalmases -# License: AGPLv3 -import time -from api import app as application -from datetime import datetime, timedelta -import pprint - -import logging -import traceback -import yaml, json - -from jinja2 import Environment, FileSystemLoader - -class Menu(): - def __init__(self): - self.menudict=self.gen_header() - pprint.pprint(self.menudict) - self.write_headers() - None - - def gen_header(self): - with open(r'system.yaml') as yml: - system=yaml.load(yml, Loader=yaml.FullLoader) - apps_internal = [] - for app in system['apps_internal']: - app['href']='https://'+app['subdomain']+'.'+application.config['DOMAIN']+app['href'] - del app['subdomain'] - apps_internal.append(app) - - with open(r'custom.yaml') as yml: - custom=yaml.load(yml, Loader=yaml.FullLoader) - custom['background_login']='https://api.'+application.config['DOMAIN']+custom['background_login'] - custom['logo']='https://api.'+application.config['DOMAIN']+custom['logo'] - - menudict={**custom,**{'apps_internal':apps_internal}} - menudict['user']={} - menudict['user']['account']='https://sso.'+application.config['DOMAIN']+system['user']['account'] - menudict['user']['avatar']='https://sso.'+application.config['DOMAIN']+system['user']['avatar'] - menudict['user']['password']='https://sso.'+application.config['DOMAIN']+system['user']['password'] - return menudict - - def write_headers(self): - env = Environment(loader=FileSystemLoader('api/static/_templates')) - template = env.get_template('apps.html') - output_from_parsed_template = template.render(data=self.menudict) - print(output_from_parsed_template) - with open("api/static/templates/header.html", "w") as fh: - fh.write(output_from_parsed_template) - - with open("api/static/templates/header_nextcloud.html", "w") as fh: - fh.write(output_from_parsed_template) - with open("api/static/templates/header_nextcloud.html", "a") as fh: - with open("api/static/_templates/nextcloud.html", "r") as nextcloud: - fh.write(nextcloud.read()) - with open("api/static/templates/header.json", "w") as fh: - fh.write(json.dumps(self.menudict)) - - def get_header(self): - return self.menudict - # with open('menu.yaml', 'w') as yml: - # print(yaml.dump(header, yml, allow_unicode=True)) \ No newline at end of file diff --git a/admin/src/api/views/MenuViews.py b/admin/src/api/views/MenuViews.py deleted file mode 100644 index 40efc3c..0000000 --- a/admin/src/api/views/MenuViews.py +++ /dev/null @@ -1,28 +0,0 @@ -#!flask/bin/python -# coding=utf-8 -from api import app -import logging as log -import traceback - -from uuid import uuid4 -import time,json -import sys,os -from flask import render_template, Response, request, redirect, url_for, jsonify - -from ..lib.menu import Menu -menu = Menu() - -@app.route('/header/', methods=['GET']) -@app.route('/header//', methods=['GET']) -def api_v2_header(format,application=False): - if application == False: - if format == 'json': - if application == False: - return json.dumps(menu.get_header()), 200, {'Content-Type': 'application/json'} - if format == 'html': - if application == False: - return render_template('header.html') - if application == 'nextcloud': - return render_template('header_nextcloud.html') - if application == 'wordpress': - return render_template('header_wordpress.html') \ No newline at end of file diff --git a/admin/src/api/views/__pycache__/MenuViews.cpython-38.pyc b/admin/src/api/views/__pycache__/MenuViews.cpython-38.pyc deleted file mode 100644 index 5e86e46..0000000 Binary files a/admin/src/api/views/__pycache__/MenuViews.cpython-38.pyc and /dev/null differ diff --git a/admin/src/start.py b/admin/src/start.py index 2a09cf8..c754f13 100644 --- a/admin/src/start.py +++ b/admin/src/start.py @@ -3,11 +3,8 @@ from gevent import monkey monkey.patch_all() -import yaml -from api import app +from admin import app -# import pprint -# pprint.pprint(app.yaml) if __name__ == '__main__': app.run(host='0.0.0.0', port=9000, debug=False) #, logger=logger, engineio_logger=engineio_logger) diff --git a/admin/src/system.yaml.example b/admin/src/system.yaml.example deleted file mode 100644 index 226fd04..0000000 --- a/admin/src/system.yaml.example +++ /dev/null @@ -1,55 +0,0 @@ -apps_internal: -- subdomain: nextcloud - href: / - icon: fa fa-cloud - name: Núvol + crear arxius - shortname: cloud -- subdomain: nextcloud - href: /apps/mail/setup - icon: fa fa-envelope-o - name: Correu - shortname: email -- subdomain: pad - href: / - icon: fa fa-file-text-o - name: Pads - shortname: pads -- subdomain: nextcloud - href: /apps/forms - icon: fa fa-check-square-o - name: Formularis - shortname: forms -- subdomain: nextcloud - href: /apps/polls - icon: fa fa-bar-chart - name: Enquestes - shortname: feedback -- subdomain: nextcloud - href: /apps/spreed - icon: fa fa-commenting-o - name: Xat - shortname: chat -- subdomain: nextcloud - href: /apps/calendar - icon: fa fa-calendar - name: Calendari - shortname: schedule -- subdomain: wp - href: /wp-login.php?saml_sso - icon: fa fa-rss - name: Webs - shortname: webs -- subdomain: nextcloud - href: /apps/bbb - icon: fa fa-video-camera - name: Reunions BBB - shortname: meets_bbb -- subdomain: nextcloud - href: /apps/photos - icon: fa fa-file-image-o - name: Fotos - shortname: photos -user: - account: /auth/realms/master/account - avatar: /auth/realms/master/avatar-provider - password: /auth/realms/master/password diff --git a/admin/src/tests/test_lib.py b/admin/src/tests/test_lib.py index cf52403..57cef0d 100644 --- a/admin/src/tests/test_lib.py +++ b/admin/src/tests/test_lib.py @@ -28,4 +28,7 @@ new_user = keycloak_admin.create_user({"email": "example@example.com", "enabled": True, "firstName": "Example", "lastName": "Example"}) -print(new_user) \ No newline at end of file +print(new_user) + +user_id_keycloak = keycloak_admin.get_user_id("admin") +print(user_id_keycloak) \ No newline at end of file diff --git a/docker-compose-parts/admin.yml b/docker-compose-parts/admin.yml index 4b16cfe..6ff59d8 100644 --- a/docker-compose-parts/admin.yml +++ b/docker-compose-parts/admin.yml @@ -19,6 +19,7 @@ services: - /etc/localtime:/etc/localtime:ro - ${BUILD_ROOT_PATH}/admin/src:/admin # Revome in production - ${BUILD_ROOT_PATH}/custom:/admin/custom #:ro in production + - ${DATA_FOLDER}/avatars:/admin/avatars:ro env_file: - .env command: sleep infinity diff --git a/isard-sso b/isard-sso index 790afd2..7a0176a 160000 --- a/isard-sso +++ b/isard-sso @@ -1 +1 @@ -Subproject commit 790afd2a9c70618e422b0e69ffa702f80a4ee1a6 +Subproject commit 7a0176a6e31ced64dc32fdcc175a21601747c0f7