Show More
@@ -176,9 +176,6 b' class BaseAppView(object):' | |||
|
176 | 176 | if not user_obj: |
|
177 | 177 | return |
|
178 | 178 | |
|
179 | if user_obj.has_forced_2fa and user_obj.extern_type != 'rhodecode': | |
|
180 | return | |
|
181 | ||
|
182 | 179 | if user_obj.needs_2fa_configure and view_name != self.SETUP_2FA_VIEW: |
|
183 | 180 | h.flash( |
|
184 | 181 | "You are required to configure 2FA", |
@@ -31,7 +31,7 b' import urllib.parse' | |||
|
31 | 31 | from rhodecode.translation import _ |
|
32 | 32 | from rhodecode.authentication.base import ( |
|
33 | 33 | RhodeCodeExternalAuthPlugin, hybrid_property) |
|
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin | |
|
35 | 35 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
36 | 36 | from rhodecode.lib.colander_utils import strip_whitespace |
|
37 | 37 | from rhodecode.lib.ext_json import json, formatted_json |
@@ -53,7 +53,7 b' class CrowdAuthnResource(AuthnPluginReso' | |||
|
53 | 53 | pass |
|
54 | 54 | |
|
55 | 55 | |
|
56 | class CrowdSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
56 | class CrowdSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): | |
|
57 | 57 | host = colander.SchemaNode( |
|
58 | 58 | colander.String(), |
|
59 | 59 | default='127.0.0.1', |
@@ -33,7 +33,7 b' import urllib.error' | |||
|
33 | 33 | from rhodecode.translation import _ |
|
34 | 34 | from rhodecode.authentication.base import ( |
|
35 | 35 | RhodeCodeExternalAuthPlugin, hybrid_property) |
|
36 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
36 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin | |
|
37 | 37 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
38 | 38 | from rhodecode.lib.colander_utils import strip_whitespace |
|
39 | 39 | from rhodecode.model.db import User |
@@ -55,7 +55,7 b' class JasigCasAuthnResource(AuthnPluginR' | |||
|
55 | 55 | pass |
|
56 | 56 | |
|
57 | 57 | |
|
58 | class JasigCasSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
58 | class JasigCasSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): | |
|
59 | 59 | service_url = colander.SchemaNode( |
|
60 | 60 | colander.String(), |
|
61 | 61 | default='https://domain.com/cas/v1/tickets', |
@@ -27,7 +27,7 b' import colander' | |||
|
27 | 27 | from rhodecode.translation import _ |
|
28 | 28 | from rhodecode.authentication.base import ( |
|
29 | 29 | RhodeCodeExternalAuthPlugin, AuthLdapBase, hybrid_property) |
|
30 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
30 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin | |
|
31 | 31 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
32 | 32 | from rhodecode.lib.colander_utils import strip_whitespace |
|
33 | 33 | from rhodecode.lib.exceptions import ( |
@@ -245,7 +245,7 b' class AuthLdap(AuthLdapBase):' | |||
|
245 | 245 | return dn, user_attrs |
|
246 | 246 | |
|
247 | 247 | |
|
248 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
248 | class LdapSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): | |
|
249 | 249 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] |
|
250 | 250 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] |
|
251 | 251 | search_scope_choices = ['BASE', 'ONELEVEL', 'SUBTREE'] |
@@ -31,7 +31,7 b' import socket' | |||
|
31 | 31 | from rhodecode.translation import _ |
|
32 | 32 | from rhodecode.authentication.base import ( |
|
33 | 33 | RhodeCodeExternalAuthPlugin, hybrid_property) |
|
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin | |
|
35 | 35 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
36 | 36 | from rhodecode.lib.colander_utils import strip_whitespace |
|
37 | 37 | |
@@ -51,7 +51,7 b' class PamAuthnResource(AuthnPluginResour' | |||
|
51 | 51 | pass |
|
52 | 52 | |
|
53 | 53 | |
|
54 | class PamSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
54 | class PamSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): | |
|
55 | 55 | service = colander.SchemaNode( |
|
56 | 56 | colander.String(), |
|
57 | 57 | default='login', |
@@ -27,7 +27,7 b' import colander' | |||
|
27 | 27 | from rhodecode.translation import _ |
|
28 | 28 | from rhodecode.lib.utils2 import safe_bytes |
|
29 | 29 | from rhodecode.model.db import User |
|
30 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
30 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin | |
|
31 | 31 | from rhodecode.authentication.base import ( |
|
32 | 32 | RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE) |
|
33 | 33 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
@@ -182,16 +182,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
182 | 182 | return None |
|
183 | 183 | |
|
184 | 184 | |
|
185 | class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
186 | global_2fa = colander.SchemaNode( | |
|
187 | colander.Bool(), | |
|
188 | default=False, | |
|
189 | description=_('Force all users to use two factor authentication by enabling this.'), | |
|
190 | missing=False, | |
|
191 | title=_('Global 2FA'), | |
|
192 | widget='bool', | |
|
193 | ) | |
|
194 | ||
|
185 | class RhodeCodeSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): | |
|
195 | 186 | auth_restriction_choices = [ |
|
196 | 187 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, 'All users'), |
|
197 | 188 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, 'Super admins only'), |
@@ -48,3 +48,17 b' class AuthnPluginSettingsSchemaBase(cola' | |||
|
48 | 48 | validator=colander.Range(min=0, max=None), |
|
49 | 49 | widget='int', |
|
50 | 50 | ) |
|
51 | ||
|
52 | ||
|
53 | class TwoFactorAuthnPluginSettingsSchemaMixin(colander.MappingSchema): | |
|
54 | """ | |
|
55 | Mixin for extending plugins with two-factor authentication option. | |
|
56 | """ | |
|
57 | global_2fa = colander.SchemaNode( | |
|
58 | colander.Bool(), | |
|
59 | default=False, | |
|
60 | description=_('Force all users to use two factor authentication with this plugin.'), | |
|
61 | missing=False, | |
|
62 | title=_('enforce 2FA for users'), | |
|
63 | widget='bool', | |
|
64 | ) |
@@ -810,11 +810,10 b' class User(Base, BaseModel):' | |||
|
810 | 810 | @hybrid_property |
|
811 | 811 | def has_forced_2fa(self): |
|
812 | 812 | """ |
|
813 |
Checks if 2fa was forced for |
|
|
813 | Checks if 2fa was forced for current user | |
|
814 | 814 | """ |
|
815 | 815 | from rhodecode.model.settings import SettingsModel |
|
816 | # So now we're supporting only auth_rhodecode_global_2fa | |
|
817 | if value := SettingsModel().get_setting_by_name('auth_rhodecode_global_2fa'): | |
|
816 | if value := SettingsModel().get_setting_by_name(f'{self.extern_type}_global_2fa'): | |
|
818 | 817 | return value.app_settings_value |
|
819 | 818 | return False |
|
820 | 819 |
@@ -63,7 +63,12 b'' | |||
|
63 | 63 | %elif node.widget == "password": |
|
64 | 64 | ${h.password(node.name, defaults.get(node.name), class_="large")} |
|
65 | 65 | %elif node.widget == "bool": |
|
66 | %if node.name == "global_2fa" and c.rhodecode_edition_id != "EE": | |
|
67 | <input type="checkbox" disabled/> | |
|
68 | <%node.description = _('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')%> | |
|
69 | %else: | |
|
66 | 70 | <div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div> |
|
71 | %endif | |
|
67 | 72 | %elif node.widget == "select": |
|
68 | 73 | ${h.select(node.name, defaults.get(node.name), node.validator.choices, class_="select2AuthSetting")} |
|
69 | 74 | %elif node.widget == "select_with_labels": |
@@ -80,7 +85,7 b'' | |||
|
80 | 85 | <span class="error-message">${errors.get(node.name)}</span> |
|
81 | 86 | <br /> |
|
82 | 87 | %endif |
|
83 | <p class="help-block pre-formatting">${node.description}</p> | |
|
88 | <p class="help-block pre-formatting">${node.description | n}</p> | |
|
84 | 89 | </div> |
|
85 | 90 | </div> |
|
86 | 91 | %endfor |
General Comments 0
You need to be logged in to leave comments.
Login now