1
0
mirror of https://github.com/0rangebananaspy/authelia.git synced 2024-09-14 22:47:21 +07:00
authelia/internal/handlers/handler_register_duo_device.go
James Elliott ce6bf74c8d
fix(server): incorrect remote ip logged in error handler ()
This fixes edge cases where the remote IP was not correctly logged. Generally this is not an issue as most errors do not hit this handler, but in instances where a transport error occurs this is important.
2022-04-08 14:13:47 +10:00

121 lines
3.9 KiB
Go

package handlers
import (
"fmt"
"net/url"
"strings"
"github.com/authelia/authelia/v4/internal/duo"
"github.com/authelia/authelia/v4/internal/middlewares"
"github.com/authelia/authelia/v4/internal/model"
"github.com/authelia/authelia/v4/internal/utils"
)
// DuoDevicesGET handler for retrieving available devices and capabilities from duo api.
func DuoDevicesGET(duoAPI duo.API) middlewares.RequestHandler {
return func(ctx *middlewares.AutheliaCtx) {
userSession := ctx.GetSession()
values := url.Values{}
values.Set("username", userSession.Username)
ctx.Logger.Debugf("Starting Duo PreAuth for %s", userSession.Username)
result, message, devices, enrollURL, err := DuoPreAuth(ctx, duoAPI)
if err != nil {
ctx.Error(fmt.Errorf("duo PreAuth API errored: %s", err), messageMFAValidationFailed)
return
}
if result == auth {
if devices == nil {
ctx.Logger.Debugf("No applicable device/method available for Duo user %s", userSession.Username)
if err := ctx.SetJSONBody(DuoDevicesResponse{Result: enroll}); err != nil {
ctx.Error(fmt.Errorf("unable to set JSON body in response"), messageMFAValidationFailed)
}
return
}
if err := ctx.SetJSONBody(DuoDevicesResponse{Result: auth, Devices: devices}); err != nil {
ctx.Error(fmt.Errorf("unable to set JSON body in response"), messageMFAValidationFailed)
}
return
}
if result == allow {
ctx.Logger.Debugf("Device selection not possible for user %s, because Duo authentication was bypassed - Defaults to Auto Push", userSession.Username)
if err := ctx.SetJSONBody(DuoDevicesResponse{Result: allow}); err != nil {
ctx.Error(fmt.Errorf("unable to set JSON body in response"), messageMFAValidationFailed)
}
return
}
if result == enroll {
ctx.Logger.Debugf("Duo user: %s not enrolled", userSession.Username)
if err := ctx.SetJSONBody(DuoDevicesResponse{Result: enroll, EnrollURL: enrollURL}); err != nil {
ctx.Error(fmt.Errorf("unable to set JSON body in response"), messageMFAValidationFailed)
}
return
}
if result == deny {
ctx.Logger.Debugf("Duo User not allowed to authenticate: %s", userSession.Username)
if err := ctx.SetJSONBody(DuoDevicesResponse{Result: deny}); err != nil {
ctx.Error(fmt.Errorf("unable to set JSON body in response"), messageMFAValidationFailed)
}
return
}
ctx.Error(fmt.Errorf("duo PreAuth API errored for %s: %s - %s", userSession.Username, result, message), messageMFAValidationFailed)
}
}
// DuoDevicePOST update the user preferences regarding Duo device and method.
func DuoDevicePOST(ctx *middlewares.AutheliaCtx) {
device := DuoDeviceBody{}
err := ctx.ParseBody(&device)
if err != nil {
ctx.Error(err, messageMFAValidationFailed)
return
}
if !utils.IsStringInSlice(device.Method, duo.PossibleMethods) {
ctx.Error(fmt.Errorf("unknown method '%s', it should be one of %s", device.Method, strings.Join(duo.PossibleMethods, ", ")), messageMFAValidationFailed)
return
}
userSession := ctx.GetSession()
ctx.Logger.Debugf("Save new preferred Duo device and method of user %s to %s using %s", userSession.Username, device.Device, device.Method)
err = ctx.Providers.StorageProvider.SavePreferredDuoDevice(ctx, model.DuoDevice{Username: userSession.Username, Device: device.Device, Method: device.Method})
if err != nil {
ctx.Error(fmt.Errorf("unable to save new preferred Duo device and method: %s", err), messageMFAValidationFailed)
return
}
ctx.ReplyOK()
}
// SecondFactorDuoDeviceDelete deletes the useres preferred Duo device and method.
func SecondFactorDuoDeviceDelete(ctx *middlewares.AutheliaCtx) {
userSession := ctx.GetSession()
ctx.Logger.Debugf("Deleting preferred Duo device and method of user %s", userSession.Username)
err := ctx.Providers.StorageProvider.DeletePreferredDuoDevice(ctx, userSession.Username)
if err != nil {
ctx.Error(fmt.Errorf("unable to delete preferred Duo device and method: %s", err), messageMFAValidationFailed)
return
}
ctx.ReplyOK()
}