Merge branch 'develop' into 'master'
Develop merge See merge request isard/isard-sso!54
commit
d30b77926a
|
@ -629,7 +629,6 @@ class Admin():
|
||||||
i=i+1
|
i=i+1
|
||||||
log.warning(' KEYCLOAK GROUPS: Adding group ('+str(i)+'/'+str(total)+'): '+g)
|
log.warning(' KEYCLOAK GROUPS: Adding group ('+str(i)+'/'+str(total)+'): '+g)
|
||||||
ev.increment({'name':g})
|
ev.increment({'name':g})
|
||||||
print(g)
|
|
||||||
self.keycloak.add_group_tree(g)
|
self.keycloak.add_group_tree(g)
|
||||||
|
|
||||||
total=len(self.external['users'])
|
total=len(self.external['users'])
|
||||||
|
@ -1170,6 +1169,22 @@ class Admin():
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def enable_users(self,data):
|
||||||
|
#data={'id':'','username':''}
|
||||||
|
ev=Events('Bulk actions','Enabling user:',total=len(data))
|
||||||
|
for user in data:
|
||||||
|
ev.increment({'name':user['username'],'data':user['username']})
|
||||||
|
self.keycloak.user_enable(user['id'])
|
||||||
|
self.resync_data()
|
||||||
|
|
||||||
|
def disable_users(self,data):
|
||||||
|
#data={'id':'','username':''}
|
||||||
|
ev=Events('Bulk actions','Disabling user:',total=len(data))
|
||||||
|
for user in data:
|
||||||
|
ev.increment({'name':user['username'],'data':user['username']})
|
||||||
|
self.keycloak.user_disable(user['id'])
|
||||||
|
self.resync_data()
|
||||||
|
|
||||||
def update_moodle_user(self,user_id,user,mdelete,madd):
|
def update_moodle_user(self,user_id,user,mdelete,madd):
|
||||||
internaluser=[u for u in self.internal['users'] if u['id']==user_id][0]
|
internaluser=[u for u in self.internal['users'] if u['id']==user_id][0]
|
||||||
cohorts=self.moodle.get_cohorts()
|
cohorts=self.moodle.get_cohorts()
|
||||||
|
@ -1244,6 +1259,13 @@ class Admin():
|
||||||
except:
|
except:
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
|
|
||||||
|
def delete_users(self,data):
|
||||||
|
ev=Events('Bulk actions','Deleting users:',total=len(data))
|
||||||
|
for user in data:
|
||||||
|
ev.increment({'name':user['username'],'data':user['username']})
|
||||||
|
self.delete_user(user['id'])
|
||||||
|
self.resync_data()
|
||||||
|
|
||||||
def delete_user(self,userid):
|
def delete_user(self,userid):
|
||||||
log.warning('Deleting user moodle, nextcloud keycloak')
|
log.warning('Deleting user moodle, nextcloud keycloak')
|
||||||
ev=Events('Deleting user','Deleting from moodle')
|
ev=Events('Deleting user','Deleting from moodle')
|
||||||
|
@ -1278,7 +1300,6 @@ class Admin():
|
||||||
else:
|
else:
|
||||||
pathpart=pathpart+'.'+part
|
pathpart=pathpart+'.'+part
|
||||||
pathslist.append(pathpart)
|
pathslist.append(pathpart)
|
||||||
print(pathslist)
|
|
||||||
|
|
||||||
### KEYCLOAK
|
### KEYCLOAK
|
||||||
#######################
|
#######################
|
||||||
|
|
|
@ -197,6 +197,16 @@ class KeycloakClient():
|
||||||
self.connect()
|
self.connect()
|
||||||
return self.keycloak_admin.update_user( user_id, payload)
|
return self.keycloak_admin.update_user( user_id, payload)
|
||||||
|
|
||||||
|
def user_enable(self,user_id):
|
||||||
|
payload={"enabled":True}
|
||||||
|
self.connect()
|
||||||
|
return self.keycloak_admin.update_user( user_id, payload)
|
||||||
|
|
||||||
|
def user_disable(self,user_id):
|
||||||
|
payload={"enabled":False}
|
||||||
|
self.connect()
|
||||||
|
return self.keycloak_admin.update_user( user_id, payload)
|
||||||
|
|
||||||
def group_user_remove(self,user_id,group_id):
|
def group_user_remove(self,user_id,group_id):
|
||||||
self.connect()
|
self.connect()
|
||||||
return self.keycloak_admin.group_user_remove(user_id,group_id)
|
return self.keycloak_admin.group_user_remove(user_id,group_id)
|
||||||
|
|
|
@ -4,6 +4,7 @@ $(document).on('shown.bs.modal', '#modalAddDesktop', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
$('#action_role option[value=""]').prop("selected",true);
|
||||||
var path = "";
|
var path = "";
|
||||||
items = [];
|
items = [];
|
||||||
document.getElementById('file-upload').addEventListener('change', readFile, false);
|
document.getElementById('file-upload').addEventListener('change', readFile, false);
|
||||||
|
@ -26,8 +27,8 @@ $(document).ready(function() {
|
||||||
{
|
{
|
||||||
console.log('SUCCESS')
|
console.log('SUCCESS')
|
||||||
// $("#modalImport").modal('hide');
|
// $("#modalImport").modal('hide');
|
||||||
// users_table.ajax.reload();
|
users_table.ajax.reload();
|
||||||
// groups_table.ajax.reload();
|
groups_table.ajax.reload();
|
||||||
},
|
},
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +70,7 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).on('pnotify.cancel', function() {
|
}).on('pnotify.cancel', function() {
|
||||||
$('#action_role option[value="none"]').prop("selected",true);
|
$('#action_role option[value=""]').prop("selected",true);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -102,12 +103,14 @@ $(document).ready(function() {
|
||||||
{
|
{
|
||||||
console.log('SUCCESS')
|
console.log('SUCCESS')
|
||||||
$("#modalImport").modal('hide');
|
$("#modalImport").modal('hide');
|
||||||
// users_table.ajax.reload();
|
users_table.ajax.reload();
|
||||||
// groups_table.ajax.reload();
|
groups_table.ajax.reload();
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
var err = eval("(" + xhr.responseText + ")");
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
alert(JSON.parse(xhr.responseText).msg)
|
alert(JSON.parse(xhr.responseText).msg)
|
||||||
|
users_table.ajax.reload();
|
||||||
|
groups_table.ajax.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,8 +166,9 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).on('pnotify.cancel', function() {
|
}).on('pnotify.cancel', function() {
|
||||||
$('#action_role option[value="none"]').prop("selected",true);
|
|
||||||
});
|
});
|
||||||
|
$('#action_role option[value=""]').prop("selected",true);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
//DataTable Main renderer
|
//DataTable Main renderer
|
||||||
|
|
|
@ -5,6 +5,7 @@ $(document).on('shown.bs.modal', '#modalAddDesktop', function () {
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
$('#bulk_actions option[value=""]').prop("selected",true);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
"url": "/api/groups",
|
"url": "/api/groups",
|
||||||
|
@ -29,30 +30,6 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// $.ajax({
|
|
||||||
// type: "GET",
|
|
||||||
// "url": "/api/groups",
|
|
||||||
// success: function(data)
|
|
||||||
// {
|
|
||||||
// data.forEach(element => {
|
|
||||||
// var groupOrigins = [];
|
|
||||||
// ['keycloak', 'moodle', 'nextcloud'].forEach(o => {
|
|
||||||
// if (element[o]) {
|
|
||||||
// groupOrigins.push(o)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// $(".groups-select").append(
|
|
||||||
// '<option value=' + element.path + '>' + element.name + ' (' + groupOrigins.join(',') + ') </option>'
|
|
||||||
// )
|
|
||||||
// });
|
|
||||||
// $('.groups-select').select2();
|
|
||||||
// },
|
|
||||||
// error: function(data)
|
|
||||||
// {
|
|
||||||
// alert('Something went wrong on our side...')
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
"url": "/api/roles",
|
"url": "/api/roles",
|
||||||
|
@ -81,10 +58,68 @@ $(document).ready(function() {
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
|
table.ajax.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#bulk_actions').on('change', function () {
|
||||||
|
action=$(this).val();
|
||||||
|
names=''
|
||||||
|
ids=[]
|
||||||
|
|
||||||
|
if(table.rows('.active').data().length){
|
||||||
|
$.each(table.rows('.active').data(),function(key, value){
|
||||||
|
names+=value['username']+'\n';
|
||||||
|
ids.push({'id':value['id'],'username':value['username']});
|
||||||
|
});
|
||||||
|
var text = "You are about to "+action+" these users:\n\n "+names
|
||||||
|
}else{
|
||||||
|
$.each(table.rows({filter: 'applied'}).data(),function(key, value){
|
||||||
|
ids.push({'id':value['id'],'username':value['username']});
|
||||||
|
});
|
||||||
|
var text = "You are about to "+action+" "+table.rows({filter: 'applied'}).data().length+" users!\n To all the users in list!"
|
||||||
|
}
|
||||||
|
console.log(ids)
|
||||||
|
new PNotify({
|
||||||
|
title: 'Bulk actions on users',
|
||||||
|
text: text,
|
||||||
|
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:"/api/users_bulk/"+$('#bulk_actions').val(),
|
||||||
|
data: JSON.stringify(ids),
|
||||||
|
success: function(data)
|
||||||
|
{
|
||||||
|
console.log('SUCCESS')
|
||||||
|
$('#bulk_actions option[value=""]').prop("selected",true);
|
||||||
|
table.ajax.reload();
|
||||||
|
},
|
||||||
|
error: function(data)
|
||||||
|
{
|
||||||
|
alert('Something went wrong on our side...')
|
||||||
|
$('#bulk_actions option[value=""]').prop("selected",true);
|
||||||
|
table.ajax.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).on('pnotify.cancel', function() {
|
||||||
|
$('#bulk_actions option[value=""]').prop("selected",true);
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
|
||||||
// Open new user modal
|
// Open new user modal
|
||||||
$('.btn-new-user').on('click', function () {
|
$('.btn-new-user').on('click', function () {
|
||||||
$("#modalAddUserForm")[0].reset();
|
$("#modalAddUserForm")[0].reset();
|
||||||
|
@ -281,6 +316,13 @@ $(document).ready(function() {
|
||||||
<button id="btn-password" class="btn btn-xs" type="button" data-placement="top" ><i class="fa fa-lock" style="color:orange"></i></button> \
|
<button id="btn-password" class="btn btn-xs" type="button" data-placement="top" ><i class="fa fa-lock" style="color:orange"></i></button> \
|
||||||
<button id="btn-edit" class="btn btn-xs" type="button" data-placement="top" ><i class="fa fa-pencil" style="color:darkblue"></i></button>'
|
<button id="btn-edit" class="btn btn-xs" type="button" data-placement="top" ><i class="fa fa-pencil" style="color:darkblue"></i></button>'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"className": 'text-center',
|
||||||
|
"data": null,
|
||||||
|
"orderable": false,
|
||||||
|
"defaultContent": '<input type="checkbox" class="form-check-input"></input>',
|
||||||
|
"width": "10px"
|
||||||
|
},
|
||||||
{ "data": "username", "width": "10px"},
|
{ "data": "username", "width": "10px"},
|
||||||
{ "data": "first", "width": "10px"},
|
{ "data": "first", "width": "10px"},
|
||||||
{ "data": "last", "width": "150px"},
|
{ "data": "last", "width": "150px"},
|
||||||
|
@ -314,12 +356,12 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{
|
{
|
||||||
"targets": 4,
|
"targets": 5,
|
||||||
"render": function ( data, type, full, meta ) {
|
"render": function ( data, type, full, meta ) {
|
||||||
return '<b>'+full.username+'</b>'
|
return '<b>'+full.username+'</b>'
|
||||||
}},
|
}},
|
||||||
{
|
{
|
||||||
"targets": 8,
|
"targets": 9,
|
||||||
"render": function ( data, type, full, meta ) {
|
"render": function ( data, type, full, meta ) {
|
||||||
grups = ''
|
grups = ''
|
||||||
full.keycloak_groups.forEach(element => {
|
full.keycloak_groups.forEach(element => {
|
||||||
|
@ -328,7 +370,7 @@ $(document).ready(function() {
|
||||||
return grups
|
return grups
|
||||||
}},
|
}},
|
||||||
{
|
{
|
||||||
"targets": 9,
|
"targets": 10,
|
||||||
"render": function ( data, type, full, meta ) {
|
"render": function ( data, type, full, meta ) {
|
||||||
if(full.quota == false){
|
if(full.quota == false){
|
||||||
return 'Unlimited'
|
return 'Unlimited'
|
||||||
|
@ -339,6 +381,15 @@ $(document).ready(function() {
|
||||||
]
|
]
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
table.on( 'click', 'tr', function () {
|
||||||
|
$(this).toggleClass('active');
|
||||||
|
if ($(this).hasClass('active')) {
|
||||||
|
$(this).find('input').prop('checked', true);
|
||||||
|
} else {
|
||||||
|
$(this).find('input').prop('checked', false);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
// $template = $(".template-detail-users");
|
// $template = $(".template-detail-users");
|
||||||
|
|
||||||
// $('#users').find('tbody').on('click', 'td.details-control', function () {
|
// $('#users').find('tbody').on('click', 'td.details-control', function () {
|
||||||
|
@ -406,6 +457,7 @@ $(document).ready(function() {
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
|
table.ajax.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).on('pnotify.cancel', function() {
|
}).on('pnotify.cancel', function() {
|
||||||
|
@ -425,10 +477,12 @@ $(document).ready(function() {
|
||||||
success: function(data)
|
success: function(data)
|
||||||
{
|
{
|
||||||
$('#modalPasswdUserForm #password').val(data);
|
$('#modalPasswdUserForm #password').val(data);
|
||||||
|
table.ajax.reload();
|
||||||
},
|
},
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
|
table.ajax.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -455,6 +509,7 @@ $(document).ready(function() {
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
|
table.ajax.reload();
|
||||||
}
|
}
|
||||||
// statusCode: {
|
// statusCode: {
|
||||||
// 404: function(data) {
|
// 404: function(data) {
|
||||||
|
|
|
@ -14,6 +14,19 @@
|
||||||
<div class="x_title">
|
<div class="x_title">
|
||||||
<h3><i class="fa fa-user"></i> Users</h3>
|
<h3><i class="fa fa-user"></i> Users</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="bulk_actions">Bulk actions: <span class="required">*</span></label>
|
||||||
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
|
<select id="bulk_actions" name="bulk_actions" class="form-control action" required>
|
||||||
|
<option value=''>Select action</option>
|
||||||
|
<option value='enable'>Enable</option>
|
||||||
|
<option value='disable'>Disable</option>
|
||||||
|
<option value='delete'>Delete</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="btn-new-user"><span style="color: #5499c7; "><i class="fa fa-plus"></i> Add new</span></a>
|
<a class="btn-new-user"><span style="color: #5499c7; "><i class="fa fa-plus"></i> Add new</span></a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -28,6 +41,7 @@
|
||||||
<th>Avatar</th>
|
<th>Avatar</th>
|
||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
|
<th>Selected</th>
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>First</th>
|
<th>First</th>
|
||||||
<th>Last</th>
|
<th>Last</th>
|
||||||
|
@ -38,6 +52,21 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th>Enabled</th>
|
||||||
|
<th>Avatar</th>
|
||||||
|
<th>Role</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
<th>Selected</th>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>First</th>
|
||||||
|
<th>Last</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Groups</th>
|
||||||
|
<th>Quota</th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@ from ..lib.helpers import system_group
|
||||||
|
|
||||||
# import Queue
|
# import Queue
|
||||||
import threading
|
import threading
|
||||||
threads={}
|
threads={'external':None}
|
||||||
# q = Queue.Queue()
|
# q = Queue.Queue()
|
||||||
|
|
||||||
from keycloak.exceptions import KeycloakGetError
|
from keycloak.exceptions import KeycloakGetError
|
||||||
|
@ -70,6 +70,51 @@ def users(provider=False):
|
||||||
user['keycloak_groups'] = [g for g in user['keycloak_groups'] if not system_group(g) ]
|
user['keycloak_groups'] = [g for g in user['keycloak_groups'] if not system_group(g) ]
|
||||||
return json.dumps(users), 200, {'Content-Type': 'application/json'}
|
return json.dumps(users), 200, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
|
@app.route('/api/users_bulk/<action>', methods=['PUT'])
|
||||||
|
@login_required
|
||||||
|
def users_bulk(action):
|
||||||
|
data=request.get_json(force=True)
|
||||||
|
if request.method == 'PUT':
|
||||||
|
if action == 'enable':
|
||||||
|
if 'external' in threads.keys():
|
||||||
|
if threads['external'] is not None and threads['external'].is_alive():
|
||||||
|
return json.dumps({'msg':'Precondition failed: already operating users'}), 412, {'Content-Type': 'application/json'}
|
||||||
|
else:
|
||||||
|
threads['external']=None
|
||||||
|
try:
|
||||||
|
threads['external'] = threading.Thread(target=app.admin.enable_users, args=(data,))
|
||||||
|
threads['external'].start()
|
||||||
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
return json.dumps({'msg':'Enable users error.'}), 500, {'Content-Type': 'application/json'}
|
||||||
|
if action == 'disable':
|
||||||
|
if 'external' in threads.keys():
|
||||||
|
if threads['external'] is not None and threads['external'].is_alive():
|
||||||
|
return json.dumps({'msg':'Precondition failed: already operating users'}), 412, {'Content-Type': 'application/json'}
|
||||||
|
else:
|
||||||
|
threads['external']=None
|
||||||
|
try:
|
||||||
|
threads['external'] = threading.Thread(target=app.admin.disable_users, args=(data,))
|
||||||
|
threads['external'].start()
|
||||||
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
return json.dumps({'msg':'Disabling users error.'}), 500, {'Content-Type': 'application/json'}
|
||||||
|
if action == 'delete':
|
||||||
|
if 'external' in threads.keys():
|
||||||
|
if threads['external'] is not None and threads['external'].is_alive():
|
||||||
|
return json.dumps({'msg':'Precondition failed: already operating users'}), 412, {'Content-Type': 'application/json'}
|
||||||
|
else:
|
||||||
|
threads['external']=None
|
||||||
|
try:
|
||||||
|
threads['external'] = threading.Thread(target=app.admin.delete_users, args=(data,))
|
||||||
|
threads['external'].start()
|
||||||
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
return json.dumps({'msg':'Deleting users error.'}), 500, {'Content-Type': 'application/json'}
|
||||||
|
return json.dumps({}), 405, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
# Update pwd
|
# Update pwd
|
||||||
@app.route('/api/user_password', methods=['GET'])
|
@app.route('/api/user_password', methods=['GET'])
|
||||||
|
@ -219,11 +264,15 @@ def external():
|
||||||
@app.route('/api/external/users')
|
@app.route('/api/external/users')
|
||||||
@login_required
|
@login_required
|
||||||
def external_users_list():
|
def external_users_list():
|
||||||
|
while threads['external'] is not None and threads['external'].is_alive():
|
||||||
|
time.sleep(.5)
|
||||||
return json.dumps(app.admin.get_external_users()), 200, {'Content-Type': 'application/json'}
|
return json.dumps(app.admin.get_external_users()), 200, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
@app.route('/api/external/groups')
|
@app.route('/api/external/groups')
|
||||||
@login_required
|
@login_required
|
||||||
def external_groups_list():
|
def external_groups_list():
|
||||||
|
while threads['external'] is not None and threads['external'].is_alive():
|
||||||
|
time.sleep(.5)
|
||||||
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('/api/external/roles', methods=['PUT'])
|
@app.route('/api/external/roles', methods=['PUT'])
|
||||||
|
|
Loading…
Reference in New Issue