def _initalGetRealms(): ''' initaly parse all config entries, and extract the realm definition :return : a dict with all realm definitions :rtype : dict of definitions ''' Realms = {} defRealmConf = "linotp.useridresolver" realmConf = "linotp.useridresolver.group." defaultRealmDef = "linotp.DefaultRealm" defaultRealm = None dc = getLinotpConfig() for entry in dc: if entry.startswith(realmConf): #the realm might contain dots "." # so take all after the 3rd dot for realm r = {} realm = entry.split(".", 3) theRealm = realm[3].lower() r["realmname"] = realm[3] r["entry"] = entry ##resids = env.config[entry] resids = getFromConfig(entry) # we adjust here the *ee resolvers from the config # so we only have to deal with the un-ee resolvers in the server # which match the available resolver classes resids = resids.replace("useridresolveree.", "useridresolver.") r["useridresolver"] = resids.split(",") Realms[theRealm] = r if entry == defRealmConf: r = {} theRealm = "_default_" r["realmname"] = theRealm r["entry"] = defRealmConf #resids = env.config[entry] resids = getFromConfig(entry) r["useridresolver"] = resids.split(",") defaultRealm = "_default_" Realms[theRealm] = r if entry == defaultRealmDef: defaultRealm = getFromConfig(defaultRealmDef) if defaultRealm is not None: _setDefaultRealm(Realms, defaultRealm) return Realms
def get_legacy_provider(provider_type): """ return a dict with legacy email or sms providers :param provider_type: either sms or email :return: dict with the provider """ provider = {} defintion = Legacy_Provider.get(provider_type, {}) if not defintion: raise Exception('unknow provider type %r' % provider_type) # find out, which providers we have config = getLinotpConfig() for key, translation in defintion.items(): if key in config: provider[translation] = config[key] if 'enc' + key in config: provider[translation] = config['enc' + key] # if Config is not avail then nothing has been defined before if 'Config' not in provider: provider = {} return provider
def getResolverList(filter_resolver_type=None): ''' Gets the list of configured resolvers :param filter_resolver_type: Only resolvers of the given type are returned :type filter_resolver_type: string :rtype: Dictionary of the resolvers and their configuration ''' Resolvers = {} resolvertypes = get_resolver_types() conf = getLinotpConfig() for entry in conf: for typ in resolvertypes: if entry.startswith("linotp." + typ): # the realm might contain dots "." # so take all after the 3rd dot for realm r = {} resolver = entry.split(".", 3) # An old entry without resolver name if len(resolver) <= 3: break r["resolvername"] = resolver[3] r["entry"] = entry r["type"] = typ if (filter_resolver_type is None) or (filter_resolver_type and filter_resolver_type == typ): Resolvers[resolver[3]] = r # Dont check the other resolver types break return Resolvers
def getResolverList(filter_resolver_type=None): ''' Gets the list of configured resolvers :param filter_resolver_type: Only resolvers of the given type are returned :type filter_resolver_type: string :rtype: Dictionary of the resolvers and their configuration ''' Resolvers = {} resolvertypes = get_resolver_types() conf = getLinotpConfig() for entry in conf: for typ in resolvertypes: if entry.startswith("linotp." + typ): #the realm might contain dots "." # so take all after the 3rd dot for realm r = {} resolver = entry.split(".", 3) # An old entry without resolver name if len(resolver) <= 3: break r["resolvername"] = resolver[3] r["entry"] = entry r["type"] = typ if (filter_resolver_type is None) or ( filter_resolver_type and filter_resolver_type == typ): Resolvers[resolver[3]] = r # Dont check the other resolver types break return Resolvers
def get_legacy_provider(provider_type): """ return a dict with legacy email or sms providers :param provider_type: either sms or email :return: dict with the provider """ provider = {} config = getLinotpConfig() defintion = Legacy_Provider.get(provider_type, {}) if not defintion: raise Exception('unknown provider type %r' % provider_type) for key, translation in defintion.items(): if key in config: provider[translation] = config[key] # prepare for return legacy_provider = {} if "Config" in provider: provider['Default'] = False legacy_provider[Legacy_Provider_Name] = provider return legacy_provider
def test_getuserlist_case_sensitive_resolver_names(fthsm, app, admin_res): g.request_context["Config"] = getLinotpConfig() # This sucks. g.request_context["CacheManager"] = app.cache # This sucks even worse. g.request_context["UserLookup"] = {} # Don't get me started. admin_realm_name = app.config["ADMIN_REALM_NAME"] admin_resolvers_key = f"useridresolver.group.{admin_realm_name}" admin_resolvers = getFromConfig(admin_resolvers_key, "") _, _, aci = admin_resolvers.rpartition(".") # As before, if we make the RCI uppercase and the `getUserList()` function # still returns a user list, then the comparison must have been # case-insensitive. With a case-sensitive comparison, the result should # be empty. search_user = User( login="******", realm=admin_realm_name, resolver_config_identifier=aci.upper(), ) user_list = getUserList({}, search_user) assert ( not user_list ), "getUserList resolver name comparison is not case-sensitive"
def test_getsearchfields_case_sensitive_resolver_names(fthsm, app): g.request_context["Config"] = getLinotpConfig() # This sucks. g.request_context["CacheManager"] = app.cache # This sucks even worse. admin_realm_name = app.config["ADMIN_REALM_NAME"] admin_resolvers_key = f"useridresolver.group.{admin_realm_name}" admin_resolvers = getFromConfig(admin_resolvers_key, "") _, _, aci = admin_resolvers.rpartition(".") user = User( login="******", realm=admin_realm_name, resolver_config_identifier=aci ) # If the user's resolver config identifier matches its resolver, then the # `getSearchFields` function should return a set of search fields. If there # is no match, the result should be empty. Hence if we tweak the RCI to be # the uppercase version, then if the comparison is case-sensitive the result # should be empty. user.resolver_config_identifier = user.resolver_config_identifier.upper() search_fields = getSearchFields(user) assert ( not search_fields ), "getSearchFields resolver name comparison is not case-sensitive"
def getResolverInfo(resolvername): ''' return the resolver info of the given resolvername :param resolvername: the requested resolver :type resolvername: string :return : dict of resolver description ''' resolver_dict = {} typ = "" resolvertypes = get_resolver_types() descr = {} conf = getLinotpConfig() for entry in conf: for typ in resolvertypes: # get the typed values of the descriptor! resolver_conf = get_resolver_classConfig(typ) if typ in resolver_conf: descr = resolver_conf.get(typ).get('config', {}) else: descr = resolver_conf if entry.startswith("linotp." + typ) and entry.endswith(resolvername): # the realm might contain dots "." # so take all after the 3rd dot for realm resolver = entry.split(".", 3) # An old entry without resolver name if len(resolver) <= 3: break value = conf.get(entry) if resolver[2] in descr: configEntry = resolver[2] if descr.get(configEntry) == 'password': # do we already have the decrypted pass? if 'enc' + entry in conf: value = conf.get('enc' + entry) else: # if no, we take the encpass and decrypt it value = conf.get(entry) try: en = decryptPassword(value) value = en except: log.info("Decryption of resolver passwd failed: compatibility issue?") resolver_dict[ resolver[2] ] = value # Dont check the other resolver types break return { "type" : typ, "data" : resolver_dict, "resolver" : resolvername}
def loadProvider(provider_type, provider_name=None): """ interface for the provider user like email token or sms token :param provider_type: 'email' or 'sms :param provider_name: the name of the provider configuration :return: the instantiated provider with already loaded configuration """ # if no provider is given, we try to lookup the default if not provider_name: config = getLinotpConfig() default_provider_key = Default_Provider_Key[provider_type] if default_provider_key in config: provider_name = config[default_provider_key] if provider_name: providers = getProvider(provider_type, provider_name=provider_name) provider_info = providers.get(provider_name) else: # if no given provider and no default, try to fallback to the old one provider_info = get_legacy_provider(provider_type=provider_type) if not provider_info: raise Exception('Unable to load provider: %r' % provider_name) provider_class = provider_info.get('Class') try: provider_class_obi = _load_provider_class(provider_class) provider = provider_class_obi() except Exception as exc: log.exception("Failed to load provider: %r" % exc) raise exc provider_config = {} config = provider_info['Config'] # backward compatibility hack: fix the handling of multiline config entries lconfig = [] lines = config.splitlines() for line in lines: line = line.strip('\\') if len(line) > 0: lconfig.append(line) config = " ".join(lconfig) try: provider_config = json.loads(config) except ValueError as exx: log.exception('Failed to load provider config %r', config) raise ValueError('Failed to load provider config:%r %r' % (config, exx)) provider.loadConfig(provider_config) return provider
def getResolverObject(resolvername): """ get the resolver instance from a resolver name spec - either take the class from the request context - or create one from the global object list + init with resolver config :remark: the resolver object is preserved in the request context, so that a resolver could preserve a connection durung a request :param resolvername: the resolver string as from the token including the config as last part :return: instance of the resolver with the loaded config """ r_obj = None ### this patch is a bit hacky: ## the normal request has a request context, where it retrieves ## the resolver info from and preserves the loaded resolvers for reusage ## But in case of a authentication request (by a redirect from a 401) ## the caller is no std request and the context object is missing :-( ## The solution is to deal with local references, either to the ## global context or to local data (where we have no reuse of the resolver) resolvers_loaded = {} try: if hasattr(context, 'resolvers_loaded') == False: setattr(context, 'resolvers_loaded', {}) resolvers_loaded = context.resolvers_loaded except Exception as exx: resolvers_loaded = {} ## test if there is already a resolver of this kind loaded if resolvername in resolvers_loaded: return resolvers_loaded.get(resolvername) ## no resolver - so instatiate one else: parts = resolvername.split('.') if len(parts) > 2: re_name = '.'.join(parts[:-1]) r_obj_class = get_resolver_class(re_name) if r_obj_class is None: log.error("unknown resolver class %s " % resolvername) return r_obj ## create the resolver instance and load the config r_obj = r_obj_class() conf = resolvername.split(".")[-1] if r_obj is not None: config = getLinotpConfig() r_obj.loadConfig(config, conf) resolvers_loaded[resolvername] = r_obj return r_obj
def delProvider(provider_type, provider_name): """ delete a provider :param provider_type: the type of Provider: sms or email :param provider_name: the name of the provider :return: the number of deleted entries """ detail = {} prefix = Provider_types.get(provider_type, {}).get('prefix') if not prefix: raise Exception('unknown provider type %r' % provider_type) # find out, which providers we have config = getLinotpConfig() # if the provider is the default one, we don't delete this one default_provider_key = Default_Provider_Key[provider_type] if default_provider_key in config: default_provider = config[default_provider_key] if provider_name == default_provider: detail = {'message': _('Default provider could not be deleted!')} ret = 0 return ret, detail # check that there are no references left provider_policies = _lookup_provider_policies(provider_type) if provider_name in provider_policies: detail = { 'message': (_('Unable to delete - provider used in policies!\n[%s]') % ','.join(provider_policies[provider_name])) } ret = 0 return ret, detail del_entries = set() provider = prefix + provider_name # first delete the provider root entry if provider in config: del_entries.add(provider) # now lookup the all decent entries provider_prefix = provider + '.' for key in config.keys(): if key[:len(provider_prefix)] == provider_prefix: del_entries.add(key) # when all entries are gathered, we can now delete them all for del_entry in del_entries: removeFromConfig(del_entry) ret = len(del_entries) return ret, detail
def get_all_new_providers(provider_type, show_managed_config=False): """ get all providers of the new format :param provider_type: the type of the provider :return: dict with all providers """ providers = {} provider_names = {} # find out, which provider type we have, currently only push, sms or email prefix = Provider_types.get(provider_type, {}).get('prefix') if not prefix: raise Exception('unknown provider type %r' % provider_type) # find out, which providers we have config = getLinotpConfig() # first identify all providers by its name for key, value in config.items(): if key[:len(prefix)] == prefix: parts = key.split('.') if len(parts) == 3: provider_names[key] = value for provider, provider_class in provider_names.items(): defintion = {} defintion['Class'] = provider_class prefix = provider + '.' for key, value in config.items(): if key[:len(prefix)] == prefix: if 'enc' + key in config: value = config.get('enc' + key) entry = key.replace(prefix, '') defintion[entry] = value defintion['Default'] = False # in case of a managed provider, the configuration is not displayed if prefix + 'Managed' in config: defintion['Managed'] = config.get(prefix + 'Managed') if not show_managed_config: del defintion['Config'] name = provider.split('.')[2] providers[name] = defintion return providers
def setProvider(params): """ save the provider info in linotp config :param params: generic parameter dictionary to support later more complex provider definitions in the dictionary currently required keys are :param type: sms or email :param name: the provider name :param config: the provider config :param timeout: the provider timeout :param: default: boolean :return: success - boolean """ provider_type = params['type'] provider_name = params['name'] prefix = Provider_types.get(provider_type, {}).get('prefix') if not prefix: raise Exception('unknown provider type %r' % provider_type) provider_prefix = prefix + provider_name storeConfig(key=provider_prefix, val=params['class']) storeConfig(key=provider_prefix + '.Timeout', val=params['timeout']) # alternative to storing the whole config in encrypted way, we # might look if it's a json and store the next Config. level # and look for the reserved additional appended type: password storeConfig(key=provider_prefix + '.Config', val=params['config'], typ='password') # finally we handle the default setting and the # ability to delete legacy entries drop_legacy = False config = getLinotpConfig() default_provider_key = Default_Provider_Key[provider_type] if 'default' in params: if params['default'] == True or params['default'].lower() == 'true': storeConfig(key=default_provider_key, val=provider_name) drop_legacy = True elif provider_name == config.get(default_provider_key, ''): drop_legacy = True if drop_legacy: # at this point we can drop the legacy definition entries = Legacy_Provider[provider_type] for entry in entries.keys(): if entry in config: removeFromConfig(entry) return True, {}
def _initalGetRealms(): ''' initaly parse all config entries, and extract the realm definition :return : a dict with all realm definitions :rtype : dict of definitions ''' Realms = {} defRealmConf = "linotp.useridresolver" realmConf = "linotp.useridresolver.group." defaultRealmDef = "linotp.DefaultRealm" defaultRealm = None dc = getLinotpConfig() for entry in dc: if entry.startswith(realmConf): #the realm might contain dots "." # so take all after the 3rd dot for realm r = {} realm = entry.split(".", 3) theRealm = realm[3].lower() r["realmname"] = realm[3] r["entry"] = entry ##resids = env.config[entry] resids = getFromConfig(entry) r["useridresolver"] = resids.split(",") Realms[theRealm] = r if entry == defRealmConf: r = {} theRealm = "_default_" r["realmname"] = theRealm r["entry"] = defRealmConf #resids = env.config[entry] resids = getFromConfig(entry) r["useridresolver"] = resids.split(",") defaultRealm = "_default_" Realms[theRealm] = r if entry == defaultRealmDef: defaultRealm = getFromConfig(defaultRealmDef) if defaultRealm is not None: _setDefaultRealm(Realms, defaultRealm) return Realms
def loadProvider(provider_type, provider_name=None): """ interface for the provider user like email token or sms token :param provider_type: 'push', 'email' or 'sms :param provider_name: the name of the provider configuration :return: the instantiated provider with already loaded configuration """ provider_info = {} config = getLinotpConfig() default_provider_key = Default_Provider_Key[provider_type] # # if no provider is given, we try to lookup the default # if default_provider_key in config and not provider_name: provider_name = config[default_provider_key] # # if there is no provider_name or the provider is a legacy one # try to load it the legacy way # if not provider_name or provider_name == Legacy_Provider_Name: provider_info = get_legacy_provider(provider_type=provider_type) provider_name = Legacy_Provider_Name # # in case of no provider_info the provider is # either a new one or or a legacy converted one # if not provider_info: providers = getProvider(provider_type, provider_name=provider_name) provider_info = providers.get(provider_name) if not provider_info: raise Exception('Unable to load provider: %r' % provider_name) provider_info = provider_info.get(provider_name, provider_info) provider_class = provider_info.get('Class') try: provider_class_obi = _load_provider_class(provider_class) provider = provider_class_obi() except Exception as exc: log.exception("Failed to load provider: %r", exc) raise exc provider_config = _build_provider_config(provider_info) provider.loadConfig(provider_config) return provider
def get_default_provider(provider_type): """ find out, which provider is declared as default :param provider_type: push, sms or email :return: the name of the default provider """ config = getLinotpConfig() # finally care for the default provider default_provider_key = Default_Provider_Key[provider_type] default_provider = config.get(default_provider_key, None) return default_provider
def authenticate(self, environ, identity): log.info("[authenticate] entering repoze authenticate function.") # log.debug( identity ) username = None realm = None options = {} realmbox = "False" authenticate = True if isSelfTest(): authenticate = False try: if isSelfTest(): if ('login' not in identity and 'repoze.who.plugins.auth_tkt.userid' in identity): u = identity.get('repoze.who.plugins.auth_tkt.userid') identity['login'] = u identity['password'] = u username = identity['login'] realm = identity['realm'] password = identity['password'] options.update(identity) realmbox = options.get("realmbox", "False") except KeyError as e: log.exception("[authenticate] Keyerror in identity: %r." % e) return None # convert string to boolean realm_mbox = False if realmbox.lower() == 'true': realm_mbox = True # check username/realm, password with request_context_safety(): linotp_config = getLinotpConfig() request_context['Config'] = linotp_config user = get_authenticated_user(username, realm, password, realm_box=realm_mbox, authenticate=authenticate, options=options) if not user: return None authUser = "******" % (user.login, user.realm) return authUser
def getRealmBox(): ''' returns the config value of selfservice.realmbox. if True, the realmbox in the selfservice login will be displayed. if False, the realmbox will not be displayed and the user needs to login via user@realm ''' rb_string = "linotp.selfservice.realmbox" log.debug("[getRealmBox] getting realmbox setting") conf = getLinotpConfig() if rb_string in conf: log.debug("[getRealmBox] read setting: %r" % conf[rb_string]) return "True" == conf[rb_string] else: return False
def setPolicy(param, context=None): ''' Function to set a policy. It expects a dict of with the following keys: * name * action * scope * realm * user * time * client ''' ret = {} name = param.get('name') action = param.get('action') scope = param.get('scope') realm = param.get('realm') user = param.get('user') time = param.get('time') client = param.get('client') active = param.get('active', "True") # before storing the policy, we have to check the impact: # if there is a problem, we will raise an exception with a warning if context and 'Policies' in context: policies = deepcopy(context['Policies']) else: Config = getLinotpConfig() policies = getPolicies(config=Config) _check_policy_impact(policies=policies, **param) ret["action"] = storeConfig("Policy.%s.action" % name, action, "", "a policy definition") ret["scope"] = storeConfig("Policy.%s.scope" % name, scope, "", "a policy definition") ret["realm"] = storeConfig("Policy.%s.realm" % name, realm, "", "a policy definition") ret["user"] = storeConfig("Policy.%s.user" % name, user, "", "a policy definition") ret["time"] = storeConfig("Policy.%s.time" % name, time, "", "a policy definition") ret["client"] = storeConfig("Policy.%s.client" % name, client, "", "a policy definition") ret["active"] = storeConfig("Policy.%s.active" % name, active, "", "a policy definition") return ret
def deletePolicy(name, enforce=False): ''' Function to delete one named policy attributes: name: (required) will only return the policy with the name ''' res = {} if not re.match('^[a-zA-Z0-9_]*$', name): raise ServerError( "policy name may only contain the " "characters a-zA-Z0-9_", id=8888) if context and 'Config' in context: Config = context['Config'] else: Config = getLinotpConfig() if context and 'Policies' in context: policies = context['Policies'] else: policies = getPolicies() # check if due to delete of the policy a lockout could happen param = policies.get(name) # delete is same as inactive ;-) if param: param['active'] = "False" param['name'] = name param['enforce'] = enforce _check_policy_impact(**param) delEntries = [] for entry in Config: if entry.startswith("linotp.Policy.%s." % name): delEntries.append(entry) for entry in delEntries: # delete this entry. log.debug("[deletePolicy] removing key: %s" % entry) ret = removeFromConfig(entry) res[entry] = ret return res
def deletePolicy(name, enforce=False): """ Function to delete one named policy attributes: name: (required) will only return the policy with the name """ res = {} if not re.match("^[a-zA-Z0-9_]*$", name): raise ServerError( "policy name may only contain the " "characters a-zA-Z0-9_", id=8888, ) if context and context.get("Config"): Config = context["Config"] else: Config = getLinotpConfig() # # we need the policies for a name lookup only policies = get_policies() # check if due to delete of the policy a lockout could happen param = policies.get(name) # delete is same as inactive ;-) if param: param["active"] = "False" param["name"] = name param["enforce"] = enforce _check_policy_impact(**param) delEntries = [] for entry in Config: if entry.startswith("linotp.Policy.%s." % name): delEntries.append(entry) for entry in delEntries: # delete this entry. log.debug("[deletePolicy] removing key: %r", entry) ret = removeFromConfig(entry) res[entry] = ret return res
def getRealms(aRealmName="", context=None): ''' lookup for a defined realm or all realms :note: the realms dict is inserted into the LinOtp Config object so that a lookup has not to reparse the whole config again :param aRealmName: a realmname - the realm, that is of interestet, if =="" all realms are returned :type aRealmName: string :return: a dict with realm description like :rtype : dict : { u'myotherrealm': {'realmname': u'myotherrealm', 'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myOtherRes'], 'entry': u'linotp.useridresolver.group.myotherrealm'}, u'mydefrealm': {'default': 'true', 'realmname': u'mydefrealm', 'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myDefRes'], 'entry': u'linotp.useridresolver.group.mydefrealm'}, u'mymixrealm': {'realmname': u'mymixrealm', 'useridresolver': ['useridresolver.PasswdIdResolver.IdResolver.myOtherRes', 'useridresolver.PasswdIdResolver.IdResolver.myDefRes'], 'entry': u'linotp.useridresolver.group.mymixrealm'}} ''' ret = {} if not context: config = getLinotpConfig() else: config = context["Config"] realms = config.getRealms() # only parse once per session if realms is None: realms = _initalGetRealms() config.setRealms(realms) ''' check if only one realm is searched ''' if aRealmName != "" : if aRealmName in realms: ret[aRealmName] = realms.get(aRealmName) else: ret.update(realms) return ret
def deletePolicy(name, enforce=False): ''' Function to delete one named policy attributes: name: (required) will only return the policy with the name ''' res = {} if not re.match('^[a-zA-Z0-9_]*$', name): raise ServerError("policy name may only contain the " "characters a-zA-Z0-9_", id=8888) if context and 'Config' in context: Config = context['Config'] else: Config = getLinotpConfig() # # we need the policies for a name lookup only policies = get_policies() # check if due to delete of the policy a lockout could happen param = policies.get(name) # delete is same as inactive ;-) if param: param['active'] = "False" param['name'] = name param['enforce'] = enforce _check_policy_impact(**param) delEntries = [] for entry in Config: if entry.startswith("linotp.Policy.%s." % name): delEntries.append(entry) for entry in delEntries: # delete this entry. log.debug("[deletePolicy] removing key: %s" % entry) ret = removeFromConfig(entry) res[entry] = ret return res
def deleteResolver(resolvername): ''' delete a resolver and all related config entries :paramm resolvername: the name of the to be deleted resolver :type resolvername: string :return: sucess or fail :rtype: boelean ''' res = False resolvertypes = get_resolver_types() conf = getLinotpConfig() delEntries = [] for entry in conf: rest = entry.split(".", 3) lSplit = len(rest) if lSplit > 3: rConf = rest[lSplit - 1] if rConf == resolvername: if rest[0] == "linotp" or rest[0] == "enclinotp" : typ = rest[1] if typ in resolvertypes: delEntries.append(entry) if len(delEntries) > 0 : try: for entry in delEntries: res = removeFromConfig(entry) log.debug("[deleteResolver] removing key: %s" % entry) res = True except Exception as e: log.error("deleteResolver: %r" % e) res = False return res
def deleteResolver(resolvername): ''' delete a resolver and all related config entries :paramm resolvername: the name of the to be deleted resolver :type resolvername: string :return: sucess or fail :rtype: boelean ''' res = False resolvertypes = get_resolver_types() conf = getLinotpConfig() delEntries = [] for entry in conf: rest = entry.split(".", 3) lSplit = len(rest) if lSplit > 3: rConf = rest[lSplit - 1] if rConf == resolvername: if rest[0] == "linotp" or rest[0] == "enclinotp": typ = rest[1] if typ in resolvertypes: delEntries.append(entry) if len(delEntries) > 0: try: for entry in delEntries: res = removeFromConfig(entry) log.debug("[deleteResolver] removing key: %s" % entry) res = True except Exception as e: log.error("deleteResolver: %r" % e) res = False return res
def create_context(self, request): """ create the request context for all controllers """ linotp_config = getLinotpConfig() self.request_context = {} self.request_context['Config'] = linotp_config self.request_context['Policies'] = getPolicies(config=linotp_config) self.request_context['translate'] = translate request_params = {} try: request_params.update(request.params) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['Params'] = request_params authUser = None try: authUser = getUserFromRequest(request) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['AuthUser'] = authUser requestUser = None try: requestUser = getUserFromParam(request_params, True) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['RequestUser'] = requestUser client = None try: client = get_client(request=request) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['Client'] = client self.request_context['audit'] = {} defaultRealm = "" try: defaultRealm = getDefaultRealm(linotp_config) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['defaultRealm'] = defaultRealm realms = None try: realms = getRealms(context=self.request_context) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) self.request_context['Realms'] = realms return
def getResolverObject(resolver_spec, config=None, load_config=True): """ get the resolver instance from a resolver specification. :remark: internally this function uses the request context for caching. :param resolver_spec: the resolver string as from the token including the config identifier. format: <resolver class identifier>.<config identifier> :return: instance of the resolver with the loaded config (or None if specification was invalid or didn't match a resolver) """ # this patch is a bit hacky: # the normal request has a request context, where it retrieves # the resolver info from and preserves the loaded resolvers for reusage # But in case of a authentication request (by a redirect from a 401) # the caller is no std request and the context object is missing :-( # The solution is to deal with local references, either to the # global context or to local data (where we have no reuse of the resolver) resolvers_loaded = context.setdefault('resolvers_loaded', {}) if not config: config = getLinotpConfig() # test if the resolver is in the cache if resolver_spec in resolvers_loaded: return resolvers_loaded.get(resolver_spec) # no resolver - so instantiate one else: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if not cls_identifier or not config_identifier: log.error('Format error: resolver_spec must have the format ' '<resolver_class_identifier>.<config_identifier>, but ' 'value was %s' % resolver_spec) return None resolver_cls = get_resolver_class(cls_identifier) if resolver_cls is None: log.error('Unknown resolver class: %s' % cls_identifier) return None resolver = resolver_cls() if load_config: try: resolver.loadConfig(config, config_identifier) except ResolverNotAvailable: log.error('Unable to connect to resolver %r', resolver_spec) return None except Exception as exx: # FIXME: Except clause is too general. resolver # should be ResolverLoadConfigError # exceptions in the useridresolver modules should # have their own type, so we can filter here log.error( 'Resolver config loading failed for resolver with ' 'specification %s: %r', resolver_spec, exx) return None # in case of the replication there might by difference # in the used resolver config and the config from the LinOTP config _check_for_resolver_cache_flush(resolver_spec, config_identifier) resolvers_loaded[resolver_spec] = resolver return resolver
def authenticate(self, environ, identity): log.debug("Authentication through repoze.") username = None realm = None options = {} realmbox = "False" authenticate = True if isSelfTest(): authenticate = False try: if isSelfTest(): if ('login' not in identity and 'repoze.who.plugins.auth_tkt.userid' in identity): u = identity.get('repoze.who.plugins.auth_tkt.userid') identity['login'] = u identity['password'] = u username = identity['login'] realm = identity['realm'] password = identity['password'] options.update(identity) realmbox = options.get("realmbox", "False") except KeyError as e: log.exception("Keyerror in repoze identity: %r." % e) return None # convert string to boolean realm_mbox = False if realmbox.lower() == 'true': realm_mbox = True # check username/realm, password with request_context_safety(): linotp_config = getLinotpConfig() request_context['Config'] = linotp_config # add the cache manager to the context glo = getGlobalObject() cache_manager = glo.cache_manager request_context['CacheManager'] = cache_manager # and also add the hsm - enables us to do otp validation :-) sep = glo.security_provider hsm = sep.getSecurityModule() request_context['hsm'] = hsm # initialize the base context # - copied for the dumb repoze middleware cache_dir = config.get("app_conf", {}).get("cache_dir", None) setupResolvers(config=linotp_config, cache_dir=cache_dir) resolver_context = initResolvers() request_context.update(resolver_context) # prepare the request local user cache if 'UserLookup' not in request_context: request_context['UserLookup'] = {} user = get_authenticated_user(username, realm, password, realm_box=realm_mbox, authenticate=authenticate, options=options) if not user: return None authUser = "******" % (user.login, user.realm) return authUser
def getProvider(provider_type, provider_name=None): """ return a dict with providers, each with it's description as dict :param provider_type: either sms or email :param provider_name: name of the provider (optional) """ providers = {} # find out, which provider type we have, currently only sms or email prefix = Provider_types.get(provider_type, {}).get('prefix') if not prefix: raise Exception('unknow provider type %r' % provider_type) default_provider_key = Default_Provider_Key[provider_type] # find out, which providers we have config = getLinotpConfig() provider_names = {} default_provider = None # if provider by name is given, we select only this one if provider_name: name = prefix + provider_name if name in config: provider_names[name] = config[name] else: # first identify all providers by its name for key, value in config.items(): if key[:len(prefix)] == prefix: parts = key.split('.') if len(parts) == 3: provider_names[key] = value for provider, provider_class in provider_names.items(): defintion = {} defintion['Class'] = provider_class prefix = provider + '.' for key, value in config.items(): if key[:len(prefix)] == prefix: if 'enc' + key in config: value = config.get('enc' + key) entry = key.replace(prefix, '') defintion[entry] = value defintion['Default'] = False name = provider.split('.')[2] providers[name] = defintion # finally care for the default provider if default_provider_key in config: default_provider = config.get(default_provider_key) if default_provider in providers: providers[default_provider]['Default'] = True # if searched for a dedicated provider, ignore the legacy one if not provider_name: if Legacy_Provider_Name not in providers: defintion = get_legacy_provider(provider_type=provider_type) if defintion: if not default_provider: defintion['Default'] = True providers[Legacy_Provider_Name] = defintion # # finally check that we preserve and show the default: # # if in the current definition, we have a different default defined (s.o.) # we trust this and overwrite the one of Config table (if any) # This will create a consistent way to bootstrap a default even # from import for provider in providers: provider_info = providers[provider] if provider_info.get('Default', False): if config.get(default_provider_key, '') != provider: storeConfig(default_provider_key, provider) # if there is only one defined, it must be the default :-) if len(providers.keys()) == 1: for provider, provider_info in providers.items(): provider_info['Default'] = True storeConfig(default_provider_key, provider) return providers
def authenticate(self, environ, identity): log.info("[authenticate] entering repoze authenticate function.") # log.debug( identity ) username = None realm = None options = {} realmbox = "False" authenticate = True if isSelfTest(): authenticate = False try: if isSelfTest(): if ('login' not in identity and 'repoze.who.plugins.auth_tkt.userid' in identity): u = identity.get('repoze.who.plugins.auth_tkt.userid') identity['login'] = u identity['password'] = u username = identity['login'] realm = identity['realm'] password = identity['password'] options.update(identity) realmbox = options.get("realmbox", "False") except KeyError as e: log.exception("[authenticate] Keyerror in identity: %r." % e) return None # convert string to boolean realm_mbox = False if realmbox.lower() == 'true': realm_mbox = True # check username/realm, password with request_context_safety(): linotp_config = getLinotpConfig() request_context['Config'] = linotp_config # add the cache manager to the context glo = getGlobalObject() cache_manager = glo.cache_manager request_context['CacheManager'] = cache_manager # and also add the hsm - enables us to do otp validation :-) sep = glo.security_provider hsm = sep.getSecurityModule() request_context['hsm'] = hsm resolver_context = initResolvers() request_context.update(resolver_context) user = get_authenticated_user(username, realm, password, realm_box=realm_mbox, authenticate=authenticate, options=options) if not user: return None authUser = "******" % (user.login, user.realm) return authUser
def getResolverObject(resolver_spec): """ get the resolver instance from a resolver specification. :remark: internally this function uses the request context for caching. :param resolver_spec: the resolver string as from the token including the config identifier. format: <resolver class identifier>.<config identifier> :return: instance of the resolver with the loaded config (or None if specification was invalid or didn't match a resolver) """ # this patch is a bit hacky: # the normal request has a request context, where it retrieves # the resolver info from and preserves the loaded resolvers for reusage # But in case of a authentication request (by a redirect from a 401) # the caller is no std request and the context object is missing :-( # The solution is to deal with local references, either to the # global context or to local data (where we have no reuse of the resolver) resolvers_loaded = context.setdefault('resolvers_loaded', {}) # test if the resolver is in the cache if resolver_spec in resolvers_loaded: return resolvers_loaded.get(resolver_spec) # no resolver - so instatiate one else: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if not cls_identifier or not config_identifier: log.error('Format error: resolver_spec must have the format ' '<resolver_class_identifier>.<config_identifier>, but ' 'value was %s' % resolver_spec) return None resolver_cls = get_resolver_class(cls_identifier) if resolver_cls is None: log.error('unknown resolver class: %s' % cls_identifier) return None resolver = resolver_cls() config = getLinotpConfig() try: resolver.loadConfig(config, config_identifier) except: # FIXME: Except clause is too general. resolver # exceptions in the useridresolver modules should # have their own type, so we can filter here log.error('resolver config loading failed for resolver with ' 'specification %s' % resolver_spec) return None resolvers_loaded[resolver_spec] = resolver return resolver
def delProvider(provider_type, provider_name): """ delete a provider :param provider_type: the type of Provider: push, sms or email :param provider_name: the name of the provider :return: the number of deleted entries """ detail = {} prefix = Provider_types.get(provider_type, {}).get('prefix') if not prefix: raise Exception('unknown provider type %r' % provider_type) # find out, which providers we have config = getLinotpConfig() # if the provider is the default one, we don't delete this one default_provider_key = Default_Provider_Key[provider_type] if default_provider_key in config: default_provider = config[default_provider_key] if provider_name == default_provider: detail = {'message': _('Default provider could not be deleted!')} ret = 0 return ret, detail # check that there are no references left provider_policies = _lookup_provider_policies(provider_type) if provider_name in provider_policies: detail = { 'message': (_('Unable to delete - provider used in ' 'policies!\n[%s]') % ','.join(provider_policies[provider_name])) } ret = 0 return ret, detail del_entries = set() provider = prefix + provider_name # treat backward default legacy case if provider_name == Legacy_Provider_Name: entries = Legacy_Provider.get(provider_type, {}) for entry in entries.keys(): if entry in config: del_entries.add(entry) if not del_entries: # first delete the provider root entry if provider in config: del_entries.add(provider) # now lookup the all decent entries provider_prefix = provider + '.' for key in config.keys(): if key[:len(provider_prefix)] == provider_prefix: del_entries.add(key) # when all entries are gathered, we can now delete them all for del_entry in del_entries: removeFromConfig(del_entry) ret = len(del_entries) return ret, detail
def getResolverInfo(resolvername): ''' return the resolver info of the given resolvername :param resolvername: the requested resolver :type resolvername: string :return : dict of resolver description ''' resolver_dict = {} typ = "" resolvertypes = get_resolver_types() descr = {} conf = getLinotpConfig() for entry in conf: for typ in resolvertypes: ## get the typed values of the descriptor! resolver_conf = get_resolver_classConfig(typ) if typ in resolver_conf: descr = resolver_conf.get(typ).get('config', {}) else: descr = resolver_conf if entry.startswith("linotp." + typ) and entry.endswith(resolvername): #the realm might contain dots "." # so take all after the 3rd dot for realm resolver = entry.split(".", 3) # An old entry without resolver name if len(resolver) <= 3: break value = conf.get(entry) if resolver[2] in descr: configEntry = resolver[2] if descr.get(configEntry) == 'password': ## do we already have the decrypted pass? if 'enc' + entry in conf: value = conf.get('enc' + entry) else: ## if no, we take the encpass and decrypt it value = conf.get(entry) try: en = decryptPassword(value) value = en except: log.info( "Decryption of resolver passwd failed: compatibility issue?" ) resolver_dict[resolver[2]] = value # Dont check the other resolver types break return {"type": typ, "data": resolver_dict, "resolver": resolvername}
def create_context(self, request): """ create the request context for all controllers """ linotp_config = getLinotpConfig() request_context['Config'] = linotp_config request_context['Policies'] = getPolicies() request_context['translate'] = translate initResolvers() request_params = {} try: request_params.update(request.params) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['Params'] = request_params authUser = None try: authUser = getUserFromRequest(request) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['AuthUser'] = authUser requestUser = None try: requestUser = getUserFromParam(request_params, True) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['RequestUser'] = requestUser client = None try: client = get_client(request=request) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['Client'] = client request_context['Audit'] = Audit request_context['audit'] = Audit.initialize(request, client=client) defaultRealm = "" try: defaultRealm = getDefaultRealm(linotp_config) except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['defaultRealm'] = defaultRealm realms = None try: realms = getRealms() except UnicodeDecodeError as exx: log.error("Faild to decode request parameters %r" % exx) request_context['Realms'] = realms request_context['hsm'] = None if hasattr(self, "hsm"): request_context['hsm'] = self.hsm # copy some system entries from pylons syskeys = { "radius.nas_identifier": "LinOTP", "radius.dictfile": "/etc/linotp2/dictionary" } sysconfig = {} for key, default in syskeys.items(): try: sysconfig[key] = config.get(key, default) except: log.info('no sytem config entry %s' % key) request_context['SystemConfig'] = sysconfig
def create_context(self, request, environment): """ create the request context for all controllers """ linotp_config = getLinotpConfig() # make the request id available in the request context request_context['RequestId'] = environment['REQUEST_ID'] # a request local cache to get the user info from the resolver request_context['UserLookup'] = {} # a request local cache to get the resolver from user and realm request_context['UserRealmLookup'] = {} request_context['Config'] = linotp_config request_context['Policies'] = parse_policies(linotp_config) request_context['translate'] = translate request_context['CacheManager'] = environment['beaker.cache'] routes = environment.get('pylons.routes_dict', {}) path = "/%s/%s" % (routes['controller'], routes['action']) request_context['Path'] = path request_context['hsm'] = self.hsm initResolvers() client = None try: client = get_client(request=request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Client'] = client request_context['Audit'] = Audit request_context['audit'] = Audit.initialize(request, client=client) authUser = None try: authUser = getUserFromRequest(request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['AuthUser'] = authUser request_context['UserLookup'] = {} # ------------------------------------------------------------------ -- # get the current resolvers resolvers = [] try: resolvers = getResolverList(config=linotp_config) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Resolvers'] = resolvers # ------------------------------------------------------------------ -- # get the current realms realms = {} try: realms = getRealms() except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Realms'] = realms # ------------------------------------------------------------------ -- defaultRealm = "" try: defaultRealm = getDefaultRealm(linotp_config) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['defaultRealm'] = defaultRealm # ------------------------------------------------------------------ -- # load the requesting user from linotp.useridresolver.UserIdResolver import ( ResolverNotAvailable) requestUser = None try: requestUser = getUserFromParam(self.request_params) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r", exx) except (ResolverNotAvailable, NoResolverFound) as exx: log.error("Failed to connect to server %r", exx) request_context['RequestUser'] = requestUser # ------------------------------------------------------------------ -- # load the providers from linotp.provider import Provider_types from linotp.provider import getProvider provider = {} for provider_type in Provider_types.keys(): provider[provider_type] = getProvider(provider_type) request_context['Provider'] = provider # ------------------------------------------------------------------ -- # for the setup of encrypted data, we require the hsm is instatiated # and available in the request context if not self.secret_key: init_key_partition(linotp_config, partition=0) # ------------------------------------------------------------------ -- # copy some system entries from pylons syskeys = { "radius.nas_identifier": "LinOTP", "radius.dictfile": "/etc/linotp2/dictionary" } sysconfig = {} for key, default in syskeys.items(): sysconfig[key] = config.get(key, default) request_context['SystemConfig'] = sysconfig
def create_context(self, request, environment): """ create the request context for all controllers """ linotp_config = getLinotpConfig() request_context['Config'] = linotp_config request_context['Policies'] = parse_policies(linotp_config) request_context['translate'] = translate request_context['CacheManager'] = environment['beaker.cache'] initResolvers() request_params = {} try: request_params.update(request.params) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Params'] = request_params authUser = None try: authUser = getUserFromRequest(request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['AuthUser'] = authUser request_context['UserLookup'] = {} requestUser = None try: requestUser = getUserFromParam(request_params) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['RequestUser'] = requestUser client = None try: client = get_client(request=request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Client'] = client request_context['Audit'] = Audit request_context['audit'] = Audit.initialize(request, client=client) defaultRealm = "" try: defaultRealm = getDefaultRealm(linotp_config) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['defaultRealm'] = defaultRealm realms = None try: realms = getRealms() except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Realms'] = realms request_context['hsm'] = None if hasattr(self, "hsm"): request_context['hsm'] = self.hsm # copy some system entries from pylons syskeys = { "radius.nas_identifier": "LinOTP", "radius.dictfile": "/etc/linotp2/dictionary" } sysconfig = {} for key, default in syskeys.items(): sysconfig[key] = config.get(key, default) request_context['SystemConfig'] = sysconfig
def __init__(self, *args, **kw): """ base controller constructor :param *args: generic argument array :param **kw: generic argument dict :return: None """ self.sep = None self.set_language(request.headers) self.base_auth_user = '' self.parent = super(WSGIController, self) self.parent.__init__(*args, **kw) # make the OpenID SQL Instance globally available openid_sql = config.get('openid_sql', None) if openid_sql is None: try: openid_storage = SQLStorage() config['openid_sql'] = openid_storage except Exception as exx: config['openid_sql'] = exx log.error("Failed to configure openid_sql: %r" % exx) first_run = False app_setup_done = config.get('app_setup_done', False) if app_setup_done is False: try: setup_app(config) config['app_setup_done'] = True first_run = True except Exception as exx: config['app_setup_done'] = False log.error("Failed to serve request: %r" % exx) raise exx # set the decryption device before loading linotp config, # so it contains the decrypted values as well glo = getGlobalObject() self.sep = glo.security_provider try: hsm = self.sep.getSecurityModule() self.hsm = hsm c.hsm = hsm except Exception as exx: log.exception('failed to assign hsm device: %r' % exx) raise exx l_config = getLinotpConfig() # initialize the elliptic curve secret + public key for the qrtoken secret_key = l_config.get('SecretKey.Partition.0', False) if not secret_key: init_key_partition(l_config, partition=0) resolver_setup_done = config.get('resolver_setup_done', False) if resolver_setup_done is False: try: cache_dir = config.get("app_conf", {}).get("cache_dir", None) setupResolvers(config=l_config, cache_dir=cache_dir) config['resolver_setup_done'] = True except Exception as exx: config['resolver_setup_done'] = False log.error("Failed to setup resolver: %r", exx) raise exx # TODO: verify merge dropped # initResolvers() # if we are in the setup cycle, we check for the linotpLicenseFile if first_run: if "linotpLicenseFile" in config and 'license' not in l_config: license_str = '' filename = config.get("linotpLicenseFile", '') try: with open(filename) as f: license_str = f.read() except IOError: log.error("could not open licence file: %s", filename) if not license_str: log.error("empty license file: %s", filename) else: with request_context_safety(): request_context['translate'] = translate import linotp.lib.support res, msg = linotp.lib.support.setSupportLicense( license_str) if res is False: log.error("failed to load license: %s: %s", license_str, msg) else: log.info("license successfully loaded") if 'provider.config_file' in config: from linotp.provider import load_provider_ini load_provider_ini(config['provider.config_file']) return
def loadProvider(provider_type, provider_name=None): """ interface for the provider user like email token or sms token :param provider_type: 'email' or 'sms :param provider_name: the name of the provider configuration :return: the instantiated provider with already loaded configuration """ provider_info = {} config = getLinotpConfig() default_provider_key = Default_Provider_Key[provider_type] # # if no provider is given, we try to lookup the default # if default_provider_key in config and not provider_name: provider_name = config[default_provider_key] # # if there is no provider_name or the provider is a legacy one # try to load it the legacy way # if not provider_name or provider_name == Legacy_Provider_Name: provider_info = get_legacy_provider(provider_type=provider_type) provider_name = Legacy_Provider_Name # # in case of no provider_info the provider is # either a new one or or a legacy converted one # if not provider_info: providers = getProvider(provider_type, provider_name=provider_name) provider_info = providers.get(provider_name) if not provider_info: raise Exception('Unable to load provider: %r' % provider_name) provider_info = provider_info.get(provider_name, provider_info) provider_class = provider_info.get('Class') try: provider_class_obi = _load_provider_class(provider_class) provider = provider_class_obi() except Exception as exc: log.exception("Failed to load provider: %r", exc) raise exc provider_config = {} config = provider_info['Config'] # # backward compatibility hack: fix the handling of multiline config entries # lconfig = [] lines = config.splitlines() for line in lines: line = line.strip('\\') if len(line) > 0: lconfig.append(line) config = " ".join(lconfig) try: provider_config = json.loads(config) except ValueError as exx: log.exception('Failed to load provider config %r', config) raise ValueError('Failed to load provider config:%r %r' % (config, exx)) provider.loadConfig(provider_config) return provider
def create_context(self, request, environment): """ create the request context for all controllers """ linotp_config = getLinotpConfig() request_context['Config'] = linotp_config request_context['Policies'] = parse_policies(linotp_config) request_context['translate'] = translate request_context['CacheManager'] = environment['beaker.cache'] request_context['Path'] = environment.get("PATH_INFO", "") or "" request_context['hsm'] = self.hsm request_params = {} try: request_params.update(request.params) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Params'] = request_params initResolvers() client = None try: client = get_client(request=request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Client'] = client request_context['Audit'] = Audit request_context['audit'] = Audit.initialize(request, client=client) authUser = None try: authUser = getUserFromRequest(request) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['AuthUser'] = authUser request_context['UserLookup'] = {} requestUser = None try: requestUser = getUserFromParam(request_params) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['RequestUser'] = requestUser defaultRealm = "" try: defaultRealm = getDefaultRealm(linotp_config) except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['defaultRealm'] = defaultRealm realms = None try: realms = getRealms() except UnicodeDecodeError as exx: log.error("Failed to decode request parameters %r" % exx) request_context['Realms'] = realms # ------------------------------------------------------------------ -- # for the setup of encrypted data, we require the hsm is instatiated # and available in the request context if not self.secret_key: init_key_partition(linotp_config, partition=0) # ------------------------------------------------------------------ -- # copy some system entries from pylons syskeys = { "radius.nas_identifier": "LinOTP", "radius.dictfile": "/etc/linotp2/dictionary" } sysconfig = {} for key, default in syskeys.items(): sysconfig[key] = config.get(key, default) request_context['SystemConfig'] = sysconfig