def _compareResolver(self, userObj, user_def): """ do the user name and resolver comparison - the user is separated by a '.' from the resolver Remark: the user must not be defined by the target resolver, its the ability to lookup in a different resolver for the user login :params userObj: the comparison user class object :param user_def: the user pattern to compare against :return: bool """ def_resolver = user_def[:-1] # if there is a prefixed user, split it from if '.' in def_resolver: def_resolver = def_resolver.split('.')[-1] # check if the resolver is defined at all from linotp.lib.resolver import getResolverList resolvers = getResolverList() if def_resolver not in resolvers: return False # if we have no user part and came that far, we ar e done if def_resolver == user_def[:-1]: return True user_resolver = user_def[:-1] # remove the resolver from the user and compare simple_user_def, _sep, _res = user_resolver.rpartition(".") return self._compareUser(userObj, simple_user_def)
def migrate_resolver(self): from linotp.lib.tools.migrate_resolver import MigrateResolverHandler ret = {} try: src = self.request_params['from'] target = self.request_params['to'] from linotp.lib.resolver import getResolverList resolvers = getResolverList() src_resolver = resolvers.get(src, None) target_resolver = resolvers.get(target, None) if not target_resolver or not src_resolver: raise Exception('Src or Target resolver is undefined!') mg = MigrateResolverHandler() ret = mg.migrate_resolver(src=src_resolver, target=target_resolver) Session.commit() return sendResult(response, ret) except Exception as e: log.exception("failed: %r" % e) Session.rollback() return sendError(response, e, 1) finally: Session.close()
def _do_readonly_param_test(self, param, is_invalid, expected_readonly, mock_get_types): """ Call getresolverlist with given configuration """ conf = { 'linotp.test.name.UnitTestResolver': 'UnitTestResolver', 'linotp.test.readonly.UnitTestResolver': param, } with patch('linotp.lib.resolver.context', return_value=conf) as mock_context: mock_context.get.return_value = conf with patch('linotp.lib.resolver.log') as mock_log: ret = resolver.getResolverList() if is_invalid: # Invalid parameter will log a message mock_log.info.assert_called_with( "Failed to convert 'readonly' attribute %r:%r", ANY, param) # If readonly, the resulting resolver has config key=readonly, value=True # If not readonly, the resulting resolver does not have the readonly key r = ret['UnitTestResolver'] if expected_readonly: assert r['readonly'] == True else: assert 'readonly' not in r
def migrate_resolver(self): from linotp.lib.tools.migrate_resolver import MigrateResolverHandler ret = {} try: src = self.request_params["from"] target = self.request_params["to"] from linotp.lib.resolver import getResolverList resolvers = getResolverList() src_resolver = resolvers.get(src, None) target_resolver = resolvers.get(target, None) if not target_resolver or not src_resolver: raise Exception("Src or Target resolver is undefined!") mg = MigrateResolverHandler() ret = mg.migrate_resolver(src=src_resolver, target=target_resolver) db.session.commit() return sendResult(response, ret) except Exception as e: log.error("migrate resolver failed") db.session.rollback() return sendError(response, e, 1)
def get_fq_resolver(res): fq_resolver = None resolvers = getResolverList() if res in resolvers: match_res = resolvers.get(res) fq_resolver = getResolverClassName(match_res['type'], match_res['resolvername']) return fq_resolver
def _do_readonly_param_test( self, param, is_invalid, expected_readonly, mock_get_types, mock_admin_resolvers, ): """ Call getresolverlist with given configuration """ conf = { "linotp.sqlresolver.name.UnitTestResolver": "UnitTestResolver", "linotp.sqlresolver.readonly.UnitTestResolver": param, } with patch("linotp.lib.resolver.context", return_value=conf) as mock_context: mock_context.get.return_value = conf with patch("linotp.lib.resolver.log") as mock_log: ret = resolver.getResolverList() if is_invalid: # Invalid parameter will log a message mock_log.info.assert_called_with( "Failed to convert 'readonly' attribute %r:%r", ANY, param, ) # If readonly, the resulting resolver has config key=readonly, value=True # If not readonly, the resulting resolver does not have the # readonly key r = ret["UnitTestResolver"] if expected_readonly: assert r["readonly"] else: assert "readonly" not in r
def _compareResolver(self, userObj, user_def): """ do the user name and resolver comparison - the user is separated by a '.' from the resolver Remark: the user must not be defined by the target resolver, its the ability to lookup in a different resolver for the user login :params userObj: the comparison user class object :param user_def: the user pattern to compare against :return: bool """ def_resolver = user_def[:-1] # if there is a prefixed user, split it from if "." in def_resolver: def_resolver = def_resolver.split(".")[-1] # check if the resolver is defined at all from linotp.lib.resolver import getResolverList resolvers = getResolverList() if def_resolver not in resolvers: return False # if we have no user part and came that far, we are done if def_resolver == user_def[:-1]: return True user_resolver = user_def[:-1] # remove the resolver from the user and compare simple_user_def = user_resolver if "." in user_resolver: simple_user_def, _sep, _res = user_resolver.rpartition(".") return self._compareUser(userObj, simple_user_def)
def migrate_resolver(self): from linotp.lib.tools.migrate_resolver import MigrateResolverHandler params = {} ret = {} try: params.update(request.params) src = params['from'] target = params['to'] from linotp.lib.resolver import getResolverList resolvers = getResolverList() src_resolver = resolvers.get(src, None) target_resolver = resolvers.get(target, None) if not target_resolver or not src_resolver: raise Exception('Src or Target resolver is undefined!') mg = MigrateResolverHandler(context=self.request_context) ret = mg.migrate_resolver(src=src_resolver, target=target_resolver) Session.commit() return sendResult(response, ret) except Exception as e: log.exception("failed: %r" % e) Session.rollback() log.error('error getting token owner') return sendError(response, e, 1) finally: Session.close() log.debug('[enable] done')
def import_users(self): """ import users from a csv file into an dedicated sql resolver """ try: params = {} params.update(request.POST) # -------------------------------------------------------------- -- # processing required arguments try: data_file = request.POST['file'] resolver_name = params['resolver'] except KeyError as exx: log.exception("Missing parameter: %r", exx) raise ParameterError("Missing parameter: %r" % exx) groupid = resolver_name # process file upload data data = data_file # -- ----------------------------------------------------------- -- # In case of form post requests, it is a "instance" of FieldStorage # i.e. the Filename is selected in the browser and the data is # transferred in an iframe. # see: http://jquery.malsup.com/form/#sample4 # -- ----------------------------------------------------------- -- if isinstance(data_file, FieldStorage): data = data_file.value # -------------------------------------------------------------- -- # process the other arguments dryrun = boolean(params.get('dryrun', False)) passwords_in_plaintext = boolean( params.get('passwords_in_plaintext', False)) file_format = params.get('format', "csv") if file_format in ('password', 'passwd'): column_mapping = { "userid": 2, "username": 0, "phone": 8, "mobile": 7, "email": 9, "surname": 5, "givenname": 4, "password": 1 } format_reader = PasswdFormatReader() elif file_format in ('csv'): skip_header = boolean(params.get('skip_header', False)) if skip_header: data = '\n'.join(data.split('\n')[1:]) column_mapping = { "username": 0, "userid": 1, "surname": 2, "givenname": 3, "email": 4, "phone": 5, "mobile": 6, "password": 7 } delimiter = str(params.get('delimiter', ",")) quotechar = str(params.get('quotechar', '"')) format_reader = DefaultFormatReader() format_reader.delimiter = delimiter format_reader.quotechar = quotechar column_mapping = params.get('column_mapping', column_mapping) else: raise Exception('unspecified file foramt') # we have to convert the column_mapping back into an dict if (isinstance(column_mapping, str) or isinstance(column_mapping, unicode)): column_mapping = json.loads(column_mapping) # prevent overwrite of existing unmanaged resolver resolvers = getResolverList() if resolver_name in resolvers: if not resolvers[resolver_name].get('readonly', False): raise Exception("Unmanged resolver with same name: %r" " already exists!" % resolver_name) # -------------------------------------------------------------- -- # feed the engine :) # use a LinOTP Database context for Sessions and Engine db_context = LinOTP_DatabaseContext( SqlSession=Session, SqlEngine=linotp.model.meta.engine) # define the import into an SQL database + resolver import_handler = SQLImportHandler(groupid=groupid, resolver_name=resolver_name, database_context=db_context) # create the UserImporter with the required mapping user_import = UserImport(import_handler) user_import.set_mapping(column_mapping) # and run the data processing result = user_import.import_csv_users( data, dryrun=dryrun, format_reader=format_reader, passwords_in_plaintext=passwords_in_plaintext) if dryrun: return sendResult(response, result) # -------------------------------------------------------------- -- # create / extend target realm for the resolver resolver_spec = import_handler.get_resolver_spec() Session.commit() return sendResult(response, result) except PolicyException as pexx: log.exception("Error during user import: %r", pexx) Session.rollback() return sendError(response, "%r" % pexx, 1) except Exception as exx: log.exception("Error during user import: %r" % exx) Session.rollback() return sendError(response, "%r" % exx) finally: Session.close() log.debug('done')
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 import_users(self): """ import users from a csv file into an dedicated sql resolver """ try: params = {} params.update(request.POST) # -------------------------------------------------------------- -- # processing required arguments try: data_file = request.POST['file'] resolver_name = params['resolver'] except KeyError as exx: log.exception("Missing parameter: %r", exx) raise ParameterError("Missing parameter: %r" % exx) groupid = resolver_name # process file upload data data = data_file # -- ----------------------------------------------------------- -- # In case of form post requests, it is a "instance" of FieldStorage # i.e. the Filename is selected in the browser and the data is # transferred in an iframe. # see: http://jquery.malsup.com/form/#sample4 # -- ----------------------------------------------------------- -- if isinstance(data_file, FieldStorage): data = data_file.value # -------------------------------------------------------------- -- # process the other arguments dryrun = boolean(params.get('dryrun', False)) passwords_in_plaintext = boolean(params.get( 'passwords_in_plaintext', False)) file_format = params.get('format', "csv") if file_format in ('password', 'passwd'): column_mapping = { "userid": 2, "username": 0, "phone": 8, "mobile": 7, "email": 9, "surname": 5, "givenname": 4, "password": 1} format_reader = PasswdFormatReader() elif file_format in ('csv'): skip_header = boolean(params.get('skip_header', False)) if skip_header: data = '\n'.join(data.split('\n')[1:]) column_mapping = { "username": 0, "userid": 1, "surname": 2, "givenname": 3, "email": 4, "phone": 5, "mobile": 6, "password": 7} delimiter = str(params.get('delimiter', ",")) quotechar = str(params.get('quotechar', '"')) format_reader = DefaultFormatReader() format_reader.delimiter = delimiter format_reader.quotechar = quotechar column_mapping = params.get('column_mapping', column_mapping) else: raise Exception('unspecified file foramt') # we have to convert the column_mapping back into an dict if (isinstance(column_mapping, str) or isinstance(column_mapping, unicode)): column_mapping = json.loads(column_mapping) # prevent overwrite of existing unmanaged resolver resolvers = getResolverList() if resolver_name in resolvers: if not resolvers[resolver_name].get('readonly', False): raise Exception("Unmanged resolver with same name: %r" " already exists!" % resolver_name) # -------------------------------------------------------------- -- # feed the engine :) # use a LinOTP Database context for Sessions and Engine db_context = LinOTP_DatabaseContext( SqlSession=Session, SqlEngine=linotp.model.meta.engine) # define the import into an SQL database + resolver import_handler = SQLImportHandler( groupid=groupid, resolver_name=resolver_name, database_context=db_context) # create the UserImporter with the required mapping user_import = UserImport(import_handler) user_import.set_mapping(column_mapping) # and run the data processing result = user_import.import_csv_users( data, dryrun=dryrun, format_reader=format_reader, passwords_in_plaintext=passwords_in_plaintext ) if dryrun: return sendResult(response, result) # -------------------------------------------------------------- -- # create / extend target realm for the resolver resolver_spec = import_handler.get_resolver_spec() Session.commit() return sendResult(response, result) except PolicyException as pexx: log.exception("Error during user import: %r", pexx) Session.rollback() return sendError(response, "%r" % pexx, 1) except Exception as exx: log.exception("Error during user import: %r" % exx) Session.rollback() return sendError(response, "%r" % exx) finally: Session.close() log.debug('done')
def import_users(self): """ import users from a csv file into an dedicated sql resolver """ try: params = self.request_params # -------------------------------------------------------------- -- # processing required arguments try: data_file = request.files["file"] resolver_name = params["resolver"] except KeyError as exx: log.error("Missing parameter: %r", exx) raise ParameterError("Missing parameter: %r" % exx) if resolver_name == current_app.config["ADMIN_RESOLVER_NAME"]: raise DeleteForbiddenError( f"default admin resolver {resolver_name} is not allowed " "to be overwritten!") groupid = resolver_name # process file upload data data = data_file # -- ----------------------------------------------------------- -- # In case of form post requests, it is a "instance" of FileStorage # i.e. the Filename is selected in the browser and the data is # transferred in an iframe. # see: http://jquery.malsup.com/form/#sample4 # -- ----------------------------------------------------------- -- if isinstance(data_file, FileStorage): data = data_file.read() data = data.decode() # -------------------------------------------------------------- -- # process the other arguments dryrun = boolean(params.get("dryrun", False)) passwords_in_plaintext = boolean( params.get("passwords_in_plaintext", False)) file_format = params.get("format", "csv") if file_format in ("password", "passwd"): column_mapping = { "userid": 2, "username": 0, "phone": 8, "mobile": 7, "email": 9, "surname": 5, "givenname": 4, "password": 1, } format_reader = PasswdFormatReader() elif file_format in ("csv"): skip_header = boolean(params.get("skip_header", False)) if skip_header: data = "\n".join(data.split("\n")[1:]) column_mapping = { "username": 0, "userid": 1, "surname": 2, "givenname": 3, "email": 4, "phone": 5, "mobile": 6, "password": 7, } delimiter = str(params.get("delimiter", ",")) quotechar = str(params.get("quotechar", '"')) format_reader = DefaultFormatReader() format_reader.delimiter = delimiter format_reader.quotechar = quotechar column_mapping = params.get("column_mapping", column_mapping) else: raise Exception("unspecified file foramt") # we have to convert the column_mapping back into an dict if isinstance(column_mapping, str): column_mapping = json.loads(column_mapping) # prevent overwrite of existing unmanaged resolver checkPolicyPre("system", "setResolver") resolvers = getResolverList() if resolver_name in resolvers: if not resolvers[resolver_name].get("readonly", False): raise Exception("Unmanged resolver with same name: %r" " already exists!" % resolver_name) # -------------------------------------------------------------- -- # feed the engine :) # use a LinOTP Database context for Sessions and Engine db_context = LinOTP_DatabaseContext(SqlSession=db.session, SqlEngine=db.engine) # define the import into an SQL database + resolver import_handler = SQLImportHandler( groupid=groupid, resolver_name=resolver_name, database_context=db_context, ) # create the UserImporter with the required mapping user_import = UserImport(import_handler) user_import.set_mapping(column_mapping) # and run the data processing result = user_import.import_csv_users( data, dryrun=dryrun, format_reader=format_reader, passwords_in_plaintext=passwords_in_plaintext, ) if dryrun: return sendResult(response, result) # -------------------------------------------------------------- -- # create / extend target realm for the resolver resolver_spec = import_handler.get_resolver_spec() db.session.commit() return sendResult(response, result) except PolicyException as pexx: log.error("Error during user import: %r", pexx) db.session.rollback() return sendError(response, "%r" % pexx, 1) except Exception as exx: log.error("Error during user import: %r", exx) db.session.rollback() return sendError(response, exx) finally: log.debug("done")