diff --git a/extapp/index.html b/extapp/index.html index d49dff1..cc00777 100644 --- a/extapp/index.html +++ b/extapp/index.html @@ -6,11 +6,11 @@ - - + \ No newline at end of file diff --git a/extapp/js/rolescontroller.js b/extapp/js/rolescontroller.js index 14ac346..d58645d 100644 --- a/extapp/js/rolescontroller.js +++ b/extapp/js/rolescontroller.js @@ -3,35 +3,169 @@ class ExtAppRoleController extends HTMLElement{ #boot; #roles; #users; - #mappings; #serviceurl; #appid; + #groupid; #loading = false; + + #header; + #section; + + #userfilter = null; + #rolefilter = null; constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") this.#serviceurl = this.#boot.url + this.attachShadow({ mode: "open" }); } connectedCallback(){ this.#appid = this.getAttribute("appid") + this.#groupid = this.getAttribute("groupid") if(!this.#loading){ this.#loading = true this.loadData() } + this.renderStructure() } + renderStructure(){ + this.shadowRoot.innerHTML = ` + + +
+
+ ` + this.#header = this.shadowRoot.querySelector("header") + this.#section = this.shadowRoot.querySelector("section") + } + + renderHeader(){ + this.#header.innerHTML = ` +
+ +
+ ${ + this.#roles.map(r=>{ + return r.name === 'uma_protection' ? '' : ` +
+ +
+ ` + }).join("") + } +
+
` + this.attachHeaderEvents() + } + + renderUsers(){ + var users = this.#rolefilter && this.#rolefilter.length ? + this.#users.filter(u=>{ + const assigned = u.mappings.map(m=>m.id) + return this.#rolefilter.reduce((a,f)=>{ + return a && (assigned.indexOf(f) !== -1) + }, true) + }) : this.#users + users = this.#userfilter ? + this.#users.filter(u=>{ + return u.username.toLowerCase().startsWith(this.#userfilter) || + u.lastName.toLowerCase().startsWith(this.#userfilter) || + u.firstName.toLowerCase().startsWith(this.#userfilter) || + u.email.toLowerCase().startsWith(this.#userfilter)}) : users + const html = ` + + ` + this.#section.innerHTML = html + this.attachSectionEvents() + } + + renderMappings(u){ + const html = ` + + ` + return html + } + + isAssigned(u, r){ + return u.mappings && u.mappings.filter(m=>m.id === r.id).length > 0 + } + + attachSectionEvents(){ + this.#section.querySelector("ul[name=users]").addEventListener("click", ev=>{ + const tgt = ev.target + if(tgt.getAttribute("name") === "role"){ + const uid = tgt.getAttribute("data-userid") + const rid = tgt.getAttribute("data-roleid") + if(tgt.classList.contains("active")){ + this.toggleMapping(uid, rid) + }else{ + this.toggleMapping(uid, rid, true) + } + } + }) + } + + attachHeaderEvents(){ + this.#header.querySelector("#search_user_filter").addEventListener("input", ev=>{ + this.#userfilter = ev.target.value.toLowerCase() + this.renderUsers() + }) + + this.#header.querySelector("div.role-filter").addEventListener("change", ev=>{ + this.#rolefilter = Array.prototype.slice.call(ev.currentTarget.querySelectorAll("input:checked")).map(r=>r.name) + this.renderUsers() + }) + } + loadData(){ Promise.all([ this.loadEligibleUsers(), this.loadRoles() ]).then(()=>{ - console.log("Done. Ui should be complete now") + //console.log("Done. Ui should be complete now") }).catch(err=>alert(err)) } loadEligibleUsers(){ - const url = this.#serviceurl + `/admin/realms/d4science/clients/${this.#appid}/roles/eligible/users?briefRepresentation=true&max=-1&first=0` + const url = this.#serviceurl + `/admin/realms/d4science/groups/${this.#groupid}/members?first=0&max=-1&briefRepresentation=true` return this.#boot.secureFetch(url).then(resp=>{ if(resp.ok){ return resp.json() @@ -41,11 +175,10 @@ class ExtAppRoleController extends HTMLElement{ throw "Fetching users: Unspecified error" } }).then(json=>{ - console.log("Fetched eligible users can show table") this.#users = json - return loadMappings() - }).then(()=>{ - console.log(this.#mappings) + const prom = this.loadMappings() + this.renderUsers() + return prom }) } @@ -61,30 +194,53 @@ class ExtAppRoleController extends HTMLElement{ } }).then(json=>{ this.#roles = json - console.log("Roles loaded, could draw header") + this.renderHeader() }) } loadMappings(){ return Promise.all( - this.#users.forEach(u => { - const url = this.#serviceurl + `/admin/realms/d4science/users/${u.id}/clients/${this.#appid}/roles` - this.#boot.secureFetch(url).then(resp=>{ - if(resp.ok){ - return resp.json() - }else if(resp.status === 403){ - throw "Fetching role mappings: You are not allowed to manage roles for this application." - }else{ - throw "Fetching role mappings: Unspecified error" - } - }).then(json=>{ - u.mappings = json - console.log(`Fetched mappings for user ${u.id} can update the proper table`) - }) + this.#users.map(u => { + return this.loadMapping(u) }) ) } + loadMapping(u){ + const url = this.#serviceurl + `/admin/realms/d4science/users/${u.id}/role-mappings/clients/${this.#appid}` + return this.#boot.secureFetch(url).then(resp=>{ + if(resp.ok){ + return resp.json() + }else if(resp.status === 403){ + throw "Fetching role mappings: You are not allowed to manage roles for this application." + }else{ + throw "Fetching role mappings: Unspecified error" + } + }).then(json=>{ + u.mappings = json + this.renderUsers() + }) + } + + toggleMapping(uid, rid, add){ + const url = this.#serviceurl + `/admin/realms/d4science/users/${uid}/role-mappings/clients/${this.#appid}` + const role = this.#roles.filter(r=>r.id === rid) + if(role.length !== 1){ + alert("Something went wrong with looking up the role") + return + } + this.#boot.secureFetch(url, { method : add ? "POST" : "DELETE", body : JSON.stringify(role), headers : { "Content-Type" : "application/json"}}).then(resp=>{ + if(resp.ok){ + return resp.text() + }else if(resp.status === 403){ + throw "Assigning or removing role: You are not allowed to manage roles for this application." + }else{ + throw "Assigning or removing role: Unspecified error" + } + }).then(()=>{ + return this.loadMapping(this.#users.filter(u=>u.id === uid)[0]) + }).catch(err=>alert(err)) + } } window.customElements.define('d4s-extapp-role-manager', ExtAppRoleController); \ No newline at end of file