122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
openapi_types "github.com/oapi-codegen/runtime/types"
|
|
|
|
"kereru.forms/internal/auth"
|
|
)
|
|
|
|
func (s *Server) GetAuthConfig(ctx context.Context, _ GetAuthConfigRequestObject) (GetAuthConfigResponseObject, error) {
|
|
_, span := s.tracer.Start(ctx, "GetAuthConfig")
|
|
defer span.End()
|
|
|
|
if s.auth == nil {
|
|
return GetAuthConfig200JSONResponse(AuthConfig{
|
|
Mode: AuthConfigMode("password"),
|
|
}), nil
|
|
}
|
|
|
|
cfg := s.auth.PublicConfig()
|
|
out := AuthConfig{
|
|
Mode: AuthConfigMode(cfg.Mode),
|
|
RequireSubmissionAuth: cfg.RequireSubmissionAuth,
|
|
}
|
|
if cfg.OIDC != nil {
|
|
out.Oidc = &OIDCClientConfig{
|
|
IssuerUrl: cfg.OIDC.IssuerURL,
|
|
AuthorizationEndpoint: cfg.OIDC.AuthorizationEndpoint,
|
|
TokenEndpoint: cfg.OIDC.TokenEndpoint,
|
|
ClientId: cfg.OIDC.ClientID,
|
|
Scopes: cfg.OIDC.Scopes,
|
|
}
|
|
}
|
|
return GetAuthConfig200JSONResponse(out), nil
|
|
}
|
|
|
|
func (s *Server) Login(ctx context.Context, request LoginRequestObject) (LoginResponseObject, error) {
|
|
_, span := s.tracer.Start(ctx, "Login")
|
|
defer span.End()
|
|
|
|
if s.auth == nil {
|
|
return Login400JSONResponse{ErrorJSONResponse: errJSON("authentication is not configured", "auth_not_configured")}, nil
|
|
}
|
|
if request.Body == nil {
|
|
return Login400JSONResponse{ErrorJSONResponse: errJSON("password is required", "invalid_request")}, nil
|
|
}
|
|
|
|
token, user, err := s.auth.Login(request.Body.Password)
|
|
switch {
|
|
case errors.Is(err, auth.ErrLocalLoginDisabled):
|
|
return Login400JSONResponse{ErrorJSONResponse: errJSON("local password login is disabled", "local_login_disabled")}, nil
|
|
case errors.Is(err, auth.ErrInvalidCredentials):
|
|
return Login401JSONResponse(Error{
|
|
Error: "invalid credentials",
|
|
Code: stringPtr("invalid_credentials"),
|
|
}), nil
|
|
case err != nil:
|
|
s.logger.Error().Err(err).Msg("local login")
|
|
return Login400JSONResponse{ErrorJSONResponse: errJSON("could not sign in", "internal_error")}, nil
|
|
default:
|
|
return Login200JSONResponse(LoginResponse{
|
|
Token: token,
|
|
User: toAPIAuthUser(user),
|
|
}), nil
|
|
}
|
|
}
|
|
|
|
func (s *Server) GetCurrentUser(ctx context.Context, _ GetCurrentUserRequestObject) (GetCurrentUserResponseObject, error) {
|
|
_, span := s.tracer.Start(ctx, "GetCurrentUser")
|
|
defer span.End()
|
|
|
|
ginCtx, ok := ctx.(*gin.Context)
|
|
if !ok {
|
|
return GetCurrentUser401JSONResponse{ErrorJSONResponse: errJSON("authentication required", "unauthenticated")}, nil
|
|
}
|
|
user, ok := CurrentUser(ginCtx)
|
|
if !ok {
|
|
return GetCurrentUser401JSONResponse{ErrorJSONResponse: errJSON("authentication required", "unauthenticated")}, nil
|
|
}
|
|
return GetCurrentUser200JSONResponse(AuthMeResponse{
|
|
Authenticated: true,
|
|
User: authUserPtr(toAPIAuthUser(user)),
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) Logout(context.Context, LogoutRequestObject) (LogoutResponseObject, error) {
|
|
return Logout204Response{}, nil
|
|
}
|
|
|
|
func toAPIAuthUser(user auth.User) AuthUser {
|
|
roles := user.Roles
|
|
if roles == nil {
|
|
roles = []string{}
|
|
}
|
|
out := AuthUser{
|
|
Id: user.ID,
|
|
Roles: roles,
|
|
CanAdmin: user.CanAdmin,
|
|
CanView: user.CanView,
|
|
}
|
|
if user.Name != "" {
|
|
name := user.Name
|
|
out.Name = &name
|
|
}
|
|
if user.Email != "" {
|
|
email := openapi_types.Email(user.Email)
|
|
out.Email = &email
|
|
}
|
|
return out
|
|
}
|
|
|
|
func authUserPtr(user AuthUser) *AuthUser {
|
|
return &user
|
|
}
|
|
|
|
func stringPtr(value string) *string {
|
|
return &value
|
|
}
|