From 9dc210d62d675191530adecf3d63e90503d8395e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 1 Jun 2021 00:48:45 +0200 Subject: [PATCH] admin progress --- admin/src/admin/lib/admin.py | 37 +++++------ admin/src/admin/lib/keycloak_client.py | 85 +++++++++++++++++++++++--- admin/src/admin/static/js/external.js | 7 +++ admin/src/admin/views/MenuViews.py | 2 +- 4 files changed, 105 insertions(+), 26 deletions(-) diff --git a/admin/src/admin/lib/admin.py b/admin/src/admin/lib/admin.py index 3a68dcf..1af82e7 100644 --- a/admin/src/admin/lib/admin.py +++ b/admin/src/admin/lib/admin.py @@ -30,19 +30,6 @@ class Admin(): sleep(2) 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 while not ready: try: @@ -390,6 +377,7 @@ class Admin(): thegroup['path']='' thegroup={**moodle_exists[0], **thegroup} thegroup['moodle']=True + thegroup['moodle_id']=thegroup['id'] else: thegroup['moodle']=False @@ -400,11 +388,12 @@ class Admin(): "path":''} thegroup={**nextcloud, **thegroup} thegroup['nextcloud']=True + thegroup['nextcloud_id']=thegroup['id'] else: thegroup['nextcloud']=False groups.append(thegroup) - + return groups def get_external_users(self): @@ -450,10 +439,21 @@ class Admin(): u['groups']=u['groups']+[g['name']] return True - def sync_external(self): + def sync_external(self,ids): + pprint(ids) + log.warning('Starting sync to keycloak') + self.sync_to_keycloak() + log.warning('Starting sync to moodle') + self.sync_to_moodle() + log.warning('Starting sync to nextcloud') + self.sync_to_nextcloud() + log.warning('All syncs finished') + + def sync_to_keycloak(self): for u in self.external['users']: log.info('Creating user: '+u['username']) - self.keycloak.add_user(u['username'],u['first'],u['last'],u['email'],'1Provaprovaprova',group=u['groups'][0]) + self.keycloak.add_user_with_groups_and_role(u['username'],u['first'],u['last'],u['email'],'1Provaprovaprova',u['roles'],u['groups']) + # self.keycloak.add_user(u['username'],u['first'],u['last'],u['email'],'1Provaprovaprova',group=u['groups'][0]) def sync_to_moodle(self): for u in self.internal['users']: @@ -526,11 +526,12 @@ class Admin(): log.error(traceback.format_exc()) log.warning('Could not remove users: '+','.join(usernames)) - def delete_moodle_groups(self): + + def delete_keycloak_groups(self): for g in self.internal['groups']: if not g['keycloak']: continue # Do not remove admin group. It should not exist in keycloak, only in nextcloud - if g['name'] == ['admin']: continue + if g['name'] in ['admin','manager','teacher','student']: continue log.info('Removing keycloak group: '+g['name']) try: self.keycloak.delete_group(g['id']) diff --git a/admin/src/admin/lib/keycloak_client.py b/admin/src/admin/lib/keycloak_client.py index e38a62f..fa1fae3 100644 --- a/admin/src/admin/lib/keycloak_client.py +++ b/admin/src/admin/lib/keycloak_client.py @@ -134,9 +134,17 @@ class KeycloakClient(): self.keycloak_admin.group_user_add(uid,gid) return uid - def add_user_role(self,client_id,user_id,role_id,role_name): + def remove_user_group(self,user_id,group_id): self.connect() - return self.keycloak_admin.assign_client_role(client_id=client_id, user_id=user_id, role_id=role_id, role_name="test") + pass + + # def add_user_role(self,user_id,role_id): + # self.connect() + # return self.keycloak_admin.assign_role(client_id=client_id, user_id=user_id, role_id=role_id, role_name="test") + + def remove_user_role(self,user_id,role_id): + self.connect() + pass def delete_user(self,userid): self.connect() @@ -146,34 +154,97 @@ class KeycloakClient(): self.connect() return self.keycloak_admin.get_user_groups(user_id=userid) + def add_user_client_role(self,client_id,user_id,role_id,role_name): + self.connect() + return self.keycloak_admin.assign_client_role(client_id=client_id, user_id=user_id, role_id=role_id, role_name="test") + ## GROUPS def get_groups(self,with_subgroups=True): self.connect() groups = self.keycloak_admin.get_groups() subgroups=[] + subgroups1=[] + # This needs to be recursive function if with_subgroups: for group in groups: if len(group['subGroups']): for sg in group['subGroups']: subgroups.append(sg) - return groups+subgroups + # for sgroup in subgroups: + # if len(sgroup['subGroups']): + # for sg1 in sgroup['subGroups']: + # subgroups1.append(sg1) + + return groups+subgroups+subgroups1 def get_group(self,path,recursive=True): self.connect() return self.keycloak_admin.get_group_by_path(path=path,search_in_subgroups=recursive) - def add_group(self,name,parent=None): + def add_group(self,name,parent=None,skip_exists=False): 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) def delete_group(self,group_id): self.connect() return self.keycloak_admin.delete_group(group_id=group_id) + def group_user_add(self,user_id,group_id): + self.connect() + return self.keycloak_admin.group_user_add(user_id, group_id) + + def add_group_tree(self,path): + parts=path.split('/') + sub='' + for i in range(1,len(parts+1)): + try: + if i == 1: parent_id=self.add_group(parts[i]) + except: + # Main already exists?? What a fail! + parent_id=self.get_group(parent_id)['id'] + continue + self.add_group(parts[i],parent_id) + + def add_user_with_groups_and_role(self,username,first,last,email,password,role,groups): + ## Add user + uid=self.add_user(username,first,last,email,password) + ## Add user to role + print('User uid: '+str(uid)+ ' role: '+str(role)) + try: + therole=role[0] + except: + therole='' + print(self.assign_realm_roles(uid,role)) + ## Create groups in user + for g in groups: + log.warning('Creating keycloak group: '+g) + parts=g.split('/') + parent_path=None + for i in range(1,len(parts)): + # parent_id=None if parent_path==None else self.get_group(parent_path)['id'] + try: + self.add_group(parts[i],parent_path,skip_exists=True) + except: + log.warning('Group '+str(parent_path)+ ' already exists. Skipping creation') + pass + if parent_path is None: + thepath='/'+parts[i] + else: + thepath=parent_path+'/'+parts[i] + if thepath=='/': continue + gid=self.get_group(path=thepath)['id'] + + self.keycloak_admin.group_user_add(uid,gid) + + + if parent_path==None: parent_path='' + parent_path=parent_path+'/'+parts[i] + + + self.group_user_add(uid,gid) + + ## ROLES def get_roles(self): self.connect() diff --git a/admin/src/admin/static/js/external.js b/admin/src/admin/static/js/external.js index 7187a98..482c888 100644 --- a/admin/src/admin/static/js/external.js +++ b/admin/src/admin/static/js/external.js @@ -13,9 +13,15 @@ $(document).ready(function() { }); $('.btn-sync').on('click', function () { + ids={} + $.each(users_table.rows().data(),function(key, value){ + ids[value['id']]=value['role'] + }); + console.log(ids) $.ajax({ type: "PUT", url:"/isard-sso-admin/external", + data: JSON.stringify(ids), success: function(data) { console.log('SUCCESS') @@ -31,6 +37,7 @@ $(document).ready(function() { }); $("#modalImport #send").on('click', function(e){ + console.log(users_table.rows().data()) var form = $('#modalImportForm'); form.parsley().validate(); if (form.parsley().isValid()){ diff --git a/admin/src/admin/views/MenuViews.py b/admin/src/admin/views/MenuViews.py index c106718..93cf2e1 100644 --- a/admin/src/admin/views/MenuViews.py +++ b/admin/src/admin/views/MenuViews.py @@ -72,7 +72,7 @@ def external(): if request.method == 'POST': return json.dumps(app.admin.upload_json(request.get_json(force=True))), 200, {'Content-Type': 'application/json'} if request.method == 'PUT': - return json.dumps(app.admin.sync_external()), 200, {'Content-Type': 'application/json'} + return json.dumps(app.admin.sync_external(request.get_json(force=True))), 200, {'Content-Type': 'application/json'} return render_template('pages/external.html', title="External", nav="External") @app.route('/isard-sso-admin/external_users_list')