Fixed avatars on deleting and UI things
parent
fab77bc09e
commit
09ae3e16e6
|
@ -78,9 +78,9 @@ class Admin():
|
||||||
'groups':[],
|
'groups':[],
|
||||||
'roles':[]}
|
'roles':[]}
|
||||||
log.warning(' Updating missing user avatars with defaults')
|
log.warning(' Updating missing user avatars with defaults')
|
||||||
av=Avatars()
|
self.av=Avatars()
|
||||||
# av.minio_delete_all_objects() # This will reset all avatars on usres
|
# av.minio_delete_all_objects() # This will reset all avatars on usres
|
||||||
av.update_missing_avatars(self.internal['users'])
|
self.av.update_missing_avatars(self.internal['users'])
|
||||||
log.warning(' SYSTEM READY TO HANDLE CONNECTIONS')
|
log.warning(' SYSTEM READY TO HANDLE CONNECTIONS')
|
||||||
|
|
||||||
## This function should be moved to postup.py
|
## This function should be moved to postup.py
|
||||||
|
@ -457,21 +457,28 @@ class Admin():
|
||||||
def get_dice_pwd(self):
|
def get_dice_pwd(self):
|
||||||
return diceware.get_passphrase(options=options)
|
return diceware.get_passphrase(options=options)
|
||||||
|
|
||||||
|
def reset_external(self):
|
||||||
|
self.external={'users':[],
|
||||||
|
'groups':[],
|
||||||
|
'roles':[]}
|
||||||
|
return True
|
||||||
|
|
||||||
def upload_json_ga(self,data):
|
def upload_json_ga(self,data):
|
||||||
groups=[]
|
groups=[]
|
||||||
log.warning('Processing uploaded groups...')
|
log.warning('Processing uploaded groups...')
|
||||||
try:
|
try:
|
||||||
ev=Events('Processing uploaded groups','Group:',total=len(data['data']['groups']))
|
ev=Events('Processing uploaded groups','Group:',total=len(data['data']['groups']),table='groups')
|
||||||
except:
|
except:
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
for g in data['data']['groups']:
|
for g in data['data']['groups']:
|
||||||
try:
|
try:
|
||||||
ev.increment({'name':g['name'],'data':g})
|
group={'provider':'external',
|
||||||
groups.append({'provider':'external',
|
|
||||||
"id": g['id'],
|
"id": g['id'],
|
||||||
"mailid": g['email'].split('@')[0],
|
"mailid": g['email'].split('@')[0],
|
||||||
"name": g['name'],
|
"name": g['name'],
|
||||||
"description": g['description']})
|
"description": g['description']}
|
||||||
|
ev.increment({'name':g['name'],'data':group})
|
||||||
|
groups.append(group)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.external['groups']=groups
|
self.external['groups']=groups
|
||||||
|
@ -480,7 +487,7 @@ class Admin():
|
||||||
users=[]
|
users=[]
|
||||||
total=len(data['data']['users'])
|
total=len(data['data']['users'])
|
||||||
item=1
|
item=1
|
||||||
ev=Events('Processing uploaded users','User:',total=len(data['data']['users']))
|
ev=Events('Processing uploaded users','User:',total=len(data['data']['users']),table='users')
|
||||||
for u in data['data']['users']:
|
for u in data['data']['users']:
|
||||||
log.warning('Processing ('+str(item)+'/'+str(total)+') uploaded user: '+u['primaryEmail'].split('@')[0])
|
log.warning('Processing ('+str(item)+'/'+str(total)+') uploaded user: '+u['primaryEmail'].split('@')[0])
|
||||||
new_user={'provider':'external',
|
new_user={'provider':'external',
|
||||||
|
@ -491,7 +498,7 @@ class Admin():
|
||||||
'username': u['primaryEmail'].split('@')[0],
|
'username': u['primaryEmail'].split('@')[0],
|
||||||
'groups':[u['orgUnitPath']], ## WARNING: Removing the first
|
'groups':[u['orgUnitPath']], ## WARNING: Removing the first
|
||||||
'roles':[],
|
'roles':[],
|
||||||
'password': diceware.get_passphrase(options=options)}
|
'password': self.get_dice_pwd()}
|
||||||
users.append(new_user)
|
users.append(new_user)
|
||||||
item+=1
|
item+=1
|
||||||
ev.increment({'name':u['primaryEmail'].split('@')[0],'data':new_user})
|
ev.increment({'name':u['primaryEmail'].split('@')[0],'data':new_user})
|
||||||
|
@ -539,7 +546,7 @@ class Admin():
|
||||||
log.warning(' KEYCLOAK USERS: Adding user ('+str(index)+'/'+str(total)+'): '+u['username'])
|
log.warning(' KEYCLOAK USERS: Adding user ('+str(index)+'/'+str(total)+'): '+u['username'])
|
||||||
ev.increment({'name':u['username'],'data':u})
|
ev.increment({'name':u['username'],'data':u})
|
||||||
uid=self.keycloak.add_user(u['username'],u['first'],u['last'],u['email'],u['password'])
|
uid=self.keycloak.add_user(u['username'],u['first'],u['last'],u['email'],u['password'])
|
||||||
|
self.av.add_user_default_avatar(uid,u['roles'][0])
|
||||||
# Add user to role and group rolename
|
# Add user to role and group rolename
|
||||||
if len(u['roles']) != 0:
|
if len(u['roles']) != 0:
|
||||||
log.warning(' KEYCLOAK USERS: Assign user '+u['username']+' with initial pwd '+ u['password']+' to role '+u['roles'][0])
|
log.warning(' KEYCLOAK USERS: Assign user '+u['username']+' with initial pwd '+ u['password']+' to role '+u['roles'][0])
|
||||||
|
@ -687,6 +694,8 @@ class Admin():
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
log.warning('Could not remove users: '+user['username'])
|
log.warning('Could not remove users: '+user['username'])
|
||||||
|
|
||||||
|
self.av.delete_user_avatar(userid)
|
||||||
|
|
||||||
def delete_keycloak_users(self):
|
def delete_keycloak_users(self):
|
||||||
total=len(self.internal['users'])
|
total=len(self.internal['users'])
|
||||||
i=0
|
i=0
|
||||||
|
@ -702,6 +711,7 @@ class Admin():
|
||||||
self.keycloak.delete_user(u['id'])
|
self.keycloak.delete_user(u['id'])
|
||||||
except:
|
except:
|
||||||
log.warning(' KEYCLOAK USERS: Could not remove user: '+u['username'] +'. Probably already not exists.')
|
log.warning(' KEYCLOAK USERS: Could not remove user: '+u['username'] +'. Probably already not exists.')
|
||||||
|
self.av.minio_delete_all_objects()
|
||||||
|
|
||||||
def delete_nextcloud_user(self,userid):
|
def delete_nextcloud_user(self,userid):
|
||||||
user=[u for u in self.internal['users'] if u['id']==userid]
|
user=[u for u in self.internal['users'] if u['id']==userid]
|
||||||
|
|
|
@ -21,6 +21,16 @@ class Avatars():
|
||||||
self._minio_set_realm()
|
self._minio_set_realm()
|
||||||
# self.update_missing_avatars()
|
# self.update_missing_avatars()
|
||||||
|
|
||||||
|
def add_user_default_avatar(self,userid,role='unknown'):
|
||||||
|
self.mclient.fput_object(
|
||||||
|
self.bucket, userid, os.path.join(app.root_path,"../custom/avatars/"+role+'.jpg'),
|
||||||
|
content_type="image/jpeg ",
|
||||||
|
)
|
||||||
|
log.warning(' AVATARS: Updated avatar for user '+userid+' with role '+role)
|
||||||
|
|
||||||
|
def delete_user_avatar(self,userid):
|
||||||
|
self.minio_delete_object(userid)
|
||||||
|
|
||||||
def update_missing_avatars(self,users):
|
def update_missing_avatars(self,users):
|
||||||
sys_roles=['admin','manager','teacher','student']
|
sys_roles=['admin','manager','teacher','student']
|
||||||
for u in self.get_users_without_image(users):
|
for u in self.get_users_without_image(users):
|
||||||
|
@ -49,7 +59,12 @@ class Avatars():
|
||||||
)
|
)
|
||||||
errors=self.mclient.remove_objects(self.bucket, delete_object_list)
|
errors=self.mclient.remove_objects(self.bucket, delete_object_list)
|
||||||
for error in errors:
|
for error in errors:
|
||||||
log.error(" AVATARS: Error occured when deleting avatar object", error)
|
log.error(" AVATARS: Error occured when deleting avatar object: "+ error)
|
||||||
|
|
||||||
|
def minio_delete_object(self,oid):
|
||||||
|
errors=self.mclient.remove_objects(self.bucket, [DeleteObject(oid)])
|
||||||
|
for error in errors:
|
||||||
|
log.error(" AVATARS: Error occured when deleting avatar object: "+ error)
|
||||||
|
|
||||||
def get_users_without_image(self,users):
|
def get_users_without_image(self,users):
|
||||||
return [u for u in users if u['id'] and u['id'] not in self.minio_get_objects()]
|
return [u for u in users if u['id'] and u['id'] not in self.minio_get_objects()]
|
|
@ -14,11 +14,12 @@ from flask_socketio import SocketIO, emit, join_room, leave_room, \
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
class Events():
|
class Events():
|
||||||
def __init__(self,title,text='',total=0):
|
def __init__(self,title,text='',total=0,table=False):
|
||||||
self.eid=str(base64.b64encode(os.urandom(32))[:8])
|
self.eid=str(base64.b64encode(os.urandom(32))[:8])
|
||||||
self.title=title
|
self.title=title
|
||||||
self.text=text
|
self.text=text
|
||||||
self.total=total
|
self.total=total
|
||||||
|
self.table=table
|
||||||
self.item=0
|
self.item=0
|
||||||
self.create()
|
self.create()
|
||||||
|
|
||||||
|
@ -61,12 +62,13 @@ class Events():
|
||||||
def increment(self,data={'name':'','data':[]}):
|
def increment(self,data={'name':'','data':[]}):
|
||||||
self.item+=1
|
self.item+=1
|
||||||
log.info('INCREMENT '+self.eid+': '+self.text)
|
log.info('INCREMENT '+self.eid+': '+self.text)
|
||||||
app.socketio.emit('notify-update',
|
app.socketio.emit('notify-increment',
|
||||||
json.dumps({'id':self.eid,
|
json.dumps({'id':self.eid,
|
||||||
'title':self.title,
|
'title':self.title,
|
||||||
'text': '['+str(self.item)+'/'+str(self.total)+'] '+self.text+' '+data['name'],
|
'text': '['+str(self.item)+'/'+str(self.total)+'] '+self.text+' '+data['name'],
|
||||||
'item':self.item,
|
'item':self.item,
|
||||||
'total':self.total,
|
'total':self.total,
|
||||||
|
'table':self.table,
|
||||||
'data':data}),
|
'data':data}),
|
||||||
namespace='/sio',
|
namespace='/sio',
|
||||||
room='admin')
|
room='admin')
|
||||||
|
@ -75,12 +77,13 @@ class Events():
|
||||||
def decrement(self,data={'name':'','data':[]}):
|
def decrement(self,data={'name':'','data':[]}):
|
||||||
self.item-=1
|
self.item-=1
|
||||||
log.info('DECREMENT '+self.eid+': '+self.text)
|
log.info('DECREMENT '+self.eid+': '+self.text)
|
||||||
app.socketio.emit('notify-update',
|
app.socketio.emit('notify-decrement',
|
||||||
json.dumps({'id':self.eid,
|
json.dumps({'id':self.eid,
|
||||||
'title':self.title,
|
'title':self.title,
|
||||||
'text': '['+str(self.item)+'/'+str(self.total)+'] '+self.text+' '+data['name'],
|
'text': '['+str(self.item)+'/'+str(self.total)+'] '+self.text+' '+data['name'],
|
||||||
'item':self.item,
|
'item':self.item,
|
||||||
'total':self.total,
|
'total':self.total,
|
||||||
|
'table':self.table,
|
||||||
'data':data}),
|
'data':data}),
|
||||||
namespace='/sio',
|
namespace='/sio',
|
||||||
room='admin')
|
room='admin')
|
||||||
|
|
|
@ -268,12 +268,12 @@ class KeycloakClient():
|
||||||
## Add user
|
## Add user
|
||||||
uid=self.add_user(username,first,last,email,password)
|
uid=self.add_user(username,first,last,email,password)
|
||||||
## Add user to role
|
## Add user to role
|
||||||
print('User uid: '+str(uid)+ ' role: '+str(role))
|
log.info('User uid: '+str(uid)+ ' role: '+str(role))
|
||||||
try:
|
try:
|
||||||
therole=role[0]
|
therole=role[0]
|
||||||
except:
|
except:
|
||||||
therole=''
|
therole=''
|
||||||
print(self.assign_realm_roles(uid,role))
|
log.info(self.assign_realm_roles(uid,role))
|
||||||
## Create groups in user
|
## Create groups in user
|
||||||
for g in groups:
|
for g in groups:
|
||||||
log.warning('Creating keycloak group: '+g)
|
log.warning('Creating keycloak group: '+g)
|
||||||
|
|
|
@ -97,7 +97,6 @@ class Moodle():
|
||||||
(headers,users)=self.moodle_pg.select_with_headers(q)
|
(headers,users)=self.moodle_pg.select_with_headers(q)
|
||||||
users_with_lists = [list(l[:-2])+([[]] if l[-2] == [None] else [list(set(l[-2]))]) + ([[]] if l[-1] == [None] else [list(set(l[-1]))]) for l in users]
|
users_with_lists = [list(l[:-2])+([[]] if l[-2] == [None] else [list(set(l[-2]))]) + ([[]] if l[-1] == [None] else [list(set(l[-1]))]) for l in users]
|
||||||
list_dict_users = [dict(zip(headers, r)) for r in users_with_lists]
|
list_dict_users = [dict(zip(headers, r)) for r in users_with_lists]
|
||||||
pprint(list_dict_users)
|
|
||||||
return list_dict_users
|
return list_dict_users
|
||||||
|
|
||||||
## NOT USED. Too slow
|
## NOT USED. Too slow
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import time
|
import time
|
||||||
from admin import app
|
from admin import app
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import pprint
|
|
||||||
|
|
||||||
import logging as log
|
import logging as log
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -296,8 +296,6 @@ class Nextcloud():
|
||||||
try:
|
try:
|
||||||
result = json.loads(self._request('GET',url))
|
result = json.loads(self._request('GET',url))
|
||||||
if result['ocs']['meta']['statuscode'] == 100: return [g for g in result['ocs']['data']['groups']]
|
if result['ocs']['meta']['statuscode'] == 100: return [g for g in result['ocs']['data']['groups']]
|
||||||
import pprint
|
|
||||||
pprint.pprint(result)
|
|
||||||
raise ProviderOpError
|
raise ProviderOpError
|
||||||
except:
|
except:
|
||||||
log.error(traceback.format_exc())
|
log.error(traceback.format_exc())
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import time
|
import time
|
||||||
from admin import app
|
from admin import app
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import pprint
|
|
||||||
|
|
||||||
import logging as log
|
import logging as log
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import time, os
|
import time, os
|
||||||
from admin import app
|
from admin import app
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import pprint
|
|
||||||
|
|
||||||
import logging as log
|
import logging as log
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -292,6 +292,7 @@ function dtUpdateInsertoLD(table, data, append){
|
||||||
}
|
}
|
||||||
|
|
||||||
function dtUpdateInsert(table, data, append){
|
function dtUpdateInsert(table, data, append){
|
||||||
|
table=$("#"+table).DataTable()
|
||||||
//Quickly appends new data rows. Does not update rows
|
//Quickly appends new data rows. Does not update rows
|
||||||
new_id=false
|
new_id=false
|
||||||
if(append == true){
|
if(append == true){
|
||||||
|
|
|
@ -30,7 +30,7 @@ socket.on('notify-destroy', function(data) {
|
||||||
notice[data.id].remove()
|
notice[data.id].remove()
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('notify-update', function(data) {
|
socket.on('notify-increment', function(data) {
|
||||||
var data = JSON.parse(data);
|
var data = JSON.parse(data);
|
||||||
if(!( data.id in notice)){
|
if(!( data.id in notice)){
|
||||||
notice[data.id] = new PNotify({
|
notice[data.id] = new PNotify({
|
||||||
|
@ -43,8 +43,13 @@ socket.on('notify-update', function(data) {
|
||||||
notice[data.id].update({
|
notice[data.id].update({
|
||||||
text: data.text
|
text: data.text
|
||||||
})
|
})
|
||||||
|
if(! data.table == false){
|
||||||
|
dtUpdateInsert(data.table,data['data']['data'])
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// new PNotify({
|
// new PNotify({
|
||||||
// title: "Quota for creating desktops full.",
|
// title: "Quota for creating desktops full.",
|
||||||
// text: "Can't create another desktop, user quota full.",
|
// text: "Can't create another desktop, user quota full.",
|
||||||
|
|
|
@ -36,6 +36,44 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.btn-clear-upload').on('click', function () {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Cleaning imported data',
|
||||||
|
text: 'Are you sure you want to clean imported data?',
|
||||||
|
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: "DELETE",
|
||||||
|
url:"/api/external",
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
$('.btn-download').on('click', function () {
|
$('.btn-download').on('click', function () {
|
||||||
|
|
||||||
data=users_table.rows().data()
|
data=users_table.rows().data()
|
||||||
|
@ -63,7 +101,7 @@ $(document).ready(function() {
|
||||||
success: function(data)
|
success: function(data)
|
||||||
{
|
{
|
||||||
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();
|
||||||
},
|
},
|
||||||
|
@ -137,7 +175,7 @@ $(document).ready(function() {
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"loadingRecords": '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i><span class="sr-only">Loading...</span>',
|
"loadingRecords": '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i><span class="sr-only">Loading...</span>',
|
||||||
"emptyTable": "<h1>You don't have any user created yet.</h1><br><h2>Create one using the +Add new button on top right of this page.</h2>"
|
"emptyTable": "<h2>No users imported yet.</h2><br><h2>Import with the Upload button on top right of this page.</h2>"
|
||||||
},
|
},
|
||||||
"rowId": "id",
|
"rowId": "id",
|
||||||
"deferRender": true,
|
"deferRender": true,
|
||||||
|
@ -150,7 +188,7 @@ $(document).ready(function() {
|
||||||
"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"},
|
||||||
|
@ -161,7 +199,13 @@ $(document).ready(function() {
|
||||||
],
|
],
|
||||||
"order": [[3, 'asc']],
|
"order": [[3, 'asc']],
|
||||||
"columnDefs": [ {
|
"columnDefs": [ {
|
||||||
"targets": 5,
|
"targets": 1,
|
||||||
|
"render": function ( data, type, full, meta ) {
|
||||||
|
return '<img src="/custom/avatars/'+full.roles+'.jpg" title="'+full.id+'" width="25" height="25" onerror="if (this.src != \'/static/img/missing.jpg\') this.src = \'/static/img/missing.jpg\';">'
|
||||||
|
return '<img src="/avatar/'+full.id+'" title="'+full.id+'" width="25" height="25">'
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
"targets": 6,
|
||||||
"render": function ( data, type, full, meta ) {
|
"render": function ( data, type, full, meta ) {
|
||||||
return "<li>" + full.groups.join("</li><li>") + "</li>"
|
return "<li>" + full.groups.join("</li><li>") + "</li>"
|
||||||
}}
|
}}
|
||||||
|
@ -176,7 +220,7 @@ $(document).ready(function() {
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"loadingRecords": '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i><span class="sr-only">Loading...</span>',
|
"loadingRecords": '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i><span class="sr-only">Loading...</span>',
|
||||||
"emptyTable": "<h1>You don't have any user created yet.</h1><br><h2>Create one using the +Add new button on top right of this page.</h2>"
|
"emptyTable": "<h2>No groups imported yet.</h2>"
|
||||||
},
|
},
|
||||||
"rowId": "id",
|
"rowId": "id",
|
||||||
"deferRender": true,
|
"deferRender": true,
|
|
@ -97,6 +97,24 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-delete_keycloak').on('click', function () {
|
$('.btn-delete_keycloak').on('click', function () {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Confirmation Needed',
|
||||||
|
text: "Are you sure you want to DELETE ALL USERS IN KEYCLOAK???",
|
||||||
|
hide: false,
|
||||||
|
opacity: 0.9,
|
||||||
|
confirm: {
|
||||||
|
confirm: true
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
closer: false,
|
||||||
|
sticker: false
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
history: false
|
||||||
|
},
|
||||||
|
addclass: 'pnotify-center'
|
||||||
|
}).get().on('pnotify.confirm', function() {
|
||||||
|
console.log('Updating user password...')
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
url:"/api/users/keycloak",
|
url:"/api/users/keycloak",
|
||||||
|
@ -112,9 +130,31 @@ $(document).ready(function() {
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}).on('pnotify.cancel', function() {
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-delete_nextcloud').on('click', function () {
|
$('.btn-delete_nextcloud').on('click', function () {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Confirmation Needed',
|
||||||
|
text: "Are you sure you want to DELETE ALL USERS IN NEXTCLOUD?",
|
||||||
|
hide: false,
|
||||||
|
opacity: 0.9,
|
||||||
|
confirm: {
|
||||||
|
confirm: true
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
closer: false,
|
||||||
|
sticker: false
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
history: false
|
||||||
|
},
|
||||||
|
addclass: 'pnotify-center'
|
||||||
|
}).get().on('pnotify.confirm', function() {
|
||||||
|
console.log('Updating user password...')
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
url:"/api/users/nextcloud",
|
url:"/api/users/nextcloud",
|
||||||
|
@ -130,9 +170,29 @@ $(document).ready(function() {
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}).on('pnotify.cancel', function() {
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-delete_moodle').on('click', function () {
|
$('.btn-delete_moodle').on('click', function () {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Confirmation Needed',
|
||||||
|
text: "Are you sure you want to DELETE ALL USERS IN MOODLE?",
|
||||||
|
hide: false,
|
||||||
|
opacity: 0.9,
|
||||||
|
confirm: {
|
||||||
|
confirm: true
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
closer: false,
|
||||||
|
sticker: false
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
history: false
|
||||||
|
},
|
||||||
|
addclass: 'pnotify-center'
|
||||||
|
}).get().on('pnotify.confirm', function() {
|
||||||
|
console.log('Updating user password...')
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
url:"/api/users/moodle",
|
url:"/api/users/moodle",
|
||||||
|
@ -148,7 +208,10 @@ $(document).ready(function() {
|
||||||
alert('Something went wrong on our side...')
|
alert('Something went wrong on our side...')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}).on('pnotify.cancel', function() {
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('.btn-sync_to_moodle').on('click', function () {
|
$('.btn-sync_to_moodle').on('click', function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
|
@ -77,9 +77,6 @@ $(document).ready(function() {
|
||||||
success: function(data)
|
success: function(data)
|
||||||
{
|
{
|
||||||
table.ajax.reload();
|
table.ajax.reload();
|
||||||
// $("#modalImport").modal('hide');
|
|
||||||
// users_table.ajax.reload();
|
|
||||||
// groups_table.ajax.reload();
|
|
||||||
},
|
},
|
||||||
error: function(data)
|
error: function(data)
|
||||||
{
|
{
|
||||||
|
@ -117,95 +114,6 @@ $(document).ready(function() {
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-delete_keycloak').on('click', function () {
|
|
||||||
$.ajax({
|
|
||||||
type: "DELETE",
|
|
||||||
url:"/api/users/keycloak",
|
|
||||||
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_nextcloud').on('click', function () {
|
|
||||||
$.ajax({
|
|
||||||
type: "DELETE",
|
|
||||||
url:"/api/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:"/api/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 () {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url:"/api/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_nextcloud').on('click', function () {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url:"/api/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...')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//DataTable Main renderer
|
//DataTable Main renderer
|
||||||
var table = $('#users').DataTable({
|
var table = $('#users').DataTable({
|
||||||
"ajax": {
|
"ajax": {
|
||||||
|
@ -250,7 +158,7 @@ $(document).ready(function() {
|
||||||
"targets": 1,
|
"targets": 1,
|
||||||
"render": function ( data, type, full, meta ) {
|
"render": function ( data, type, full, meta ) {
|
||||||
// return '<object data="/static/img/missing.jpg" type="image/jpeg" width="25" height="25"><img src="/avatar/'+full.id+'" title="'+full.id+'" width="25" height="25"></object>'
|
// return '<object data="/static/img/missing.jpg" type="image/jpeg" width="25" height="25"><img src="/avatar/'+full.id+'" title="'+full.id+'" width="25" height="25"></object>'
|
||||||
return '<img src="/avatar/'+full.id+'" title="'+full.id+'" width="25" height="25">'
|
return '<img src="/avatar/'+full.id+'" title="'+full.id+'" width="25" height="25" onerror="if (this.src != \'/static/img/missing.jpg\') this.src = \'/static/img/missing.jpg\';">'
|
||||||
}},
|
}},
|
||||||
{
|
{
|
||||||
"targets": 2,
|
"targets": 2,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li role="presentation" class="sync-status">
|
<!-- <li role="presentation" class="sync-status">
|
||||||
<a href="javascript:" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="false">
|
<a href="javascript:" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="false">
|
||||||
<i class="fa fa-spinner"></i>
|
<i class="fa fa-spinner"></i>
|
||||||
<span class="badge"></span>
|
<span class="badge"></span>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li> -->
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
<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>
|
||||||
<a class="btn-download"><span style="color: #5499c7; "><i class="fa fa-download"></i> Download</span></a>
|
<a class="btn-download"><span style="color: #5499c7; "><i class="fa fa-download"></i> Download</span></a>
|
||||||
|
<a class="btn-clear-upload"><span style="color: #5499c7; "><i class="fa fa-cross"></i> Clear upload</span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th>Avatar</th>
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>First</th>
|
<th>First</th>
|
||||||
<th>Last</th>
|
<th>Last</th>
|
||||||
|
@ -83,5 +85,5 @@
|
||||||
<!-- Switchery -->
|
<!-- Switchery -->
|
||||||
<script src="/vendors/switchery/dist/switchery.min.js"></script>
|
<script src="/vendors/switchery/dist/switchery.min.js"></script>
|
||||||
<!-- Desktops sse & modals -->
|
<!-- Desktops sse & modals -->
|
||||||
<script src="/static/js/external.js"></script>
|
<script src="/static/js/sysadmin/external.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<button class="btn btn-primary btn-xs btn-sync_to_moodle">
|
<button class="btn btn-primary btn-xs btn-sync_to_moodle">
|
||||||
<i class="fa fa-refresh" aria-hidden="true"></i> Sync to Moodle
|
<i class="fa fa-refresh" aria-hidden="true"></i> Sync to Moodle
|
||||||
</button>
|
</button>
|
||||||
{% if current_user.role =='sysadmin' %}
|
{% if current_user.role =='admin' %}
|
||||||
<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>
|
||||||
|
|
|
@ -21,23 +21,6 @@
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="x_content">
|
<div class="x_content">
|
||||||
{% if current_user.role =='admin' %}
|
|
||||||
<button class="btn btn-primary btn-xs btn-sync_to_nextcloud">
|
|
||||||
<i class="fa fa-refresh" aria-hidden="true"></i> Sync to Nextcloud
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary btn-xs btn-sync_to_moodle">
|
|
||||||
<i class="fa fa-refresh" aria-hidden="true"></i> Sync to Moodle
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-danger btn-xs btn-delete_keycloak">
|
|
||||||
<i class="fa fa-trash"></i> Delete all keycloak
|
|
||||||
</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>
|
|
||||||
{% endif %}
|
|
||||||
<table id="users" class="table" width="100%">
|
<table id="users" class="table" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -103,7 +103,7 @@ def groups(provider=False):
|
||||||
|
|
||||||
### SYSADM USERS ONLY
|
### SYSADM USERS ONLY
|
||||||
|
|
||||||
@app.route('/api/external', methods=['POST', 'PUT', 'GET'])
|
@app.route('/api/external', methods=['POST', 'PUT', 'GET','DELETE'])
|
||||||
@login_required
|
@login_required
|
||||||
def external():
|
def external():
|
||||||
if 'external' in threads.keys():
|
if 'external' in threads.keys():
|
||||||
|
@ -112,8 +112,8 @@ def external():
|
||||||
else:
|
else:
|
||||||
threads['external']=None
|
threads['external']=None
|
||||||
|
|
||||||
data=request.get_json(force=True)
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
data=request.get_json(force=True)
|
||||||
if data['format']=='json-ga':
|
if data['format']=='json-ga':
|
||||||
threads['external'] = threading.Thread(target=app.admin.upload_json_ga, args=(data,))
|
threads['external'] = threading.Thread(target=app.admin.upload_json_ga, args=(data,))
|
||||||
threads['external'].start()
|
threads['external'].start()
|
||||||
|
@ -123,9 +123,14 @@ def external():
|
||||||
threads['external'].start()
|
threads['external'].start()
|
||||||
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
if request.method == 'PUT':
|
if request.method == 'PUT':
|
||||||
|
data=request.get_json(force=True)
|
||||||
threads['external'] = threading.Thread(target=app.admin.sync_external, args=(data,))
|
threads['external'] = threading.Thread(target=app.admin.sync_external, args=(data,))
|
||||||
threads['external'].start()
|
threads['external'].start()
|
||||||
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
|
if request.method == 'DELETE':
|
||||||
|
print('RESET')
|
||||||
|
app.admin.reset_external()
|
||||||
|
return json.dumps({}), 200, {'Content-Type': 'application/json'}
|
||||||
return json.dumps({}), 500, {'Content-Type': 'application/json'}
|
return json.dumps({}), 500, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
@app.route('/api/external/users')
|
@app.route('/api/external/users')
|
||||||
|
|
Loading…
Reference in New Issue