authelia/internal/handlers/handler_user_info.go
Amir Zarrinkafsh 54694c4fca
[MISC] Ignore errcheck recommendations for legacy code (#893)
* [MISC] Ignore errcheck recommendations for legacy code
Some of this is likely intended to stay how it is, some could use refactoring, for now we will mark is and ignore it from the linter to be potentially addressed in the future.

* [MISC] Ensure files are gofmt-ed
2020-04-22 13:33:14 +10:00

112 lines
2.8 KiB
Go

package handlers
import (
"fmt"
"strings"
"sync"
"github.com/sirupsen/logrus"
"github.com/authelia/authelia/internal/authentication"
"github.com/authelia/authelia/internal/middlewares"
"github.com/authelia/authelia/internal/storage"
"github.com/authelia/authelia/internal/utils"
)
func loadInfo(username string, storageProvider storage.Provider, preferences *UserPreferences, logger *logrus.Entry) []error {
var wg sync.WaitGroup
wg.Add(3)
errors := make([]error, 0)
go func() {
defer wg.Done()
method, err := storageProvider.LoadPreferred2FAMethod(username)
if err != nil {
errors = append(errors, err)
logger.Error(err)
return
}
if method == "" {
preferences.Method = authentication.PossibleMethods[0]
} else {
preferences.Method = method
}
}()
go func() {
defer wg.Done()
_, _, err := storageProvider.LoadU2FDeviceHandle(username)
if err != nil {
if err == storage.ErrNoU2FDeviceHandle {
return
}
errors = append(errors, err)
logger.Error(err)
return
}
preferences.HasU2F = true
}()
go func() {
defer wg.Done()
_, err := storageProvider.LoadTOTPSecret(username)
if err != nil {
if err == storage.ErrNoTOTPSecret {
return
}
errors = append(errors, err)
logger.Error(err)
return
}
preferences.HasTOTP = true
}()
wg.Wait()
return errors
}
// UserInfoGet get the info related to the user identified by the session.
func UserInfoGet(ctx *middlewares.AutheliaCtx) {
userSession := ctx.GetSession()
preferences := UserPreferences{}
errors := loadInfo(userSession.Username, ctx.Providers.StorageProvider, &preferences, ctx.Logger)
if len(errors) > 0 {
ctx.Error(fmt.Errorf("Unable to load user information"), operationFailedMessage)
return
}
ctx.SetJSONBody(preferences) //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
}
// MethodBody the selected 2FA method.
type MethodBody struct {
Method string `json:"method" valid:"required"`
}
// MethodPreferencePost update the user preferences regarding 2FA method.
func MethodPreferencePost(ctx *middlewares.AutheliaCtx) {
bodyJSON := MethodBody{}
err := ctx.ParseBody(&bodyJSON)
if err != nil {
ctx.Error(err, operationFailedMessage)
return
}
if !utils.IsStringInSlice(bodyJSON.Method, authentication.PossibleMethods) {
ctx.Error(fmt.Errorf("Unknown method '%s', it should be one of %s", bodyJSON.Method, strings.Join(authentication.PossibleMethods, ", ")), operationFailedMessage)
return
}
userSession := ctx.GetSession()
ctx.Logger.Debugf("Save new preferred 2FA method of user %s to %s", userSession.Username, bodyJSON.Method)
err = ctx.Providers.StorageProvider.SavePreferred2FAMethod(userSession.Username, bodyJSON.Method)
if err != nil {
ctx.Error(fmt.Errorf("Unable to save new preferred 2FA method: %s", err), operationFailedMessage)
return
}
ctx.ReplyOK()
}