aboutsummaryrefslogtreecommitdiff
path: root/internal/auth/service.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--internal/auth/service.go97
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
+}