def pushtoken(self): ''' This is the method for testing authentication using your KeyIdentity Push Token Call it directly in your browser like this http(s)://server/auth/pushtoken ''' log.debug("[pushtoken] authenticating user") return render("/auth-push.mako")
def qrtoken(self): ''' This is the method for testing authentication using your LinOTP QR Token Call it directly in your browser like this http(s)://server/auth/qrtoken ''' log.debug("[qrtoken] authenticating user") return render("/auth-qrtoken.mako")
def challenge_response(self): """ This is the method for testing challenge-response authentication Call it directly in your browser like this http(s)://server/auth/challenge_response """ log.debug("[challenge_response] index, authenticating user") return render("/auth-challenge-response.mako")
def load_form(self): ''' This shows the enrollment form for a requested token type. implicit parameters are: :param type: token type :param scope: defines the rendering scope :return: rendered html of the requested token ''' res = '' try: try: act = self.request_params["type"] except KeyError: raise ParameterError("Missing parameter: 'type'", id=905) try: (tok, section, scope) = act.split('.') except Exception: return res if section != 'selfservice': return res if tok in tokenclass_registry: tclt = tokenclass_registry.get(tok) if hasattr(tclt, 'getClassInfo'): sections = tclt.getClassInfo(section, {}) if scope in list(sections.keys()): section = sections.get(scope) page = section.get('page') c.scope = page.get('scope') c.authUser = self.authUser html = page.get('html') res = render(os.path.sep + html).decode() res = remove_empty_lines(res) db.session.commit() return res except CompileException as exx: log.exception("[load_form] compile error while processing %r.%r:" "Exeption was %r" % (tok, scope, exx)) db.session.rollback() raise exx except Exception as exx: db.session.rollback() error = ('error (%r) accessing form data for: tok:%r, scope:%r' ', section:%r' % (exx, tok, scope, section)) log.exception(error) return '<pre>%s</pre>' % error
def webprovisiongoogletoken(self): """ This is the form for an google token to do web provisioning. """ try: c.actions = get_selfservice_actions(self.authUser) return render("/selfservice/webprovisiongoogle.mako") except Exception as exx: log.error("[webprovisiongoogletoken] failed with error: %r", exx) return sendError(response, exx)
def webprovisiongoogletoken(self): ''' This is the form for an google token to do web provisioning. ''' try: c.actions = getSelfserviceActions(self.authUser) return render('/selfservice/webprovisiongoogle.mako') except Exception as exx: log.exception("[webprovisiongoogletoken] failed with error: %r" % exx) return sendError(response, exx)
def login(self): """ Render the Manage-UI login page """ user = getUserFromRequest() if user: # user is authenticated, no login required. return redirect(url_for(".index")) c.debug = current_app.config["DEBUG"] return render("manage/login.mako")
def tokentype(self): """""" c.title = "TokenTypeInfo" ttinfo = [] ttinfo.extend(list(tokenclass_registry.keys())) for tok in tokenclass_registry: tclass_object = tokenclass_registry.get(tok) if hasattr(tclass_object, "getClassType"): ii = tclass_object.getClassType() ttinfo.append(ii) log.debug("[index] importers: %s", IMPORT_TEXT) c.tokeninfo = ttinfo return render("/manage/tokentypeinfo.mako").decode("utf-8")
def tokentype(self): ''' ''' c.title = 'TokenTypeInfo' ttinfo = [] ttinfo.extend(list(tokenclass_registry.keys())) for tok in tokenclass_registry: tclass_object = tokenclass_registry.get(tok) if hasattr(tclass_object, 'getClassType'): ii = tclass_object.getClassType() ttinfo.append(ii) log.debug("[index] importers: %s" % IMPORT_TEXT) c.tokeninfo = ttinfo return render('/manage/tokentypeinfo.mako').decode('utf-8')
def login(self): ''' render the selfservice login page ''' c.title = _("LinOTP Self Service Login") # ------------------------------------------------------------------ -- # prepare the realms and put the default realm on the top defaultRealm = getDefaultRealm() realmArray = [defaultRealm] for realm in getRealms(): if realm != defaultRealm: realmArray.append(realm) # ------------------------------------------------------------------ -- # prepare the global context c for the rendering context c.defaultRealm = defaultRealm c.realmArray = realmArray c.realmbox = getRealmBox() context = get_pre_context(c.audit['client']) mfa_login = context['mfa_login'] mfa_3_fields = context['mfa_3_fields'] c.otp = False c.mfa_3_fields = False if mfa_login and mfa_3_fields: c.mfa_3_fields = True response = Response(render('/selfservice/login.mako')) if request.cookies.get('user_selfservice'): remove_auth_cookie(request.cookies.get('user_selfservice')) response.delete_cookie('user_selfservice') return response
def login(self): """ render the selfservice login page """ c.title = _("LinOTP Self Service Login") # ------------------------------------------------------------------ -- # prepare the realms and put the default realm on the top defaultRealm = getDefaultRealm() realmArray = [defaultRealm] for realm in getRealms(): if realm != defaultRealm: realmArray.append(realm) # ------------------------------------------------------------------ -- # prepare the global context c for the rendering context c.defaultRealm = defaultRealm c.realmArray = realmArray c.realmbox = getRealmBox() context = get_pre_context(g.audit["client"]) mfa_login = bool(context["settings"]["mfa_login"]) mfa_3_fields = bool(context["settings"]["mfa_3_fields"]) c.mfa_login = mfa_login c.mfa_3_fields = mfa_login and mfa_3_fields response = Response(render("/selfservice/login.mako")) if request.cookies.get("user_selfservice"): remove_auth_cookie(request.cookies.get("user_selfservice")) response.delete_cookie("user_selfservice") return response
def add_dynamic_selfservice_enrollment(config, actions): """ add_dynamic_actions - load the html of the dynamic tokens according to the policy definition :param actions: the allowd policy actions for the current scope :type actions: array of actions names :return: hash of {tokentype : html for tab} """ dynanmic_actions = {} for tclass_object in set(tokenclass_registry.values()): tok = tclass_object.getClassType() if hasattr(tclass_object, "getClassInfo"): try: selfservice = tclass_object.getClassInfo( "selfservice", ret=None ) # # check if we have a policy in the token definition for the enroll if ( "enroll" in selfservice and "enroll" + tok.upper() in actions ): service = selfservice.get("enroll") tab = service.get("title") c.scope = tab.get("scope") t_file = tab.get("html") t_html = render(t_file).decode() """ remove empty lines """ t_html = "\n".join( [ line for line in t_html.split("\n") if line.strip() != "" ] ) e_name = "%s.%s.%s" % (tok, "selfservice", "enroll") dynanmic_actions[e_name] = t_html # # check if there are other selfserive policy actions policy = tclass_object.getClassInfo("policy", ret=None) if "selfservice" in policy: selfserv_policies = list(policy.get("selfservice").keys()) for action in actions: if action in selfserv_policies: # # now lookup, if there is an additional section # # in the selfservice to render service = selfservice.get(action) tab = service.get("title") c.scope = tab.get("scope") t_file = tab.get("html") t_html = render(t_file).decode() """ remove empty lines """ t_html = "\n".join( [ line for line in t_html.split("\n") if line.strip() != "" ] ) e_name = "%s.%s.%s" % (tok, "selfservice", action) dynanmic_actions[e_name] = t_html except Exception as exx: log.info( "[_add_dynamic_actions] no policy for tokentype " "%r found (%r)", tok, exx, ) return dynanmic_actions
def resync(self): ''' In this form, the user can resync an HMAC based OTP token by providing two OTP values ''' return render('/selfservice/resync.mako')
def landing(self): ''' This is the landing page for selfservice ''' c.tokenArray = getTokenForUser(self.authUser) return render('/selfservice/landing.mako')
def webprovisionoathtoken(self): ''' This is the form for an oathtoken to do web provisioning. ''' return render('/selfservice/webprovisionoath.mako')
def setpin(self): ''' In this form the user may set the OTP PIN, which is the static password he enters when logging in in front of the otp value. ''' return render('/selfservice/setpin.mako')
def history(self): ''' This is the form to display the history table for the user ''' return render('/selfservice/history.mako')
def tokeninfo(self): """ this returns the contents of /admin/show?serial=xyz in an html format """ param = self.request_params try: try: serial = param["serial"] except KeyError: raise ParameterError("Missing parameter: 'serial'") filterRealm = "" # check admin authorization res = checkPolicyPre("admin", "show", param) # check if policies are active at all # If they are not active, we are allowed to SHOW any tokens. filterRealm = ["*"] if res["active"] and res["realms"]: filterRealm = res["realms"] log.info( "[tokeninfo] admin >%s< may display the following realms:" " %s", res["admin"], filterRealm, ) log.info("[tokeninfo] displaying tokens: serial: %s", serial) toks = TokenIterator( User("", "", ""), serial, filterRealm=filterRealm ) # now row by row lines = [] for tok in toks: lines.append(tok) if len(lines) > 0: c.tokeninfo = lines[0] else: c.tokeninfo = {} for k in c.tokeninfo: if "LinOtp.TokenInfo" == k: try: # Try to convert string to Dictionary c.tokeninfo["LinOtp.TokenInfo"] = json.loads( c.tokeninfo["LinOtp.TokenInfo"] ) except BaseException: pass return render("/manage/tokeninfo.mako").decode("utf-8") except PolicyException as pe: log.error("[tokeninfo] Error during checking policies: %r", pe) db.session.rollback() return sendError(response, pe, 1) except Exception as exx: log.error("[tokeninfo] failed! %r", exx) db.session.rollback() return sendError(response, exx)
def audittrail(self): ''' This is the template for the audit trail TAB ''' c.title = "LinOTP Management - Audit Trail" return render('/manage/audit.mako').decode('utf-8')
def assign(self): ''' In this form the user may assign an already existing Token to himself. For this, the user needs to know the serial number of the Token. ''' return render('/selfservice/assign.mako')
def getmultiotp(self): ''' This function is used to retrieve multiple otp values for a given user or a given serial. If the user has more than one token, the list of the tokens is returend. method: gettoken/getmultiotp arguments: serial - the serial number of the token count - number of otp values to return curTime - used ONLY for internal testing: datetime.datetime object returns: JSON response ''' getotp_active = config.get("GETOTP_ENABLED") if not getotp_active: return sendError(response, "getotp is not activated.", 0) param = self.request_params ret = {} try: serial = getParam(param, "serial", required) count = int(getParam(param, "count", required)) curTime = getParam(param, "curTime", optional) view = getParam(param, "view", optional) r1 = checkPolicyPre('admin', 'getotp', param) log.debug("[getmultiotp] admin-getotp policy: %s", r1) max_count = checkPolicyPre('gettoken', 'max_count', param) log.debug("[getmultiotp] maxcount policy: %s", max_count) if count > max_count: count = max_count log.debug("[getmultiotp] retrieving OTP value for token %s", serial) ret = get_multi_otp(serial, count=int(count), curTime=curTime) ret["serial"] = serial g.audit['success'] = True db.session.commit() if view: c.ret = ret return render('/manage/multiotp_view.mako').decode('utf-8') else: return sendResult(response, ret, 0) except PolicyException as pe: log.exception("[getotp] gettoken/getotp policy failed: %r", pe) db.session.rollback() return sendError(response, str(pe), 1) except Exception as exx: log.exception("[getmultiotp] gettoken/getmultiotp failed: %r", exx) db.session.rollback() return sendError(response, "gettoken/getmultiotp failed: %r" % exx, 0)
def getmultiotp(self): """ This function is used to retrieve multiple otp values for a given user or a given serial. If the user has more than one token, the list of the tokens is returend. method: gettoken/getmultiotp arguments: serial - the serial number of the token count - number of otp values to return curTime - used ONLY for internal testing: datetime.datetime object returns: JSON response """ getotp_active = boolean(getFromConfig("linotpGetotp.active", False)) if not getotp_active: return sendError(response, "getotp is not activated.", 0) param = self.request_params ret = {} try: serial = getParam(param, "serial", required) count = int(getParam(param, "count", required)) curTime = getParam(param, "curTime", optional) view = getParam(param, "view", optional) r1 = checkPolicyPre("admin", "getotp", param) log.debug("[getmultiotp] admin-getotp policy: %s", r1) max_count = checkPolicyPre("gettoken", "max_count", param) log.debug("[getmultiotp] maxcount policy: %s", max_count) if count > max_count: count = max_count log.debug("[getmultiotp] retrieving OTP value for token %s", serial) ret = get_multi_otp(serial, count=int(count), curTime=curTime) ret["serial"] = serial g.audit["success"] = True db.session.commit() if view: c.ret = ret return render("/selfservice/multiotp_view.mako").decode( "utf-8") else: return sendResult(response, ret, 0) except PolicyException as pe: log.error("[getotp] gettoken/getotp policy failed: %r", pe) db.session.rollback() return sendError(response, pe, 1) except Exception as exx: log.error("[getmultiotp] gettoken/getmultiotp failed: %r", exx) db.session.rollback() return sendError(response, "gettoken/getmultiotp failed: %r" % exx, 0)
def add_dynamic_selfservice_enrollment(config, actions): ''' add_dynamic_actions - load the html of the dynamic tokens according to the policy definition :param actions: the allowd policy actions for the current scope :type actions: array of actions names :return: hash of {tokentype : html for tab} ''' dynanmic_actions = {} for tclass_object in set(tokenclass_registry.values()): tok = tclass_object.getClassType() if hasattr(tclass_object, 'getClassInfo'): try: selfservice = tclass_object.getClassInfo('selfservice', ret=None) # # check if we have a policy in the token definition for the enroll if 'enroll' in selfservice and 'enroll' + tok.upper( ) in actions: service = selfservice.get('enroll') tab = service.get('title') c.scope = tab.get('scope') t_file = tab.get('html') t_html = render(t_file).decode() ''' remove empty lines ''' t_html = '\n'.join([ line for line in t_html.split('\n') if line.strip() != '' ]) e_name = "%s.%s.%s" % (tok, 'selfservice', 'enroll') dynanmic_actions[e_name] = t_html # # check if there are other selfserive policy actions policy = tclass_object.getClassInfo('policy', ret=None) if 'selfservice' in policy: selfserv_policies = list(policy.get('selfservice').keys()) for action in actions: if action in selfserv_policies: # # now lookup, if there is an additional section # # in the selfservice to render service = selfservice.get(action) tab = service.get('title') c.scope = tab.get('scope') t_file = tab.get('html') t_html = render(t_file).decode() ''' remove empty lines ''' t_html = '\n'.join([ line for line in t_html.split('\n') if line.strip() != '' ]) e_name = "%s.%s.%s" % (tok, 'selfservice', action) dynanmic_actions[e_name] = t_html except Exception as e: log.info('[_add_dynamic_actions] no policy for tokentype ' '%s found (%r)' % (str(tok), e)) return dynanmic_actions
def reset(self): ''' In this form the user can reset the Failcounter of the Token. ''' return render('/selfservice/reset.mako')
def index(self): ''' This is the main function of the management web UI ''' try: c.debug = bool(config.get('debug', False)) c.title = "LinOTP Management" admin_user = getUserFromRequest(request) if 'login' in admin_user: c.admin = admin_user['login'] log.debug("[index] importers: %s" % IMPORT_TEXT) c.importers = IMPORT_TEXT help_version = c.version[:c.version.find('.')] c.help_url = config.get('HELP_URL').format(help_version) # -------------------------------------------------------------- -- # check for support of setting admin password c.admin_can_change_password = False if ('linotpadmin.user' in config and 'linotpadmin.password' in config): c.admin_can_change_password = True # -------------------------------------------------------------- -- # add render info for token type config confs = _getTokenTypeConfig('config') token_config_tab = {} token_config_div = {} for conf in confs: tab = '' div = '' try: # loc = conf +'_token_settings' tab = confs.get(conf).get('title') # tab = '<li ><a href=#'+loc+'>'+tab+'</a></li>' div = confs.get(conf).get('html') # div = +div+'</div>' except Exception as e: log.debug( '[index] no config info for token type %s (%r)' % (conf, e)) if tab is not None and div is not None and len( tab) > 0 and len(div) > 0: token_config_tab[conf] = tab token_config_div[conf] = div c.token_config_tab = token_config_tab c.token_config_div = token_config_div # add the enrollment fragments from the token definition # tab: <option value="ocra">${_("OCRA - challenge/response Token")}</option> # div: "<div id='"+ tt + "'>"+enroll+"</div>" enrolls = _getTokenTypeConfig('init') token_enroll_tab = {} token_enroll_div = {} for conf in enrolls: tab = '' div = '' try: tab = enrolls.get(conf).get('title') div = enrolls.get(conf).get('html') except Exception as e: log.debug( '[index] no enrollment info for token type %s (%r)' % (conf, e)) if tab is not None and div is not None and len( tab) > 0 and len(div) > 0: token_enroll_tab[conf] = tab token_enroll_div[conf] = div c.token_enroll_tab = token_enroll_tab c.token_enroll_div = token_enroll_div c.tokentypes = _getTokenTypes() # Use HTTP_X_FORWARDED_HOST in preference to HTTP_HOST # in case we're running behind a reverse proxy http_host = request.environ.get("HTTP_X_FORWARDED_HOST", '') if not http_host: http_host = request.environ.get("HTTP_HOST") url_scheme = request.environ.get("wsgi.url_scheme") c.logout_url = "%s://log-me-out:fake@%s/manage/logout" % ( url_scheme, http_host) Session.commit() ren = render('/manage/manage-base.mako') return ren except PolicyException as pe: log.exception("[index] Error during checking policies: %r" % pe) Session.rollback() return sendError(response, str(pe), 1) except Exception as ex: log.exception("[index] failed! %r" % ex) Session.rollback() raise finally: Session.close()
def getotp(self): ''' In this form, the user can retrieve OTP values ''' return render('/selfservice/getotp.mako')
def policies(self): ''' This is the template for the policies TAB ''' c.title = "LinOTP Management - Policies" return render('/manage/policies.mako').decode('utf-8')
def unassign(self): ''' In this form the user may select a token of his own and unassign this token. ''' return render('/selfservice/unassign.mako')
def tokeninfo(self): ''' this returns the contents of /admin/show?serial=xyz in an html format ''' param = self.request_params try: try: serial = param['serial'] except KeyError: raise ParameterError("Missing parameter: 'serial'") filterRealm = "" # check admin authorization res = checkPolicyPre('admin', 'show', param) # check if policies are active at all # If they are not active, we are allowed to SHOW any tokens. filterRealm = ["*"] if res['active'] and res['realms']: filterRealm = res['realms'] log.info("[tokeninfo] admin >%s< may display the following realms:" " %s" % (res['admin'], filterRealm)) log.info("[tokeninfo] displaying tokens: serial: %s", serial) toks = TokenIterator(User("", "", ""), serial, filterRealm=filterRealm) # now row by row lines = [] for tok in toks: lines.append(tok) if len(lines) > 0: c.tokeninfo = lines[0] else: c.tokeninfo = {} for k in c.tokeninfo: if "LinOtp.TokenInfo" == k: try: # Try to convert string to Dictionary c.tokeninfo['LinOtp.TokenInfo'] = json.loads( c.tokeninfo['LinOtp.TokenInfo']) except: pass return render('/manage/tokeninfo.mako').decode('utf-8') except PolicyException as pe: log.exception("[tokeninfo] Error during checking policies: %r" % pe) Session.rollback() return sendError(response, str(pe), 1) except Exception as e: log.exception("[tokeninfo] failed! %r" % e) Session.rollback() return sendError(response, e) finally: Session.close()
def delete(self): ''' In this form the user may select a token of his own and delete this token. ''' return render('/selfservice/delete.mako')