def roles_edit(): logger = logging.getLogger("TMI.roles_edit") def pop_session(): session.pop("roles_initial", None) session.pop("roles", None) # TODO: This needs to be a decorator if not session.get('user_id', False): return redirect(COMMON_URL_LOGIN) user = User.get_by_id(session['user_id']) if user is None or not RolesUsers.user_has_role(user, ["EDIT-ROLE", "ADD-USER"]): # this should never happen... logout if it does... logger.error("Unable to find user id {}".format(session['user_id'])) session.pop('user_id', None) redirect(COMMON_URL_INDEX) w = WrapBokeh(PAGE_URL, logger) w.add( "sel_uname", Select(options=[], value=None, title="Select User", css_classes=['sel_uname'])) w.add("cbg_roles", CheckboxGroup(labels=[], active=[], css_classes=['cbg_roles'])) w.add("b_submit", Button(label="Update", css_classes=['b_submit'])) w.add("b_cancel", Button(label="Cancel", css_classes=['b_cancel'])) w.init() user = User.get_by_id(session['user_id']) if user is None: logger.error("Unable to find user id {}".format(session['user_id'])) session.pop('user_id') redirect(COMMON_URL_INDEX) # Create a dominate document, see https://github.com/Knio/dominate # this line should go after any "return redirect" statements w.dominate_document() url_page_css(w.dom_doc, PAGE_URL) args, _redirect_page_metrics = w.process_req(request) if not args: return _redirect_page_metrics logger.info("{} : args {}".format(PAGE_URL, args)) redir, url = toolbar_menu_redirect(args) if redir: pop_session() return redirect(url) if args.get("b_cancel", False): pop_session() return redirect(COMMON_URL_LAND) updated = False if args.get( "b_submit", False) and session["roles_initial"] != w.get("cbg_roles").active: # need to convert the CheckboxGroup list indexes to Role IDs selected_idexes = w.get("cbg_roles").active if selected_idexes == [None]: selected_idexes = [] selected_roles = [] for idx in selected_idexes: selected_roles.append(session["roles"][idx]) edit_user = User.get_username(w.get("sel_uname").value) logger.info("{} updated roles {}".format(edit_user.username, selected_roles)) success = User.update_roles(edit_user.username, selected_roles) if success: updated = True doc_layout = layout(sizing_mode="fixed") page_toolbar_menu(w, doc_layout, args, user) # populate users all_users = User.get_username(None, all=True) sel_users = [("Select", "Select User")] for u in all_users: if u.username in app.config["app"]["user"]["protected"]: continue sel_users.append((u.username, u.username)) w.get("sel_uname").options = sel_users w.get("sel_uname").value = args.get("sel_uname", None) # last value or none session["roles_initial"] = [] # new selection was done, update the roles if w.get("sel_uname").value not in ['Select', None]: edit_user = User.get_username(w.get("sel_uname").value) roles = [] user_ids = [] session["roles"] = [] for _id, _name, _desc in Role.get_all(): session["roles"].append(_name) roles.append(_desc) if RolesUsers.user_has_role(edit_user, _name): user_ids.append(roles.index(_desc)) w.get("cbg_roles").labels = roles w.get("cbg_roles").active = user_ids if args['callerWidget'] == 'sel_uname' or updated: session["roles_initial"] = w.get("cbg_roles").active if args["callerWidget"] == 'cbg_roles': if len(args['cbg_roles']) == 0: w.get("cbg_roles").active = [] else: w.get("cbg_roles").active = [ int(i) for i in args['cbg_roles'].split(",") ] # change submit button if there is a change in roles if session["roles_initial"] == w.get("cbg_roles").active: w.add_css( "b_submit", { 'button': { 'background-color': GUI.BUTTON_DISABLED_GRAY, 'pointer-events': None } }) else: w.add_css("b_submit", {'button': { 'background-color': GUI.BUTTON_ENABLED_GREEN }}) w.add_css("b_cancel", {'button': {'background-color': GUI.BUTTON_CANCEL}}) wbox = widgetbox(w.get("sel_uname"), w.get("cbg_roles"), w.get("b_submit"), w.get("b_cancel")) left_margin = int(int(args.get("windowWidth", 800)) * 0.2) doc_layout.children.append(row([Spacer(width=left_margin), wbox])) return w.render(doc_layout)