def test_12_get_allowed_tokentypes(self): set_policy(name="tt1", scope=SCOPE.AUTHZ, action="tokentype=hotp " "totp, enroll") set_policy(name="tt2", scope=SCOPE.AUTHZ, action="tokentype=motp") P = PolicyClass() ttypes = P.get_action_values("tokentype", scope=SCOPE.AUTHZ) self.assertTrue("motp" in ttypes) self.assertTrue("totp" in ttypes) self.assertTrue("hotp" in ttypes) self.assertFalse("spass" in ttypes) type_policies = P.get_action_values("tokentype", scope=SCOPE.AUTHZ) self.assertTrue("motp" in type_policies.keys()) self.assertTrue("totp" in type_policies.keys()) self.assertTrue("hotp" in type_policies.keys()) self.assertFalse("spass" in type_policies.keys()) # motp is defined in policy "tt2" self.assertEqual(type_policies.get("motp"), ["tt2"]) # totp and hotp is defined in policy "tt1" self.assertEqual(type_policies.get("hotp"), ["tt1"]) self.assertEqual(type_policies.get("totp"), ["tt1"])
def test_23_priorities_equal_actions(self): # create two policies with the same action values set_policy(name="email1", scope=SCOPE.AUTH, action="emailtext='text 1'", priority=1) set_policy(name="email2", scope=SCOPE.AUTH, action="emailtext='text 1'", priority=1) # this reduces the action values to unique values P = PolicyClass() self.assertEqual( P.get_action_values(scope=SCOPE.AUTH, action="emailtext"), ["text 1"]) # this is allowed if the policies agree self.assertEqual( P.get_action_values(scope=SCOPE.AUTH, action="emailtext", unique=True), ["text 1"]) set_policy(name="email2", action="emailtext='text 2'") P.reload_from_db() with self.assertRaises(PolicyError): P.get_action_values(scope=SCOPE.AUTH, action="emailtext", unique=True) delete_policy("email1") delete_policy("email2")
def test_13_get_allowed_serials(self): set_policy(name="st1", scope=SCOPE.AUTHZ, action="serial=OATH") set_policy(name="st2", scope=SCOPE.AUTHZ, action="serial=mOTP ") P = PolicyClass() ttypes = P.get_action_values("serial", scope=SCOPE.AUTHZ) self.assertTrue("OATH" in ttypes) self.assertTrue("mOTP" in ttypes) self.assertFalse("TOTP" in ttypes) serial_policies = P.get_action_values("serial", scope=SCOPE.AUTHZ) self.assertEqual(serial_policies.get("OATH"), ["st1"]) self.assertEqual(serial_policies.get("mOTP"), ["st2"])
def test_25_get_action_values(self): # We test action values with different priority and values! set_policy("act1", scope=SCOPE.AUTH, action="{0!s}=userstore".format(ACTION.OTPPIN), priority=1) set_policy("act2", scope=SCOPE.AUTH, action="{0!s}=userstore".format(ACTION.OTPPIN), priority=1) set_policy("act3", scope=SCOPE.AUTH, action="{0!s}=none".format(ACTION.OTPPIN), priority=3) # Now we should get the userstore action value. Both policies act1 and act2 have the unique value # with prioritoy 1 P = PolicyClass() audit_data = {} r = P.get_action_values(action=ACTION.OTPPIN, scope=SCOPE.AUTH, unique=True, audit_data=audit_data) self.assertEqual(r, {"userstore": ["act1", "act2"]}) # The audit_data contains act1 and act2 self.assertTrue("act1" in audit_data.get("policies")) self.assertTrue("act2" in audit_data.get("policies")) self.assertTrue("act3" not in audit_data.get("policies"))
def test_13_get_allowed_serials(self): set_policy(name="st1", scope=SCOPE.AUTHZ, action="serial=OATH") set_policy(name="st2", scope=SCOPE.AUTHZ, action="serial=mOTP ") P = PolicyClass() ttypes = P.get_action_values("serial", scope=SCOPE.AUTHZ) self.assertTrue("OATH" in ttypes) self.assertTrue("mOTP" in ttypes) self.assertFalse("TOTP" in ttypes)
def test_12_get_allowed_tokentypes(self): set_policy(name="tt1", scope=SCOPE.AUTHZ, action="tokentype=hotp " "totp, enroll") set_policy(name="tt2", scope=SCOPE.AUTHZ, action="tokentype=motp") P = PolicyClass() ttypes = P.get_action_values("tokentype", scope=SCOPE.AUTHZ) self.assertTrue("motp" in ttypes) self.assertTrue("totp" in ttypes) self.assertTrue("hotp" in ttypes) self.assertFalse("spass" in ttypes)
def single_page_application(): instance = request.script_root if instance == "/": instance = "" # The backend URL should come from the configuration of the system. backend_url = "" if current_app.config.get("PI_UI_DEACTIVATED"): # Do not provide the UI return render_template("deactivated.html") # The default theme. We can change this later theme = current_app.config.get("PI_CSS", DEFAULT_THEME) # Get further customizations customization = current_app.config.get("PI_CUSTOMIZATION", "/static/customize/") customization = customization.strip('/') # TODO: we should add the CSS into PI_CUSTOMZATION/css # Enrollment-Wizard: # PI_CUSTOMIZATION/views/includes/token.enroll.pre.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.pre.bottom.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.bottom.html # Get the hidden external links external_links = current_app.config.get("PI_EXTERNAL_LINKS", True) # Get the logo file logo = current_app.config.get("PI_LOGO", "privacyIDEA1.png") browser_lang = request.accept_languages.best_match( ["en", "de", "de-DE"], default="en").split("-")[0] # The page title can be configured in pi.cfg page_title = current_app.config.get("PI_PAGE_TITLE", "privacyIDEA Authentication System") # check if login with REMOTE_USER is allowed. remote_user = "" password_reset = False if not hasattr(request, "all_data"): request.all_data = {} # Depending on displaying the realm dropdown, we fill realms or not. policy_object = PolicyClass() realms = "" client_ip = get_client_ip(request, get_from_config(SYSCONF.OVERRIDECLIENT)) realm_dropdown = policy_object.get_policies(action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip, active=True) if realm_dropdown: try: realm_dropdown_values = policy_object.get_action_values( action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip) # Use the realms from the policy. realms = ",".join(realm_dropdown_values) except AttributeError as ex: # The policy is still a boolean realm_dropdown action # Thus we display ALL realms realms = ",".join(get_realms()) try: if is_remote_user_allowed(request): remote_user = request.remote_user password_reset = is_password_reset() hsm_ready = True except HSMException: hsm_ready = False # Use policies to determine the customization of menu # and baseline. get_action_values returns an array! sub_state = subscription_status() customization_menu_file = policy_object.get_action_values( allow_white_space_in_action=True, action=ACTION.CUSTOM_MENU, scope=SCOPE.WEBUI, client=client_ip, unique=True) if len(customization_menu_file) and list(customization_menu_file)[0] \ and sub_state not in [1, 2]: customization_menu_file = list(customization_menu_file)[0] else: customization_menu_file = "templates/menu.html" customization_baseline_file = policy_object.get_action_values( allow_white_space_in_action=True, action=ACTION.CUSTOM_BASELINE, scope=SCOPE.WEBUI, client=client_ip, unique=True) if len(customization_baseline_file) and list(customization_baseline_file)[0] \ and sub_state not in [1, 2]: customization_baseline_file = list(customization_baseline_file)[0] else: customization_baseline_file = "templates/baseline.html" login_text = policy_object.get_action_values( allow_white_space_in_action=True, action=ACTION.LOGIN_TEXT, scope=SCOPE.WEBUI, client=client_ip, unique=True) if len(login_text) and list(login_text)[0] and sub_state not in [1, 2]: login_text = list(login_text)[0] else: login_text = "" return render_template( "index.html", instance=instance, backendUrl=backend_url, browser_lang=browser_lang, remote_user=remote_user, theme=theme, password_reset=password_reset, hsm_ready=hsm_ready, has_job_queue=str(has_job_queue()), customization=customization, customization_menu_file=customization_menu_file, customization_baseline_file=customization_baseline_file, realms=realms, external_links=external_links, login_text=login_text, logo=logo, page_title=page_title)
def single_page_application(): instance = request.script_root if instance == "/": instance = "" # The backend URL should come from the configuration of the system. backend_url = "" if current_app.config.get("PI_UI_DEACTIVATED"): # Do not provide the UI return render_template("deactivated.html") # The default theme. We can change this later theme = current_app.config.get("PI_CSS", DEFAULT_THEME) # Get further customizations customization = current_app.config.get("PI_CUSTOMIZATION", "/static/customize/") customization = customization.strip('/') # TODO: we should add the CSS into PI_CUSTOMZATION/css # Enrollment-Wizard: # PI_CUSTOMIZATION/views/includes/token.enroll.pre.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.pre.bottom.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.bottom.html # Get the hidden external links external_links = current_app.config.get("PI_EXTERNAL_LINKS", True) # Get the logo file logo = current_app.config.get("PI_LOGO", "privacyIDEA1.png") browser_lang = request.accept_languages.best_match(["en", "de"]) # check if login with REMOTE_USER is allowed. remote_user = "" password_reset = False if not hasattr(request, "all_data"): request.all_data = {} # Depending on displaying the realm dropdown, we fill realms or not. policy_object = PolicyClass() realms = "" client_ip = request.access_route[0] if request.access_route else \ request.remote_addr realm_dropdown = policy_object.get_policies(action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip, active=True) if realm_dropdown: try: realm_dropdown_values = policy_object.get_action_values( action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip) # Use the realms from the policy. realms = ",".join(realm_dropdown_values) except AttributeError as ex: # The policy is still a boolean realm_dropdown action # Thus we display ALL realms realms = ",".join(get_realms().keys()) if realms: realms = "," + realms try: if is_remote_user_allowed(request): remote_user = request.remote_user password_reset = is_password_reset() hsm_ready = True except HSMException: hsm_ready = False # Use policies to determine the customization of menu # and baseline. get_action_values returns an array! sub_state = subscription_status() customization_menu_file = policy_object.get_action_values( allow_white_space_in_action=True, action=ACTION.CUSTOM_MENU, scope=SCOPE.WEBUI, client=client_ip, unique=True) if len(customization_menu_file) and customization_menu_file[0] \ and sub_state not in [1, 2]: customization_menu_file = customization_menu_file[0] else: customization_menu_file = "templates/menu.html" customization_baseline_file = policy_object.get_action_values( allow_white_space_in_action=True, action=ACTION.CUSTOM_BASELINE, scope=SCOPE.WEBUI, client=client_ip, unique=True) if len(customization_baseline_file) and customization_baseline_file[0] \ and sub_state not in [1, 2]: customization_baseline_file = customization_baseline_file[0] else: customization_baseline_file = "templates/baseline.html" return render_template("index.html", instance=instance, backendUrl=backend_url, browser_lang=browser_lang, remote_user=remote_user, theme=theme, password_reset=password_reset, hsm_ready=hsm_ready, customization=customization, customization_menu_file=customization_menu_file, customization_baseline_file=customization_baseline_file, realms=realms, external_links=external_links, logo=logo)
def test_23_priorities(self): # create three policies with three different texts and different priorities set_policy(name="email1", scope=SCOPE.AUTH, action="emailtext=text 1", priority=4) set_policy(name="email2", scope=SCOPE.AUTH, action="emailtext=text 2", priority=1) set_policy(name="email3", scope=SCOPE.AUTH, action="emailtext=text 3", priority=77) # this chooses email2, because it has the highest priority P = PolicyClass() self.assertEqual( P.get_action_values(action="emailtext", scope=SCOPE.AUTH, unique=True, allow_white_space_in_action=True), ["text 2"]) delete_policy("email2") P.reload_from_db() # with email2 gone, this chooses email1 self.assertEqual( P.get_action_values(action="emailtext", scope=SCOPE.AUTH, unique=True, allow_white_space_in_action=True), ["text 1"]) # if we now add another policy with priority 77, we get no conflict # because email1 is chosen set_policy(name="email4", scope=SCOPE.AUTH, action="emailtext=text 4", priority=77) P.reload_from_db() self.assertEqual( P.get_action_values(action="emailtext", scope=SCOPE.AUTH, unique=True, allow_white_space_in_action=True), ["text 1"]) # but we get a conflict if we change the priority of email4 to 4 set_policy(name="email4", scope=SCOPE.AUTH, action="emailtext=text 4", priority=4) P.reload_from_db() with self.assertRaises(PolicyError) as cm: P.get_action_values(action="emailtext", scope=SCOPE.AUTH, unique=True, allow_white_space_in_action=True) self.assertIn("policies with conflicting actions", str(cm.exception)) pols = P.get_policies(action="emailtext", scope=SCOPE.AUTH) self.assertEqual(len(pols), 3) with self.assertRaises(PolicyError) as cm: P.check_for_conflicts(pols, "emailtext") P.check_for_conflicts([], "emailtext") P.check_for_conflicts([pols[0]], "emailtext") # we can also change the priority set_policy(name="email4", priority=3) P.reload_from_db() self.assertEqual( P.get_action_values(action="emailtext", scope=SCOPE.AUTH, unique=True, allow_white_space_in_action=True), ["text 4"]) # now we have # email1, priority=4 # email3, priority=77 # email4, priority=3 # export, delete all, re-import exported = export_policies(P.get_policies()) self.assertIn("priority = 4", exported) self.assertIn("priority = 77", exported) delete_all_policies() import_policies(exported) pols = P.get_policies(action="emailtext", scope=SCOPE.AUTH) self.assertEqual(len(pols), 3) # this sorts by priority self.assertEqual([p['name'] for p in pols], ['email4', 'email1', 'email3']) # priority must be at least 1 with self.assertRaises(ParameterError): set_policy(name="email4", scope=SCOPE.AUTH, priority=0) with self.assertRaises(ParameterError): set_policy(name="email4", scope=SCOPE.AUTH, priority=-5) delete_policy("email1") delete_policy("email3") delete_policy("email4")
def single_page_application(): instance = request.script_root if instance == "/": instance = "" # The backend URL should come from the configuration of the system. backend_url = "" if current_app.config.get("PI_UI_DEACTIVATED"): # Do not provide the UI return render_template("deactivated.html") # The default theme. We can change this later theme = current_app.config.get("PI_CSS", DEFAULT_THEME) # Get further customizations customization = current_app.config.get("PI_CUSTOMIZATION", "/static/customize/") customization = customization.strip('/') # TODO: we should add the CSS into PI_CUSTOMZATION/css # Enrollment-Wizard: # PI_CUSTOMIZATION/views/includes/token.enroll.pre.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.pre.bottom.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.bottom.html # Get the hidden external links external_links = current_app.config.get("PI_EXTERNAL_LINKS", True) # Get the logo file logo = current_app.config.get("PI_LOGO", "privacyIDEA1.png") browser_lang = request.accept_languages.best_match(["en", "de"]) # check if login with REMOTE_USER is allowed. remote_user = "" password_reset = False if not hasattr(request, "all_data"): request.all_data = {} # Depending on displaying the realm dropdown, we fill realms or not. policy_object = PolicyClass() realms = "" client_ip = request.access_route[0] if request.access_route else \ request.remote_addr realm_dropdown = policy_object.get_policies(action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip, active=True) if realm_dropdown: try: realm_dropdown_values = policy_object.get_action_values( action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip) # Use the realms from the policy. realms = ",".join(realm_dropdown_values) except AttributeError as ex: # The policy is still a boolean realm_dropdown action # Thus we display ALL realms realms = ",".join(get_realms().keys()) if realms: realms = "," + realms try: if is_remote_user_allowed(request): remote_user = request.remote_user password_reset = is_password_reset() hsm_ready = True except HSMException: hsm_ready = False return render_template("index.html", instance=instance, backendUrl=backend_url, browser_lang=browser_lang, remote_user=remote_user, theme=theme, password_reset=password_reset, hsm_ready=hsm_ready, customization=customization, realms=realms, external_links=external_links, logo=logo)
def single_page_application(): instance = request.script_root if instance == "/": instance = "" # The backend URL should come from the configuration of the system. backend_url = "" if current_app.config.get("PI_UI_DEACTIVATED"): # Do not provide the UI return render_template("deactivated.html") # The default theme. We can change this later theme = current_app.config.get("PI_CSS", DEFAULT_THEME) # Get further customizations customization = current_app.config.get("PI_CUSTOMIZATION", "/static/customize/") customization = customization.strip('/') # TODO: we should add the CSS into PI_CUSTOMZATION/css # Enrollment-Wizard: # PI_CUSTOMIZATION/views/includes/token.enroll.pre.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.pre.bottom.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.top.html # PI_CUSTOMIZATION/views/includes/token.enroll.post.bottom.html browser_lang = request.accept_languages.best_match(["en", "de"]) # check if login with REMOTE_USER is allowed. remote_user = "" password_reset = False if not hasattr(request, "all_data"): request.all_data = {} # Depending on displaying the realm dropdown, we fill realms or not. policy_object = PolicyClass() realms = "" client_ip = request.access_route[0] if request.access_route else \ request.remote_addr realm_dropdown = policy_object.get_policies(action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip) if realm_dropdown: try: realm_dropdown_values = policy_object.get_action_values( action=ACTION.REALMDROPDOWN, scope=SCOPE.WEBUI, client=client_ip) # Use the realms from the policy. realms = ",".join(realm_dropdown_values) except AttributeError as ex: # The policy is still a boolean realm_dropdown action # Thus we display ALL realms realms = ",".join(get_realms().keys()) if realms: realms = "," + realms try: if is_remote_user_allowed(request): remote_user = request.remote_user password_reset = is_password_reset() hsm_ready = True except HSMException: hsm_ready = False return render_template("index.html", instance=instance, backendUrl=backend_url, browser_lang=browser_lang, remote_user=remote_user, theme=theme, password_reset=password_reset, hsm_ready=hsm_ready, customization=customization, realms=realms)