nidus-sync/resource/impersonation.go

57 lines
1.6 KiB
Go
Raw Normal View History

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
}