package auth import ( "context" "errors" "github.com/Unkn0wnCat/calapi/internal/ghost" "github.com/Unkn0wnCat/calapi/internal/logger" "github.com/go-chi/chi/middleware" "github.com/spf13/viper" "go.uber.org/zap" ) const ( AuthTypeGhost = "GHOST" AuthTypeNone = "NONE" ) type User struct { ID string Username string Name string } func Authenticate(ctx context.Context, username string, password string) (*User, error) { switch viper.GetString("auth.type") { case AuthTypeGhost: return AuthenticateGhost(ctx, username, password) case AuthTypeNone: logger.Logger.Info("anonymously authenticated", zap.String("requestId", middleware.GetReqID(ctx)), ) return &User{ ID: "ANON-NO-AUTH", Username: "anonymous", Name: "Anonymous User", }, nil default: return nil, errors.New("unknown authentication method") } } func AuthenticateGhost(ctx context.Context, username string, password string) (*User, error) { api := ghost.GhostAPI{ BaseURL: viper.GetString("auth.ghost.base_url"), Jar: nil, } _, err := api.Login(username, password) if err != nil { logger.Logger.Warn("invalid ghost credentials", zap.String("requestId", middleware.GetReqID(ctx)), zap.Error(err), ) return nil, err } ghostUser, err := api.UserSelf() if err != nil { logger.Logger.Error("ghost error", zap.String("requestId", middleware.GetReqID(ctx)), zap.Error(err), ) return nil, err } if len(ghostUser.Users) == 0 { logger.Logger.Error("unexpected empty response from Ghost API", zap.String("requestId", middleware.GetReqID(ctx)), ) return nil, errors.New("unexpected empty response from Ghost API") } logger.Logger.Info("ghost authentication success", zap.String("requestId", middleware.GetReqID(ctx)), zap.String("userId", ghostUser.Users[0].ID), zap.String("username", ghostUser.Users[0].Email), zap.Error(err), ) user := &User{ ID: ghostUser.Users[0].ID, Username: ghostUser.Users[0].Email, Name: ghostUser.Users[0].Name, } return user, nil }