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