From 689a57ec4a444f8233fe2e5ec7ceb0903218218d Mon Sep 17 00:00:00 2001 From: Max Resnick Date: Fri, 14 Aug 2020 23:13:41 -0700 Subject: feat: working login gauth --- internal/db/redis/auth.go | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 internal/db/redis/auth.go (limited to 'internal/db/redis') 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 +} -- cgit v1.2.3