dcd3a63128
The JSONRedirect/JSONOK/JSONError functions were put into "Base" context incorrectly, it would cause abuse. Actually, they are for "web context" only, so, move them to the correct place. And by the way, use them to simplify old code: +75 -196
122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
// Copyright 2014 The Gogs Authors. All rights reserved.
|
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package security
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
auth_model "code.gitea.io/gitea/models/auth"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
"code.gitea.io/gitea/modules/base"
|
|
"code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/services/auth/source/oauth2"
|
|
)
|
|
|
|
const (
|
|
tplSettingsSecurity base.TplName = "user/settings/security/security"
|
|
tplSettingsTwofaEnroll base.TplName = "user/settings/security/twofa_enroll"
|
|
)
|
|
|
|
// Security render change user's password page and 2FA
|
|
func Security(ctx *context.Context) {
|
|
ctx.Data["Title"] = ctx.Tr("settings.security")
|
|
ctx.Data["PageIsSettingsSecurity"] = true
|
|
|
|
if ctx.FormString("openid.return_to") != "" {
|
|
settingsOpenIDVerify(ctx)
|
|
return
|
|
}
|
|
|
|
loadSecurityData(ctx)
|
|
|
|
ctx.HTML(http.StatusOK, tplSettingsSecurity)
|
|
}
|
|
|
|
// DeleteAccountLink delete a single account link
|
|
func DeleteAccountLink(ctx *context.Context) {
|
|
id := ctx.FormInt64("id")
|
|
if id <= 0 {
|
|
ctx.Flash.Error("Account link id is not given")
|
|
} else {
|
|
if _, err := user_model.RemoveAccountLink(ctx.Doer, id); err != nil {
|
|
ctx.Flash.Error("RemoveAccountLink: " + err.Error())
|
|
} else {
|
|
ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success"))
|
|
}
|
|
}
|
|
|
|
ctx.JSONRedirect(setting.AppSubURL + "/user/settings/security")
|
|
}
|
|
|
|
func loadSecurityData(ctx *context.Context) {
|
|
enrolled, err := auth_model.HasTwoFactorByUID(ctx.Doer.ID)
|
|
if err != nil {
|
|
ctx.ServerError("SettingsTwoFactor", err)
|
|
return
|
|
}
|
|
ctx.Data["TOTPEnrolled"] = enrolled
|
|
|
|
credentials, err := auth_model.GetWebAuthnCredentialsByUID(ctx.Doer.ID)
|
|
if err != nil {
|
|
ctx.ServerError("GetWebAuthnCredentialsByUID", err)
|
|
return
|
|
}
|
|
ctx.Data["WebAuthnCredentials"] = credentials
|
|
|
|
tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID})
|
|
if err != nil {
|
|
ctx.ServerError("ListAccessTokens", err)
|
|
return
|
|
}
|
|
ctx.Data["Tokens"] = tokens
|
|
|
|
accountLinks, err := user_model.ListAccountLinks(ctx.Doer)
|
|
if err != nil {
|
|
ctx.ServerError("ListAccountLinks", err)
|
|
return
|
|
}
|
|
|
|
// map the provider display name with the AuthSource
|
|
sources := make(map[*auth_model.Source]string)
|
|
for _, externalAccount := range accountLinks {
|
|
if authSource, err := auth_model.GetSourceByID(externalAccount.LoginSourceID); err == nil {
|
|
var providerDisplayName string
|
|
|
|
type DisplayNamed interface {
|
|
DisplayName() string
|
|
}
|
|
|
|
type Named interface {
|
|
Name() string
|
|
}
|
|
|
|
if displayNamed, ok := authSource.Cfg.(DisplayNamed); ok {
|
|
providerDisplayName = displayNamed.DisplayName()
|
|
} else if named, ok := authSource.Cfg.(Named); ok {
|
|
providerDisplayName = named.Name()
|
|
} else {
|
|
providerDisplayName = authSource.Name
|
|
}
|
|
sources[authSource] = providerDisplayName
|
|
}
|
|
}
|
|
ctx.Data["AccountLinks"] = sources
|
|
|
|
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers()
|
|
if err != nil {
|
|
ctx.ServerError("GetActiveOAuth2Providers", err)
|
|
return
|
|
}
|
|
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
|
ctx.Data["OAuth2Providers"] = oauth2Providers
|
|
|
|
openid, err := user_model.GetUserOpenIDs(ctx.Doer.ID)
|
|
if err != nil {
|
|
ctx.ServerError("GetUserOpenIDs", err)
|
|
return
|
|
}
|
|
ctx.Data["OpenIDs"] = openid
|
|
}
|