mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-27 14:13:52 +03:00
feat: Add option to disable builtin authentication.
Setting ENABLE_INTERNAL_SIGNIN to false will disable the built-in signin form, should the administrator prefer to limit users to SSO. Continuation of forgejo/forgejo#6076
This commit is contained in:
parent
48b91fa31a
commit
a126477e86
6 changed files with 59 additions and 0 deletions
|
@ -901,6 +901,9 @@ LEVEL = Info
|
||||||
;; Show Registration button
|
;; Show Registration button
|
||||||
;SHOW_REGISTRATION_BUTTON = true
|
;SHOW_REGISTRATION_BUTTON = true
|
||||||
;;
|
;;
|
||||||
|
;; Whether to allow internal signin
|
||||||
|
; ENABLE_INTERNAL_SIGNIN = true
|
||||||
|
;;
|
||||||
;; Show milestones dashboard page - a view of all the user's milestones
|
;; Show milestones dashboard page - a view of all the user's milestones
|
||||||
;SHOW_MILESTONES_DASHBOARD_PAGE = true
|
;SHOW_MILESTONES_DASHBOARD_PAGE = true
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -43,6 +43,7 @@ var Service = struct {
|
||||||
AllowOnlyInternalRegistration bool
|
AllowOnlyInternalRegistration bool
|
||||||
AllowOnlyExternalRegistration bool
|
AllowOnlyExternalRegistration bool
|
||||||
ShowRegistrationButton bool
|
ShowRegistrationButton bool
|
||||||
|
EnableInternalSignIn bool
|
||||||
ShowMilestonesDashboardPage bool
|
ShowMilestonesDashboardPage bool
|
||||||
RequireSignInView bool
|
RequireSignInView bool
|
||||||
EnableNotifyMail bool
|
EnableNotifyMail bool
|
||||||
|
@ -175,6 +176,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
|
||||||
Service.EmailDomainBlockList = append(Service.EmailDomainBlockList, toAdd...)
|
Service.EmailDomainBlockList = append(Service.EmailDomainBlockList, toAdd...)
|
||||||
}
|
}
|
||||||
Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
|
Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
|
||||||
|
Service.EnableInternalSignIn = sec.Key("ENABLE_INTERNAL_SIGNIN").MustBool(true)
|
||||||
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
|
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
|
||||||
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
|
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
|
||||||
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
|
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
|
||||||
|
|
|
@ -164,6 +164,7 @@ func SignIn(ctx *context.Context) {
|
||||||
ctx.Data["PageIsSignIn"] = true
|
ctx.Data["PageIsSignIn"] = true
|
||||||
ctx.Data["PageIsLogin"] = true
|
ctx.Data["PageIsLogin"] = true
|
||||||
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
|
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
|
||||||
|
ctx.Data["EnableInternalSignIn"] = setting.Service.EnableInternalSignIn
|
||||||
|
|
||||||
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
|
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
|
||||||
context.SetCaptchaData(ctx)
|
context.SetCaptchaData(ctx)
|
||||||
|
@ -187,6 +188,13 @@ func SignInPost(ctx *context.Context) {
|
||||||
ctx.Data["PageIsSignIn"] = true
|
ctx.Data["PageIsSignIn"] = true
|
||||||
ctx.Data["PageIsLogin"] = true
|
ctx.Data["PageIsLogin"] = true
|
||||||
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
|
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
|
||||||
|
ctx.Data["EnableInternalSignIn"] = setting.Service.EnableInternalSignIn
|
||||||
|
|
||||||
|
// Permission denied if EnableInternalSignIn is false
|
||||||
|
if !setting.Service.EnableInternalSignIn {
|
||||||
|
ctx.Error(http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.HTML(http.StatusOK, tplSignIn)
|
ctx.HTML(http.StatusOK, tplSignIn)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
{{if or .OAuth2Providers .EnableOpenIDSignIn}}
|
{{if or .OAuth2Providers .EnableOpenIDSignIn}}
|
||||||
|
{{if .EnableInternalSignIn}}
|
||||||
<div class="divider divider-text">
|
<div class="divider divider-text">
|
||||||
{{ctx.Locale.Tr "sign_in_or"}}
|
{{ctx.Locale.Tr "sign_in_or"}}
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
||||||
<div id="oauth2-login-navigator" class="tw-py-1">
|
<div id="oauth2-login-navigator" class="tw-py-1">
|
||||||
<div class="tw-flex tw-flex-col tw-justify-center">
|
<div class="tw-flex tw-flex-col tw-justify-center">
|
||||||
<div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2">
|
<div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2">
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached segment">
|
<div class="ui attached segment">
|
||||||
|
{{if .EnableInternalSignIn}}
|
||||||
<form class="ui form" action="{{.SignInLink}}" method="post">
|
<form class="ui form" action="{{.SignInLink}}" method="post">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
<div class="required field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
|
<div class="required field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
{{template "user/auth/oauth_container" .}}
|
{{template "user/auth/oauth_container" .}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/test"
|
||||||
"code.gitea.io/gitea/modules/translation"
|
"code.gitea.io/gitea/modules/translation"
|
||||||
"code.gitea.io/gitea/tests"
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
|
@ -93,3 +94,44 @@ func TestSigninWithRememberMe(t *testing.T) {
|
||||||
req = NewRequest(t, "GET", "/user/settings")
|
req = NewRequest(t, "GET", "/user/settings")
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
session.MakeRequest(t, req, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDisableSignin(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
t.Run("Disabled", func(t *testing.T) {
|
||||||
|
defer test.MockVariableValue(&setting.Service.EnableInternalSignIn, false)()
|
||||||
|
|
||||||
|
t.Run("UI", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/user/login")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
htmlDoc.AssertElement(t, "form[action='/user/login']", false)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Signin", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
req := NewRequest(t, "POST", "/user/login")
|
||||||
|
MakeRequest(t, req, http.StatusForbidden)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Enabled", func(t *testing.T) {
|
||||||
|
defer test.MockVariableValue(&setting.Service.EnableInternalSignIn, true)()
|
||||||
|
|
||||||
|
t.Run("UI", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/user/login")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
htmlDoc.AssertElement(t, "form[action='/user/login']", true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Signin", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
req := NewRequest(t, "POST", "/user/login")
|
||||||
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue