parent child groups
parent
defd0b51fe
commit
c02ef731af
|
@ -16,4 +16,11 @@ zope.event==4.4
|
||||||
zope.interface==5.1.0
|
zope.interface==5.1.0
|
||||||
psycopg2==2.8.6
|
psycopg2==2.8.6
|
||||||
Flask-SocketIO==2.8.6
|
Flask-SocketIO==2.8.6
|
||||||
mysql-connector-python==8.0.25
|
mysql-connector-python==8.0.25
|
||||||
|
|
||||||
|
|
||||||
|
#Flask-SocketIO==2.8.6
|
||||||
|
#gevent==1.4.0
|
||||||
|
#greenlet==0.4.15
|
||||||
|
python-engineio==3.8.1
|
||||||
|
python-socketio==4.1.0
|
|
@ -32,6 +32,8 @@ Postup()
|
||||||
from admin.lib.admin import Admin
|
from admin.lib.admin import Admin
|
||||||
app.admin=Admin()
|
app.admin=Admin()
|
||||||
|
|
||||||
|
app.ready=False
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Debug should be removed on production!
|
Debug should be removed on production!
|
||||||
'''
|
'''
|
||||||
|
@ -84,3 +86,4 @@ from .views import AvatarViews
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,19 @@ class Admin():
|
||||||
sleep(2)
|
sleep(2)
|
||||||
log.warning('Keycloak connected.')
|
log.warning('Keycloak connected.')
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# self.keycloak.add_group('parent1')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# try:
|
||||||
|
# self.keycloak.add_group('child1','/parent1')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# try:
|
||||||
|
# self.keycloak.add_group('child2','/parent1')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
|
||||||
ready=False
|
ready=False
|
||||||
while not ready:
|
while not ready:
|
||||||
try:
|
try:
|
||||||
|
@ -306,6 +319,7 @@ class Admin():
|
||||||
theuser={**moodle_exists[0], **theuser}
|
theuser={**moodle_exists[0], **theuser}
|
||||||
theuser['moodle']=True
|
theuser['moodle']=True
|
||||||
theuser['moodle_groups']=moodle_exists[0]['groups']
|
theuser['moodle_groups']=moodle_exists[0]['groups']
|
||||||
|
theuser['moodle_id']=moodle_exists[0]['id']
|
||||||
else:
|
else:
|
||||||
theuser['moodle']=False
|
theuser['moodle']=False
|
||||||
theuser['moodle_groups']=[]
|
theuser['moodle_groups']=[]
|
||||||
|
@ -315,6 +329,7 @@ class Admin():
|
||||||
theuser={**nextcloud_exists[0], **theuser}
|
theuser={**nextcloud_exists[0], **theuser}
|
||||||
theuser['nextcloud']=True
|
theuser['nextcloud']=True
|
||||||
theuser['nextcloud_groups']=nextcloud_exists[0]['groups']
|
theuser['nextcloud_groups']=nextcloud_exists[0]['groups']
|
||||||
|
theuser['nextcloud_id']=nextcloud_exists[0]['id']
|
||||||
else:
|
else:
|
||||||
theuser['nextcloud']=False
|
theuser['nextcloud']=False
|
||||||
theuser['nextcloud_groups']=[]
|
theuser['nextcloud_groups']=[]
|
||||||
|
@ -406,15 +421,18 @@ class Admin():
|
||||||
for g in data['data']['groups']:
|
for g in data['data']['groups']:
|
||||||
# for m in data['data']['d_members']:
|
# for m in data['data']['d_members']:
|
||||||
|
|
||||||
groups.append({'provider':data['provider'],
|
# data['provider']
|
||||||
|
groups.append({'provider':'external',
|
||||||
"id": g['id'],
|
"id": g['id'],
|
||||||
|
"mailid": g['email'].split('@')[0],
|
||||||
"name": g['name'],
|
"name": g['name'],
|
||||||
"description": g['description']})
|
"description": g['description']})
|
||||||
self.external['groups']=groups
|
self.external['groups']=groups
|
||||||
|
|
||||||
users=[]
|
users=[]
|
||||||
for u in data['data']['users']:
|
for u in data['data']['users']:
|
||||||
users.append({'provider':data['provider'],
|
# data['provider']
|
||||||
|
users.append({'provider':'external',
|
||||||
'id':u['id'],
|
'id':u['id'],
|
||||||
'email': u['primaryEmail'],
|
'email': u['primaryEmail'],
|
||||||
'first': u['name']['givenName'],
|
'first': u['name']['givenName'],
|
||||||
|
@ -424,6 +442,12 @@ class Admin():
|
||||||
'roles':[]})
|
'roles':[]})
|
||||||
self.external['users']=users
|
self.external['users']=users
|
||||||
|
|
||||||
|
## Add groups to users (now they only have their orgUnitPath)
|
||||||
|
for g in self.external['groups']:
|
||||||
|
for useringroup in data['data']['d_members'][g['mailid']]:
|
||||||
|
for u in self.external['users']:
|
||||||
|
if u['id'] == useringroup['id']:
|
||||||
|
u['groups']=u['groups']+[g['name']]
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def sync_external(self):
|
def sync_external(self):
|
||||||
|
@ -468,7 +492,41 @@ class Admin():
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
log.warning('Could not remove user: '+u['username'])
|
log.warning('Could not remove user: '+u['username'])
|
||||||
|
|
||||||
def delete_keycloak_groups(self):
|
def delete_nextcloud_users(self):
|
||||||
|
for u in self.internal['users']:
|
||||||
|
if u['nextcloud'] and not u['keycloak']:
|
||||||
|
if u['roles'] and 'admin' in u['roles']: continue
|
||||||
|
log.info('Removing nextcloud user: '+u['username'])
|
||||||
|
try:
|
||||||
|
self.nextcloud.delete_user(u['nextcloud_id'])
|
||||||
|
socketio.emit('update',
|
||||||
|
json.dumps({'status':True,'item':'user','action':'delete','itemdata':u}),
|
||||||
|
namespace='/isard-sso-admin/sio',
|
||||||
|
room='admin')
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
log.warning('Could not remove user: '+u['username'])
|
||||||
|
|
||||||
|
def delete_moodle_users(self):
|
||||||
|
userids=[]
|
||||||
|
usernames=[]
|
||||||
|
for u in self.internal['users']:
|
||||||
|
if u['moodle'] and not u['keycloak']:
|
||||||
|
userids.append(u['moodle_id'])
|
||||||
|
usernames.append(u['username'])
|
||||||
|
|
||||||
|
log.warning('Removing moodle users: '+','.join(usernames))
|
||||||
|
try:
|
||||||
|
self.moodle.delete_users(userids)
|
||||||
|
socketio.emit('update',
|
||||||
|
json.dumps({'status':True,'item':'user','action':'delete','itemdata':u}),
|
||||||
|
namespace='/isard-sso-admin/sio',
|
||||||
|
room='admin')
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
log.warning('Could not remove users: '+','.join(usernames))
|
||||||
|
|
||||||
|
def delete_moodle_groups(self):
|
||||||
for g in self.internal['groups']:
|
for g in self.internal['groups']:
|
||||||
if not g['keycloak']: continue
|
if not g['keycloak']: continue
|
||||||
# Do not remove admin group. It should not exist in keycloak, only in nextcloud
|
# Do not remove admin group. It should not exist in keycloak, only in nextcloud
|
||||||
|
@ -478,4 +536,11 @@ class Admin():
|
||||||
self.keycloak.delete_group(g['id'])
|
self.keycloak.delete_group(g['id'])
|
||||||
except:
|
except:
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
log.warning('Could not remove group: '+g['name'])
|
log.warning('Could not remove group: '+g['name'])
|
||||||
|
|
||||||
|
def external_roleassign(self,data):
|
||||||
|
for newuserid in data['ids']:
|
||||||
|
for externaluser in self.external['users']:
|
||||||
|
if externaluser['id'] == newuserid:
|
||||||
|
externaluser['roles']=[data['action']]
|
||||||
|
return True
|
|
@ -164,6 +164,10 @@ class KeycloakClient():
|
||||||
|
|
||||||
def add_group(self,name,parent=None):
|
def add_group(self,name,parent=None):
|
||||||
self.connect()
|
self.connect()
|
||||||
|
if parent is not None: parent=self.get_group(parent)['id']
|
||||||
|
print(name)
|
||||||
|
print(parent)
|
||||||
|
print('DONE')
|
||||||
return self.keycloak_admin.create_group({"name":name}, parent=parent)
|
return self.keycloak_admin.create_group({"name":name}, parent=parent)
|
||||||
|
|
||||||
def delete_group(self,group_id):
|
def delete_group(self,group_id):
|
||||||
|
|
|
@ -2,7 +2,7 @@ from requests import get, post
|
||||||
from admin import app
|
from admin import app
|
||||||
|
|
||||||
import logging as log
|
import logging as log
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
from .postgres import Postgres
|
from .postgres import Postgres
|
||||||
|
|
||||||
|
@ -72,6 +72,14 @@ class Moodle():
|
||||||
user = self.call('core_user_create_users', users=data)
|
user = self.call('core_user_create_users', users=data)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
def delete_user(self, user_id):
|
||||||
|
user = self.call('core_user_delete_users', userids=[user_id])
|
||||||
|
return user
|
||||||
|
|
||||||
|
def delete_users(self, userids):
|
||||||
|
user = self.call('core_user_delete_users', userids=userids)
|
||||||
|
return user
|
||||||
|
|
||||||
def get_user_by(self, key, value):
|
def get_user_by(self, key, value):
|
||||||
criteria = [{'key': key, 'value': value}]
|
criteria = [{'key': key, 'value': value}]
|
||||||
user = self.call('core_user_get_users', criteria=criteria)
|
user = self.call('core_user_get_users', criteria=criteria)
|
||||||
|
|
|
@ -128,7 +128,7 @@ class Nextcloud():
|
||||||
|
|
||||||
def add_user(self,userid,userpassword,quota=False,group=False,email='',displayname=''):
|
def add_user(self,userid,userpassword,quota=False,group=False,email='',displayname=''):
|
||||||
data={'userid':userid,'password':userpassword,'quota':quota,'groups[]':group,'email':email,'displayname':displayname}
|
data={'userid':userid,'password':userpassword,'quota':quota,'groups[]':group,'email':email,'displayname':displayname}
|
||||||
if not group: del data['group']
|
if not group: del data['groups[]']
|
||||||
if not quota: del data['quota']
|
if not quota: del data['quota']
|
||||||
# if group:
|
# if group:
|
||||||
# data={'userid':userid,'password':userpassword,'quota':quota,'groups[]':group,'email':email,'displayname':displayname}
|
# data={'userid':userid,'password':userpassword,'quota':quota,'groups[]':group,'email':email,'displayname':displayname}
|
||||||
|
|
|
@ -54,6 +54,60 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#action_role').on('change', function () {
|
||||||
|
action=$(this).val();
|
||||||
|
names=''
|
||||||
|
ids=[]
|
||||||
|
|
||||||
|
if(users_table.rows('.active').data().length){
|
||||||
|
$.each(users_table.rows('.active').data(),function(key, value){
|
||||||
|
names+=value['name']+'\n';
|
||||||
|
ids.push(value['id']);
|
||||||
|
});
|
||||||
|
var text = "You are about to assign role "+action+" these users:\n\n "+names
|
||||||
|
}else{
|
||||||
|
$.each(users_table.rows({filter: 'applied'}).data(),function(key, value){
|
||||||
|
ids.push(value['id']);
|
||||||
|
});
|
||||||
|
var text = "You are about to assign role "+action+" "+users_table.rows({filter: 'applied'}).data().length+" users!\n All the users in list!"
|
||||||
|
}
|
||||||
|
new PNotify({
|
||||||
|
title: 'Role assignment!',
|
||||||
|
text: 'You will asign the role '+action,
|
||||||
|
hide: false,
|
||||||
|
opacity: 0.9,
|
||||||
|
confirm: {
|
||||||
|
confirm: true
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
closer: false,
|
||||||
|
sticker: false
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
history: false
|
||||||
|
},
|
||||||
|
addclass: 'pnotify-center'
|
||||||
|
}).get().on('pnotify.confirm', function() {
|
||||||
|
$.ajax({
|
||||||
|
type: "PUT",
|
||||||
|
url:"/isard-sso-admin/external/roles",
|
||||||
|
data: JSON.stringify({'ids':ids,'action':action}),
|
||||||
|
success: function(data)
|
||||||
|
{
|
||||||
|
console.log('SUCCESS')
|
||||||
|
users_table.ajax.reload();
|
||||||
|
groups_table.ajax.reload();
|
||||||
|
},
|
||||||
|
error: function(data)
|
||||||
|
{
|
||||||
|
alert('Something went wrong on our side...')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).on('pnotify.cancel', function() {
|
||||||
|
$('#action_role option[value="none"]').prop("selected",true);
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
|
||||||
//DataTable Main renderer
|
//DataTable Main renderer
|
||||||
var users_table = $('#users').DataTable({
|
var users_table = $('#users').DataTable({
|
||||||
"ajax": {
|
"ajax": {
|
||||||
|
@ -74,8 +128,8 @@ $(document).ready(function() {
|
||||||
"width": "10px",
|
"width": "10px",
|
||||||
"defaultContent": '<button class="btn btn-xs btn-info" type="button" data-placement="top" ><i class="fa fa-plus"></i></button>'
|
"defaultContent": '<button class="btn btn-xs btn-info" type="button" data-placement="top" ><i class="fa fa-plus"></i></button>'
|
||||||
},
|
},
|
||||||
{ "data": "provider", "width": "10px" },
|
// { "data": "provider", "width": "10px" },
|
||||||
{ "data": "id", "width": "10px" },
|
// { "data": "id", "width": "10px" },
|
||||||
{ "data": "username", "width": "10px"},
|
{ "data": "username", "width": "10px"},
|
||||||
{ "data": "first", "width": "10px"},
|
{ "data": "first", "width": "10px"},
|
||||||
{ "data": "last", "width": "10px"},
|
{ "data": "last", "width": "10px"},
|
||||||
|
@ -84,9 +138,15 @@ $(document).ready(function() {
|
||||||
{ "data": "roles", "width": "10px"},
|
{ "data": "roles", "width": "10px"},
|
||||||
],
|
],
|
||||||
"order": [[3, 'asc']],
|
"order": [[3, 'asc']],
|
||||||
"columnDefs": [ ]
|
"columnDefs": [ {
|
||||||
|
"targets": 5,
|
||||||
|
"render": function ( data, type, full, meta ) {
|
||||||
|
return "<li>" + full.groups.join("</li><li>") + "</li>"
|
||||||
|
}}
|
||||||
|
]
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
||||||
var groups_table = $('#groups').DataTable({
|
var groups_table = $('#groups').DataTable({
|
||||||
"ajax": {
|
"ajax": {
|
||||||
"url": "/isard-sso-admin/external_groups_list",
|
"url": "/isard-sso-admin/external_groups_list",
|
||||||
|
@ -106,8 +166,8 @@ $(document).ready(function() {
|
||||||
"width": "10px",
|
"width": "10px",
|
||||||
"defaultContent": '<button class="btn btn-xs btn-info" type="button" data-placement="top" ><i class="fa fa-plus"></i></button>'
|
"defaultContent": '<button class="btn btn-xs btn-info" type="button" data-placement="top" ><i class="fa fa-plus"></i></button>'
|
||||||
},
|
},
|
||||||
{ "data": "id", "width": "10px" },
|
// { "data": "id", "width": "10px" },
|
||||||
{ "data": "provider", "width": "10px" },
|
// { "data": "provider", "width": "10px" },
|
||||||
{ "data": "name", "width": "10px" },
|
{ "data": "name", "width": "10px" },
|
||||||
{ "data": "description", "width": "10px"},
|
{ "data": "description", "width": "10px"},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// SocketIO
|
// SocketIO
|
||||||
socket = io.connect(location.protocol+'//' + document.domain + ':' + location.port+'/isard-sso-admin/sio');
|
socket = io.connect(location.protocol+'//' + document.domain +'/isard-sso-admin/sio');
|
||||||
|
console.log(location.protocol+'//' + document.domain +'/isard-sso-admin/sio')
|
||||||
socket.on('connect', function() {
|
socket.on('connect', function() {
|
||||||
connection_done();
|
// connection_done();
|
||||||
console.log('Listening status socket');
|
console.log('Listening status socket');
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('connect_error', function(data) {
|
socket.on('connect_error', function(data) {
|
||||||
connection_lost();
|
// connection_lost();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('update', function(data) {
|
socket.on('update', function(data) {
|
||||||
|
|
|
@ -112,6 +112,41 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.btn-delete_nextcloud').on('click', function () {
|
||||||
|
$.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url:"/isard-sso-admin/users/nextcloud",
|
||||||
|
success: function(data)
|
||||||
|
{
|
||||||
|
console.log('SUCCESS')
|
||||||
|
// $("#modalImport").modal('hide');
|
||||||
|
// users_table.ajax.reload();
|
||||||
|
// groups_table.ajax.reload();
|
||||||
|
},
|
||||||
|
error: function(data)
|
||||||
|
{
|
||||||
|
alert('Something went wrong on our side...')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn-delete_moodle').on('click', function () {
|
||||||
|
$.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url:"/isard-sso-admin/users/moodle",
|
||||||
|
success: function(data)
|
||||||
|
{
|
||||||
|
console.log('SUCCESS')
|
||||||
|
// $("#modalImport").modal('hide');
|
||||||
|
// users_table.ajax.reload();
|
||||||
|
// groups_table.ajax.reload();
|
||||||
|
},
|
||||||
|
error: function(data)
|
||||||
|
{
|
||||||
|
alert('Something went wrong on our side...')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
$('.btn-sync_to_moodle').on('click', function () {
|
$('.btn-sync_to_moodle').on('click', function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
|
@ -14,6 +14,19 @@
|
||||||
<div class="x_title">
|
<div class="x_title">
|
||||||
<h3><i class="fa fa-desktop"></i> External</h3>
|
<h3><i class="fa fa-desktop"></i> External</h3>
|
||||||
<ul class="nav navbar-right panel_toolbox">
|
<ul class="nav navbar-right panel_toolbox">
|
||||||
|
<li>
|
||||||
|
<div class="item form-group">
|
||||||
|
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="action_role">Assign role: <span class="required">*</span></label>
|
||||||
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
|
<select id="action_role" name="action_role" class="form-control action" required>
|
||||||
|
<option value=''>Select role</option>
|
||||||
|
<option value='manager'>Manager</option>
|
||||||
|
<option value='teacher'>Teacher</option>
|
||||||
|
<option value='student'>Student</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="btn-sync"><span style="color: #5499c7; "><i class="fa fa-rocket"></i> Sync to system</span></a>
|
<a class="btn-sync"><span style="color: #5499c7; "><i class="fa fa-rocket"></i> Sync to system</span></a>
|
||||||
<a class="btn-upload"><span style="color: #5499c7; "><i class="fa fa-upload"></i> Upload</span></a>
|
<a class="btn-upload"><span style="color: #5499c7; "><i class="fa fa-upload"></i> Upload</span></a>
|
||||||
|
@ -28,8 +41,6 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>Provider</th>
|
|
||||||
<th>Id</th>
|
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>First</th>
|
<th>First</th>
|
||||||
<th>Last</th>
|
<th>Last</th>
|
||||||
|
@ -48,8 +59,6 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>Id</th>
|
|
||||||
<th>Provider</th>
|
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
<input id="id" hidden/>
|
<input id="id" hidden/>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<div class="item form-group">
|
<!-- <div class="item form-group">
|
||||||
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="provider">Provider name: <span class="required">*</span></label>
|
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="provider">Provider name: <span class="required">*</span></label>
|
||||||
<div class="col-md-6 col-sm-6 col-xs-12">
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
<input id="provider" name="provider" placeholder="" type="text" style="width:100%">
|
<input id="provider" name="provider" placeholder="" type="text" style="width:100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="item form-group">
|
<div class="item form-group">
|
||||||
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="format">Format: <span class="required">*</span></label>
|
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="format">Format: <span class="required">*</span></label>
|
||||||
<div class="col-md-6 col-sm-6 col-xs-12">
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="x_panela" id="bulkusers-quota" style="padding: 5px;">
|
<!-- <div class="x_panela" id="bulkusers-quota" style="padding: 5px;">
|
||||||
<p style="font-size: 18px;margin-bottom:0px;">Map User keys</p>
|
<p style="font-size: 18px;margin-bottom:0px;">Map User keys</p>
|
||||||
|
|
||||||
<div class="item form-group">
|
<div class="item form-group">
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal Footer -->
|
<!-- Modal Footer -->
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
<button class="btn btn-danger btn-xs btn-delete_keycloak">
|
<button class="btn btn-danger btn-xs btn-delete_keycloak">
|
||||||
<i class="fa fa-trash"></i> Delete all keycloak
|
<i class="fa fa-trash"></i> Delete all keycloak
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-danger btn-xs btn-delete_nextcloud">
|
||||||
|
<i class="fa fa-trash"></i> Delete missing keycloak in nextcloud
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger btn-xs btn-delete_moodle">
|
||||||
|
<i class="fa fa-trash"></i> Delete missing keycloak in moodle
|
||||||
|
</button>
|
||||||
<table id="users" class="table" width="100%">
|
<table id="users" class="table" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -68,5 +74,6 @@
|
||||||
<!-- Switchery -->
|
<!-- Switchery -->
|
||||||
<script src="/isard-sso-admin/vendors/switchery/dist/switchery.min.js"></script>
|
<script src="/isard-sso-admin/vendors/switchery/dist/switchery.min.js"></script>
|
||||||
<!-- Desktops sse & modals -->
|
<!-- Desktops sse & modals -->
|
||||||
<script src="/isard-sso-admin/static/js/users.js"></script>
|
<script src="/isard-sso-admin/static/js/users.js"></script>
|
||||||
|
<script src="/isard-sso-admin/static/js/status_socket.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -23,6 +23,10 @@ def users(provider=False):
|
||||||
if request.method == 'DELETE':
|
if request.method == 'DELETE':
|
||||||
if provider == 'keycloak':
|
if provider == 'keycloak':
|
||||||
return json.dumps(app.admin.delete_keycloak_users()), 200, {'Content-Type': 'application/json'}
|
return json.dumps(app.admin.delete_keycloak_users()), 200, {'Content-Type': 'application/json'}
|
||||||
|
if provider == 'nextcloud':
|
||||||
|
return json.dumps(app.admin.delete_nextcloud_users()), 200, {'Content-Type': 'application/json'}
|
||||||
|
if provider == 'moodle':
|
||||||
|
return json.dumps(app.admin.delete_moodle_users()), 200, {'Content-Type': 'application/json'}
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
if provider == 'moodle':
|
if provider == 'moodle':
|
||||||
return json.dumps(app.admin.sync_to_moodle()), 200, {'Content-Type': 'application/json'}
|
return json.dumps(app.admin.sync_to_moodle()), 200, {'Content-Type': 'application/json'}
|
||||||
|
@ -79,4 +83,10 @@ def external_users_list():
|
||||||
@app.route('/isard-sso-admin/external_groups_list')
|
@app.route('/isard-sso-admin/external_groups_list')
|
||||||
# @login_required
|
# @login_required
|
||||||
def external_groups_list():
|
def external_groups_list():
|
||||||
return json.dumps(app.admin.get_external_groups()), 200, {'Content-Type': 'application/json'}
|
return json.dumps(app.admin.get_external_groups()), 200, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
|
@app.route('/isard-sso-admin/external/roles', methods=['PUT'])
|
||||||
|
# @login_required
|
||||||
|
def external_roles():
|
||||||
|
if request.method == 'PUT':
|
||||||
|
return json.dumps(app.admin.external_roleassign(request.get_json(force=True))), 200, {'Content-Type': 'application/json'}
|
|
@ -0,0 +1,16 @@
|
||||||
|
from flask_socketio import SocketIO, emit, join_room, leave_room, \
|
||||||
|
close_room, rooms, disconnect, send
|
||||||
|
from admin import app
|
||||||
|
socketio = SocketIO(app)
|
||||||
|
|
||||||
|
@socketio.on('connect', namespace='/isard-sso-admin/sio')
|
||||||
|
def socketio_connect():
|
||||||
|
join_room('admin')
|
||||||
|
socketio.emit('update',
|
||||||
|
json.dumps('Joined'),
|
||||||
|
namespace='/isard-sso-admin/sio',
|
||||||
|
room='admin')
|
||||||
|
|
||||||
|
@socketio.on('disconnect', namespace='/isard-sso-admin/sio')
|
||||||
|
def socketio_domains_disconnect():
|
||||||
|
None
|
|
@ -134,6 +134,7 @@ class MoodleSaml():
|
||||||
'duallogin': '1',
|
'duallogin': '1',
|
||||||
'idpattr': 'username',
|
'idpattr': 'username',
|
||||||
'autocreate': '1',
|
'autocreate': '1',
|
||||||
|
'anyauth': '1',
|
||||||
'saml_role_siteadmin_map': 'admin',
|
'saml_role_siteadmin_map': 'admin',
|
||||||
'saml_role_coursecreator_map': 'teacher',
|
'saml_role_coursecreator_map': 'teacher',
|
||||||
'saml_role_manager_map': 'manager',
|
'saml_role_manager_map': 'manager',
|
||||||
|
|
|
@ -3,8 +3,26 @@
|
||||||
from gevent import monkey
|
from gevent import monkey
|
||||||
monkey.patch_all()
|
monkey.patch_all()
|
||||||
|
|
||||||
|
from flask_socketio import SocketIO, emit, join_room, leave_room, \
|
||||||
|
close_room, rooms, disconnect, send
|
||||||
|
import json
|
||||||
from admin import app
|
from admin import app
|
||||||
|
|
||||||
|
socketio = SocketIO(app)
|
||||||
|
socketio.init_app(app, cors_allowed_origins="*")
|
||||||
|
|
||||||
|
# from .admin.views.Socketio import *
|
||||||
|
@socketio.on('connect', namespace='/isard-sso-admin/sio')
|
||||||
|
def socketio_connect():
|
||||||
|
join_room('admin')
|
||||||
|
socketio.emit('update',
|
||||||
|
json.dumps('Joined'),
|
||||||
|
namespace='/isard-sso-admin/sio',
|
||||||
|
room='admin')
|
||||||
|
|
||||||
|
@socketio.on('disconnect', namespace='/isard-sso-admin/sio')
|
||||||
|
def socketio_domains_disconnect():
|
||||||
|
None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=9000, debug=False) #, logger=logger, engineio_logger=engineio_logger)
|
socketio.run(app,host='0.0.0.0', port=9000, debug=False, cors_allowed_origins="*") #, logger=logger, engineio_logger=engineio_logger)
|
||||||
|
|
|
@ -34,6 +34,9 @@ frontend website
|
||||||
http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt }
|
http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt }
|
||||||
bind :443 ssl crt /certs/chain.pem
|
bind :443 ssl crt /certs/chain.pem
|
||||||
|
|
||||||
|
acl is_upgrade hdr(Connection) -i upgrade
|
||||||
|
acl is_websocket hdr(Upgrade) -i websocket
|
||||||
|
|
||||||
acl is_nextcloud hdr_beg(host) nextcloud.
|
acl is_nextcloud hdr_beg(host) nextcloud.
|
||||||
acl is_moodle hdr_beg(host) moodle.
|
acl is_moodle hdr_beg(host) moodle.
|
||||||
acl is_jitsi hdr_beg(host) jitsi.
|
acl is_jitsi hdr_beg(host) jitsi.
|
||||||
|
@ -51,11 +54,13 @@ frontend website
|
||||||
use_backend be_oof if is_oof
|
use_backend be_oof if is_oof
|
||||||
use_backend be_wp if is_wp
|
use_backend be_wp if is_wp
|
||||||
use_backend be_etherpad if is_pad
|
use_backend be_etherpad if is_pad
|
||||||
|
use_backend be_admin if is_sso { path_beg /socket.io }
|
||||||
use_backend be_adminer if is_sso { path_beg /isard-sso-adminer }
|
use_backend be_adminer if is_sso { path_beg /isard-sso-adminer }
|
||||||
use_backend be_admin if is_sso { path_beg /isard-sso-admin }
|
use_backend be_admin if is_sso { path_beg /isard-sso-admin }
|
||||||
use_backend be_sso if is_sso
|
use_backend be_sso if is_sso
|
||||||
use_backend be_ipa if is_ipa
|
use_backend be_ipa if is_ipa
|
||||||
use_backend be_api if is_api
|
use_backend be_api if is_api
|
||||||
|
|
||||||
|
|
||||||
# default_backend be_sso
|
# default_backend be_sso
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue