added admin against SPs and avatars on api
parent
7edd696d9a
commit
e482c77bff
|
@ -12,7 +12,7 @@ COPY admin/docker/requirements.pip3 /requirements.pip3
|
||||||
RUN pip3 install --no-cache-dir -r requirements.pip3
|
RUN pip3 install --no-cache-dir -r requirements.pip3
|
||||||
RUN apk del .build_deps
|
RUN apk del .build_deps
|
||||||
|
|
||||||
RUN apk add curl
|
RUN apk add curl py3-yaml
|
||||||
|
|
||||||
# SSH configuration
|
# SSH configuration
|
||||||
ARG SSH_ROOT_PWD
|
ARG SSH_ROOT_PWD
|
||||||
|
|
|
@ -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...')
|
print('Starting isard-sso api...')
|
||||||
|
|
||||||
from api.lib.load_config import loadConfig
|
from admin.lib.load_config import loadConfig
|
||||||
try:
|
try:
|
||||||
loadConfig(app)
|
loadConfig(app)
|
||||||
except:
|
except:
|
||||||
print('Could not get environment variables...')
|
print('Could not get environment variables...')
|
||||||
|
|
||||||
|
from admin.lib.admin import Admin
|
||||||
|
app.admin=Admin()
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Debug should be removed on production!
|
Debug should be removed on production!
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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})
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
from api import app
|
from admin import app
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
import logging as log
|
import logging as log
|
|
@ -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
|
|
@ -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 '<d:status>HTTP/1.1 200 OK</d:status>' 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 '<s:message>The resource you tried to create already exists</s:message>' 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
|
||||||
|
|
|
@ -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
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -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/<format>', methods=['GET'])
|
||||||
|
# @app.route('/header/<format>/<application>', 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')
|
Binary file not shown.
Binary file not shown.
|
@ -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))
|
|
|
@ -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/<format>', methods=['GET'])
|
|
||||||
@app.route('/header/<format>/<application>', 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')
|
|
Binary file not shown.
|
@ -3,11 +3,8 @@
|
||||||
from gevent import monkey
|
from gevent import monkey
|
||||||
monkey.patch_all()
|
monkey.patch_all()
|
||||||
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
from api import app
|
from admin import app
|
||||||
|
|
||||||
# import pprint
|
|
||||||
# pprint.pprint(app.yaml)
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=9000, debug=False) #, logger=logger, engineio_logger=engineio_logger)
|
app.run(host='0.0.0.0', port=9000, debug=False) #, logger=logger, engineio_logger=engineio_logger)
|
||||||
|
|
|
@ -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
|
|
|
@ -29,3 +29,6 @@ new_user = keycloak_admin.create_user({"email": "example@example.com",
|
||||||
"firstName": "Example",
|
"firstName": "Example",
|
||||||
"lastName": "Example"})
|
"lastName": "Example"})
|
||||||
print(new_user)
|
print(new_user)
|
||||||
|
|
||||||
|
user_id_keycloak = keycloak_admin.get_user_id("admin")
|
||||||
|
print(user_id_keycloak)
|
|
@ -19,6 +19,7 @@ services:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- ${BUILD_ROOT_PATH}/admin/src:/admin # Revome in production
|
- ${BUILD_ROOT_PATH}/admin/src:/admin # Revome in production
|
||||||
- ${BUILD_ROOT_PATH}/custom:/admin/custom #:ro in production
|
- ${BUILD_ROOT_PATH}/custom:/admin/custom #:ro in production
|
||||||
|
- ${DATA_FOLDER}/avatars:/admin/avatars:ro
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
command: sleep infinity
|
command: sleep infinity
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 790afd2a9c70618e422b0e69ffa702f80a4ee1a6
|
Subproject commit 7a0176a6e31ced64dc32fdcc175a21601747c0f7
|
Loading…
Reference in New Issue