56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/auth"
|
|
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform"
|
|
"github.com/aarondl/opt/omit"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func Impersonation(r *router) *impersonationR {
|
|
return &impersonationR{
|
|
router: r,
|
|
}
|
|
}
|
|
|
|
type impersonationR struct {
|
|
router *router
|
|
}
|
|
type impersonation struct {
|
|
UserID omit.Val[int] `json:"id"`
|
|
}
|
|
|
|
func (res *impersonationR) Create(ctx context.Context, r *http.Request, u platform.User, i impersonation) (*impersonation, *nhttp.ErrorWithStatus) {
|
|
if i.UserID.IsUnset() {
|
|
return nil, nhttp.NewBadRequest("you must provide an 'id'")
|
|
}
|
|
target_id := i.UserID.MustGet()
|
|
l, err := platform.ImpersonationCreate(ctx, u, target_id)
|
|
if err != nil {
|
|
return nil, nhttp.NewError("create impersonation: %w", err)
|
|
}
|
|
auth.ImpersonateUser(ctx, target_id)
|
|
log.Info().Int("user.id", u.ID).Str("username", u.Username).Int("target.id", target_id).Int32("log.id", l.ID).Msg("Impersonation begins")
|
|
return &impersonation{
|
|
UserID: i.UserID,
|
|
}, nil
|
|
}
|
|
func (res *impersonationR) Delete(ctx context.Context, r *http.Request, u platform.User) *nhttp.ErrorWithStatus {
|
|
if auth.ImpersonatedUser == nil {
|
|
return nhttp.NewBadRequest("not impersonating")
|
|
}
|
|
real_user_id := auth.ImpersonatorID(ctx)
|
|
if real_user_id == nil {
|
|
return nhttp.NewError("No impersonator ID")
|
|
}
|
|
err := platform.ImpersonationEnd(ctx, u, *real_user_id)
|
|
if err != nil {
|
|
return nhttp.NewError("end impersonation: %w", err)
|
|
}
|
|
auth.ImpersonateEnd(ctx)
|
|
return nil
|
|
}
|