aboutsummaryrefslogtreecommitdiff
path: root/internal/db
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--internal/db/redis/auth.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/internal/db/redis/auth.go b/internal/db/redis/auth.go
new file mode 100644
index 0000000..0c5246c
--- /dev/null
+++ b/internal/db/redis/auth.go
@@ -0,0 +1,108 @@
+package redis
+
+import (
+ "log"
+
+ "github.com/gomodule/redigo/redis"
+ "golang.org/x/oauth2"
+
+ "git.ofmax.li/iserv/internal/auth"
+)
+
+var (
+ createAuthLua = redis.NewScript(2, `
+ if redis.call("SISMEMBER","invites",KEYS[1]) == 1 then
+ return redis.call("HMSET",KEYS[2],unpack(ARGV))
+ end
+ return nil
+ `)
+)
+
+// AuthRepo supporting auth
+type AuthRepo struct {
+ db *redis.Pool
+}
+
+// NewRedisAuthRepo redis.Pool
+// creates auth repo around redis pool
+func NewRedisAuthRepo(conn *redis.Pool) *AuthRepo {
+ return &AuthRepo{
+ conn,
+ }
+}
+
+// IsAuthorized is member of invites
+func (db *AuthRepo) IsAuthorized(gp *auth.GoogleAuthProfile) (bool, error) {
+ conn := db.db.Get()
+ defer conn.Close()
+ authProfileKey := "auth:goog:" + gp.Email
+ reply, err := redis.Bool(conn.Do("SISMEMBER", "invites", authProfileKey))
+ if err != nil {
+ return reply, err
+ }
+ return reply, err
+}
+
+// LookUpAuthProfileID get internal profileid
+func (db *AuthRepo) LookUpAuthProfileID(gp *auth.GoogleAuthProfile) (string, error) {
+ conn := db.db.Get()
+ var id string
+ defer conn.Close()
+ authProfileKey := "auth:goog:" + gp.ProfileID
+ reply, err := redis.Values(conn.Do("HMGET", authProfileKey, "id"))
+ if err == redis.ErrNil {
+ // no profile
+ return "", nil
+ } else if err != nil {
+ // some other error
+ return "", err
+ }
+ if _, err := redis.Scan(reply, &id); err != nil {
+ return "", err
+ }
+ return id, nil
+}
+
+// SaveAuthProfile save profile, validate against invites
+func (db *AuthRepo) SaveAuthProfile(ap *auth.Profile) error {
+ // TODO this will over-write refresh tokens
+ conn := db.db.Get()
+ defer conn.Close()
+ authProfileKey := "auth:goog:" + ap.ID
+ prof := redis.Args{}.Add(ap.Email).Add(authProfileKey).AddFlat(ap)
+ res, err := createAuthLua.Do(conn, prof...)
+ log.Printf("auth save response %+v", res)
+ conn.Flush()
+ return err
+}
+
+func (db *AuthRepo) getAuthProfile(id string) (*auth.Profile, error) {
+ conn := db.db.Get()
+ defer conn.Close()
+ authProfileKey := "auth:goog:" + id
+ authProfile := auth.Profile{}
+ res, err := redis.Values(conn.Do("HGETALL", authProfileKey))
+ if err != nil {
+ log.Fatal(err)
+ }
+ log.Printf("getAuthProfile: %+v", res)
+ redis.ScanStruct(res, &authProfile)
+ return &authProfile, err
+}
+
+// GetProfileToken token for profile
+func (db *AuthRepo) GetProfileToken(id string) (*oauth2.Token, error) {
+ profile, err := db.getAuthProfile(id)
+ if err != nil {
+ return nil, err
+ }
+ tkn, err := profile.Token()
+ if err != nil {
+ return nil, err
+ }
+ refreshedToken, err := oauth2.ReuseTokenSource(tkn, profile).Token()
+ if err != nil {
+ return nil, err
+ }
+ return refreshedToken, nil
+}