diff options
| author | Max Resnick <max@ofmax.li> | 2020-08-14 23:13:41 -0700 |
|---|---|---|
| committer | Max Resnick <max@ofmax.li> | 2020-11-08 07:57:13 -0800 |
| commit | 689a57ec4a444f8233fe2e5ec7ceb0903218218d (patch) | |
| tree | 1bcfe6786c38b4ae11997d5d97dc3c5fba747b97 /internal/auth/service.go | |
| parent | 77c2e6aca2dc0f851f55e30a0f49c9ee7c2c952e (diff) | |
| download | iserv-master.tar.gz | |
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 +} |