diff options
Diffstat (limited to '')
| -rw-r--r-- | internal/auth/service.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/internal/auth/service.go b/internal/auth/service.go new file mode 100644 index 0000000..9997264 --- /dev/null +++ b/internal/auth/service.go @@ -0,0 +1,97 @@ +package auth + +import ( + "errors" + "log" + "time" + + "golang.org/x/oauth2" + + "github.com/gbrlsnchs/jwt/v3" +) + +var ( + singingSecret = jwt.NewHS512([]byte("the wolf says moo")) + // ErrInvalidToken error for token + ErrInvalidToken = errors.New("Invalid token provided") + // ErrInvalidJWT error for jwt + ErrInvalidJWT = errors.New("Invalid JWT") + // ErrUnauthorized error for unauthorized access + ErrUnauthorized = errors.New("Unauthorized") +) + +// Servicer access to auth functionality +type Servicer interface { + LoginOrRegisterSessionID(t *oauth2.Token, gp *GoogleAuthProfile) (string, bool, error) + GenerateStateToken() (string, error) + ValidateStateToken(token string, sessionToken string) (bool, error) +} + +// Service a container for auth deps +type Service struct { + repo Repo +} + +// NewService create auth service +func NewService(repo Repo) *Service { + return &Service{ + repo, + } +} + +// GenerateStateToken create a random token for oauth exchange +func (a *Service) GenerateStateToken() (string, error) { + now := time.Now() + pl := jwt.Payload{ + Issuer: "iserv-state", + Subject: "state param", + IssuedAt: jwt.NumericDate(now), + } + tokenBytes, err := jwt.Sign(pl, singingSecret) + if err != nil { + return "", err + } + return string(tokenBytes[:]), err +} + +// ValidateStateToken validate provided token +func (a *Service) ValidateStateToken(token string, sessionToken string) (bool, error) { + if token == sessionToken { + p := jwt.Payload{} + _, err := jwt.Verify([]byte(token), singingSecret, &p) + if err != nil { + return false, ErrInvalidJWT + } + return true, nil + } + return false, ErrInvalidToken +} + +// LoginOrRegisterSessionID create a login +func (a *Service) LoginOrRegisterSessionID(t *oauth2.Token, gp *GoogleAuthProfile) (string, bool, error) { + isAuthorized, err := a.repo.IsAuthorized(gp) + newRegistration := false + if err != nil { + return "", newRegistration, err + } + if isAuthorized != true { + return "", newRegistration, ErrUnauthorized + } + profileID, err := a.repo.LookUpAuthProfileID(gp) + if err != nil { + return "", newRegistration, err + } + if profileID == "" { + // create profile + log.Printf("creating new profile") + profile := NewAuthProfile(t, gp) + profileID = profile.ID + log.Printf("new profile %+v", profile) + err = a.repo.SaveAuthProfile(profile) + if err != nil { + return "", newRegistration, err + } + newRegistration = true + } + return profileID, newRegistration, nil +} |