2019-12-07 18:18:22 +07:00
package handlers
import (
2022-03-28 08:26:30 +07:00
"database/sql"
"errors"
2019-12-07 18:18:22 +07:00
"fmt"
"strings"
2020-04-05 19:37:21 +07:00
2021-08-11 08:04:35 +07:00
"github.com/authelia/authelia/v4/internal/middlewares"
2022-03-28 08:26:30 +07:00
"github.com/authelia/authelia/v4/internal/model"
2021-08-11 08:04:35 +07:00
"github.com/authelia/authelia/v4/internal/utils"
2019-12-07 18:18:22 +07:00
)
2022-03-28 08:26:30 +07:00
// UserInfoPOST handles setting up info for users if necessary when they login.
func UserInfoPOST ( ctx * middlewares . AutheliaCtx ) {
userSession := ctx . GetSession ( )
var (
userInfo model . UserInfo
err error
)
if _ , err = ctx . Providers . StorageProvider . LoadPreferred2FAMethod ( ctx , userSession . Username ) ; err != nil {
if errors . Is ( err , sql . ErrNoRows ) {
if err = ctx . Providers . StorageProvider . SavePreferred2FAMethod ( ctx , userSession . Username , "" ) ; err != nil {
ctx . Error ( fmt . Errorf ( "unable to load user information: %v" , err ) , messageOperationFailed )
}
} else {
ctx . Error ( fmt . Errorf ( "unable to load user information: %v" , err ) , messageOperationFailed )
}
}
if userInfo , err = ctx . Providers . StorageProvider . LoadUserInfo ( ctx , userSession . Username ) ; err != nil {
ctx . Error ( fmt . Errorf ( "unable to load user information: %v" , err ) , messageOperationFailed )
return
}
var (
changed bool
)
if changed = userInfo . SetDefaultPreferred2FAMethod ( ctx . AvailableSecondFactorMethods ( ) ) ; changed {
if err = ctx . Providers . StorageProvider . SavePreferred2FAMethod ( ctx , userSession . Username , userInfo . Method ) ; err != nil {
ctx . Error ( fmt . Errorf ( "unable to save user two factor method: %v" , err ) , messageOperationFailed )
return
}
}
userInfo . DisplayName = userSession . DisplayName
err = ctx . SetJSONBody ( userInfo )
if err != nil {
ctx . Logger . Errorf ( "Unable to set user info response in body: %s" , err )
}
}
// UserInfoGET get the info related to the user identified by the session.
func UserInfoGET ( ctx * middlewares . AutheliaCtx ) {
2019-12-07 18:18:22 +07:00
userSession := ctx . GetSession ( )
2021-11-23 16:45:38 +07:00
userInfo , err := ctx . Providers . StorageProvider . LoadUserInfo ( ctx , userSession . Username )
if err != nil {
ctx . Error ( fmt . Errorf ( "unable to load user information: %v" , err ) , messageOperationFailed )
2019-12-07 18:18:22 +07:00
return
}
2020-05-06 02:35:32 +07:00
2020-06-21 20:40:37 +07:00
userInfo . DisplayName = userSession . DisplayName
2021-11-23 16:45:38 +07:00
err = ctx . SetJSONBody ( userInfo )
2020-12-16 08:47:31 +07:00
if err != nil {
ctx . Logger . Errorf ( "Unable to set user info response in body: %s" , err )
}
2019-12-07 18:18:22 +07:00
}
// MethodPreferencePost update the user preferences regarding 2FA method.
func MethodPreferencePost ( ctx * middlewares . AutheliaCtx ) {
2021-12-01 19:11:29 +07:00
bodyJSON := preferred2FAMethodBody { }
2020-05-06 02:35:32 +07:00
2019-12-07 18:18:22 +07:00
err := ctx . ParseBody ( & bodyJSON )
if err != nil {
2021-07-22 10:52:37 +07:00
ctx . Error ( err , messageOperationFailed )
2019-12-07 18:18:22 +07:00
return
}
2022-03-28 08:26:30 +07:00
if ! utils . IsStringInSlice ( bodyJSON . Method , ctx . AvailableSecondFactorMethods ( ) ) {
ctx . Error ( fmt . Errorf ( "unknown or unavailable method '%s', it should be one of %s" , bodyJSON . Method , strings . Join ( ctx . AvailableSecondFactorMethods ( ) , ", " ) ) , messageOperationFailed )
2019-12-07 18:18:22 +07:00
return
}
userSession := ctx . GetSession ( )
2020-01-06 06:03:16 +07:00
ctx . Logger . Debugf ( "Save new preferred 2FA method of user %s to %s" , userSession . Username , bodyJSON . Method )
2021-11-23 16:45:38 +07:00
err = ctx . Providers . StorageProvider . SavePreferred2FAMethod ( ctx , userSession . Username , bodyJSON . Method )
2019-12-07 18:18:22 +07:00
if err != nil {
2021-09-17 12:53:40 +07:00
ctx . Error ( fmt . Errorf ( "unable to save new preferred 2FA method: %s" , err ) , messageOperationFailed )
2019-12-07 18:18:22 +07:00
return
}
ctx . ReplyOK ( )
}