2022-10-30 08:52:49 +00:00
package handlers
import (
2022-11-19 05:48:47 +00:00
"encoding/json"
"errors"
2022-12-31 07:27:43 +00:00
"fmt"
2022-11-19 05:48:47 +00:00
"strconv"
"github.com/valyala/fasthttp"
2022-10-30 08:52:49 +00:00
"github.com/authelia/authelia/v4/internal/middlewares"
2022-12-31 07:27:43 +00:00
"github.com/authelia/authelia/v4/internal/model"
2022-11-19 05:48:47 +00:00
"github.com/authelia/authelia/v4/internal/regulation"
2023-01-25 11:03:30 +00:00
"github.com/authelia/authelia/v4/internal/session"
2022-12-12 01:21:27 +00:00
"github.com/authelia/authelia/v4/internal/storage"
2022-10-30 08:52:49 +00:00
)
2022-11-19 05:48:47 +00:00
func getWebauthnDeviceIDFromContext ( ctx * middlewares . AutheliaCtx ) ( int , error ) {
deviceIDStr , ok := ctx . UserValue ( "deviceID" ) . ( string )
if ! ok {
ctx . SetStatusCode ( fasthttp . StatusBadRequest )
return 0 , errors . New ( "Invalid device ID type" )
}
deviceID , err := strconv . Atoi ( deviceIDStr )
if err != nil {
ctx . Error ( err , messageOperationFailed )
ctx . SetStatusCode ( fasthttp . StatusBadRequest )
return 0 , err
}
return deviceID , nil
}
2022-12-31 07:27:43 +00:00
// WebauthnDevicesGET returns all devices registered for the current user.
func WebauthnDevicesGET ( ctx * middlewares . AutheliaCtx ) {
2023-01-25 11:03:30 +00:00
var (
userSession session . UserSession
err error
)
if userSession , err = ctx . GetSession ( ) ; err != nil {
ctx . Logger . WithError ( err ) . Error ( "Error occurred retrieving user session" )
ctx . ReplyForbidden ( )
2022-10-30 08:52:49 +00:00
2023-01-25 11:03:30 +00:00
return
}
devices , err := ctx . Providers . StorageProvider . LoadWebauthnDevicesByUsername ( ctx , userSession . Username )
2022-10-30 08:52:49 +00:00
2022-12-12 01:21:27 +00:00
if err != nil && err != storage . ErrNoWebauthnDevice {
2022-10-30 08:52:49 +00:00
ctx . Error ( err , messageOperationFailed )
return
}
if err = ctx . SetJSONBody ( devices ) ; err != nil {
ctx . Error ( err , messageOperationFailed )
return
}
}
2022-11-19 05:48:47 +00:00
2022-12-31 07:27:43 +00:00
// WebauthnDevicePUT updates the description for a specific device for the current user.
func WebauthnDevicePUT ( ctx * middlewares . AutheliaCtx ) {
var (
bodyJSON bodyEditWebauthnDeviceRequest
2022-11-19 05:48:47 +00:00
2023-01-25 11:03:30 +00:00
id int
device * model . WebauthnDevice
userSession session . UserSession
err error
2022-12-31 07:27:43 +00:00
)
2022-11-19 05:48:47 +00:00
2023-01-25 11:03:30 +00:00
if userSession , err = ctx . GetSession ( ) ; err != nil {
ctx . Logger . WithError ( err ) . Error ( "Error occurred retrieving user session" )
ctx . ReplyForbidden ( )
return
}
2022-11-19 05:48:47 +00:00
2022-12-31 07:27:43 +00:00
if err = json . Unmarshal ( ctx . PostBody ( ) , & bodyJSON ) ; err != nil {
2023-01-25 11:03:30 +00:00
ctx . Logger . Errorf ( "Unable to parse %s update request data for user '%s': %+v" , regulation . AuthTypeWebauthn , userSession . Username , err )
2022-11-19 05:48:47 +00:00
ctx . SetStatusCode ( fasthttp . StatusBadRequest )
ctx . Error ( err , messageOperationFailed )
return
}
2022-12-31 07:27:43 +00:00
if id , err = getWebauthnDeviceIDFromContext ( ctx ) ; err != nil {
return
}
if device , err = ctx . Providers . StorageProvider . LoadWebauthnDeviceByID ( ctx , id ) ; err != nil {
ctx . Error ( err , messageOperationFailed )
return
}
2023-01-25 11:03:30 +00:00
if device . Username != userSession . Username {
ctx . Error ( fmt . Errorf ( "user '%s' tried to delete device with id '%d' which belongs to '%s" , userSession . Username , device . ID , device . Username ) , messageOperationFailed )
2022-11-19 05:48:47 +00:00
return
}
2023-01-25 11:03:30 +00:00
if err = ctx . Providers . StorageProvider . UpdateWebauthnDeviceDescription ( ctx , userSession . Username , id , bodyJSON . Description ) ; err != nil {
2022-11-19 05:48:47 +00:00
ctx . Error ( err , messageOperationFailed )
return
}
}
2022-12-31 07:27:43 +00:00
// WebauthnDeviceDELETE deletes a specific device for the current user.
func WebauthnDeviceDELETE ( ctx * middlewares . AutheliaCtx ) {
var (
2023-01-25 11:03:30 +00:00
id int
device * model . WebauthnDevice
userSession session . UserSession
err error
2022-12-31 07:27:43 +00:00
)
2022-11-19 05:48:47 +00:00
2022-12-31 07:27:43 +00:00
if id , err = getWebauthnDeviceIDFromContext ( ctx ) ; err != nil {
return
}
if device , err = ctx . Providers . StorageProvider . LoadWebauthnDeviceByID ( ctx , id ) ; err != nil {
ctx . Error ( err , messageOperationFailed )
2022-11-19 05:48:47 +00:00
return
}
2023-01-25 11:03:30 +00:00
if userSession , err = ctx . GetSession ( ) ; err != nil {
ctx . Logger . WithError ( err ) . Error ( "Error occurred retrieving user session" )
ctx . ReplyForbidden ( )
return
}
2022-12-31 07:27:43 +00:00
2023-01-25 11:03:30 +00:00
if device . Username != userSession . Username {
ctx . Error ( fmt . Errorf ( "user '%s' tried to delete device with id '%d' which belongs to '%s" , userSession . Username , device . ID , device . Username ) , messageOperationFailed )
2022-12-31 07:27:43 +00:00
return
}
if err = ctx . Providers . StorageProvider . DeleteWebauthnDevice ( ctx , device . KID . String ( ) ) ; err != nil {
2022-11-19 05:48:47 +00:00
ctx . Error ( err , messageOperationFailed )
return
}
2022-12-31 07:27:43 +00:00
ctx . ReplyOK ( )
2022-11-19 05:48:47 +00:00
}