diff --git a/internal/auth/agent/user.go b/internal/auth/agent/user.go index 94a11b9..5e146fe 100644 --- a/internal/auth/agent/user.go +++ b/internal/auth/agent/user.go @@ -1,6 +1,7 @@ package agent import ( + "encoding/json" "fmt" "forge.cadoles.com/Cadoles/emissary/internal/auth" @@ -29,4 +30,18 @@ func (u *User) Agent() *datastore.Agent { return u.agent } +func (u *User) MarshalJSON() ([]byte, error) { + type user struct { + Subject string `json:"subject"` + Tenant string `json:"tenant"` + } + + jsonUser := user{ + Subject: u.Subject(), + Tenant: string(u.Tenant()), + } + + return json.Marshal(jsonUser) +} + var _ auth.User = &User{} diff --git a/internal/auth/middleware.go b/internal/auth/middleware.go index c180f8f..cdb2980 100644 --- a/internal/auth/middleware.go +++ b/internal/auth/middleware.go @@ -64,16 +64,16 @@ func Middleware(authenticators ...Authenticator) func(http.Handler) http.Handler } if user == nil { - isUnauthorized, isUnauthenticated, isUnknown := checkErrors(errs) + hasUnauthorized, hasUnauthenticated, hasUnknown := checkErrors(errs) switch { - case isUnauthorized && !isUnknown: + case hasUnauthorized && !hasUnknown: api.ErrorResponse(w, http.StatusForbidden, api.ErrCodeForbidden, nil) return - case isUnauthenticated && !isUnknown: - api.ErrorResponse(w, http.StatusForbidden, api.ErrCodeForbidden, nil) + case hasUnauthenticated && !hasUnknown: + api.ErrorResponse(w, http.StatusUnauthorized, api.ErrCodeUnauthorized, nil) return - case isUnknown: + case hasUnknown: api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil) return default: @@ -101,10 +101,8 @@ func checkErrors(errs []error) (isUnauthorized bool, isUnauthenticated bool, isU switch { case errors.Is(e, ErrUnauthorized): isUnauthorized = true - continue case errors.Is(e, ErrUnauthenticated): isUnauthenticated = true - continue default: isUnknown = true } diff --git a/internal/auth/user/user.go b/internal/auth/user/user.go index b2e9d49..df12f39 100644 --- a/internal/auth/user/user.go +++ b/internal/auth/user/user.go @@ -1,6 +1,8 @@ package user import ( + "encoding/json" + "forge.cadoles.com/Cadoles/emissary/internal/auth" "forge.cadoles.com/Cadoles/emissary/internal/datastore" ) @@ -39,4 +41,20 @@ func (u *User) Role() Role { return u.role } +func (u *User) MarshalJSON() ([]byte, error) { + type user struct { + Subject string `json:"subject"` + Tenant string `json:"tenant"` + Role string `json:"role"` + } + + jsonUser := user{ + Subject: u.Subject(), + Tenant: string(u.Tenant()), + Role: string(u.Role()), + } + + return json.Marshal(jsonUser) +} + var _ auth.User = &User{} diff --git a/internal/server/api/get_session.go b/internal/server/api/get_session.go new file mode 100644 index 0000000..5ddcfd1 --- /dev/null +++ b/internal/server/api/get_session.go @@ -0,0 +1,35 @@ +package api + +import ( + "net/http" + + "forge.cadoles.com/Cadoles/emissary/internal/auth" + "forge.cadoles.com/Cadoles/emissary/internal/datastore" + "github.com/pkg/errors" + "gitlab.com/wpetit/goweb/api" + "gitlab.com/wpetit/goweb/logger" +) + +func (m *Mount) getSession(w http.ResponseWriter, r *http.Request) { + user, ok := assertRequestUser(w, r) + if !ok { + return + } + + ctx := r.Context() + + tenant, err := m.tenantRepo.Get(ctx, user.Tenant()) + if err != nil && !errors.Is(err, datastore.ErrNotFound) { + err = errors.WithStack(err) + logger.Error(ctx, "could not retrieve user tenant", logger.CapturedE(err)) + api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil) + } + + api.DataResponse(w, http.StatusOK, struct { + User auth.User `json:"user"` + Tenant *datastore.Tenant `json:"tenant"` + }{ + User: user, + Tenant: tenant, + }) +} diff --git a/internal/server/api/mount.go b/internal/server/api/mount.go index 0bfc4eb..ff1aa14 100644 --- a/internal/server/api/mount.go +++ b/internal/server/api/mount.go @@ -23,6 +23,8 @@ func (m *Mount) Mount(r chi.Router) { r.Group(func(r chi.Router) { r.Use(auth.Middleware(m.authenticators...)) + r.Get("/session", m.getSession) + r.Route("/agents", func(r chi.Router) { r.With(assertUserWithWriteAccess).Post("/claim", m.claimAgent)