diff options
| author | Max Resnick <max@ofmax.li> | 2020-11-08 11:45:16 -0800 |
|---|---|---|
| committer | Max Resnick <max@ofmax.li> | 2021-01-01 10:50:14 -0800 |
| commit | a397341ad471cc761f7fb930d77e53cf7eb40a2a (patch) | |
| tree | 76fb8318269569687fdd30467dc61ecba3499d09 /internal/db/redis | |
| parent | 689a57ec4a444f8233fe2e5ec7ceb0903218218d (diff) | |
| download | iserv-a397341ad471cc761f7fb930d77e53cf7eb40a2a.tar.gz | |
adds casbin and accounts
Diffstat (limited to 'internal/db/redis')
| -rw-r--r-- | internal/db/redis/acct.go | 44 | ||||
| -rw-r--r-- | internal/db/redis/auth.go | 51 | ||||
| -rw-r--r-- | internal/db/redis/image.go | 2 |
3 files changed, 79 insertions, 18 deletions
diff --git a/internal/db/redis/acct.go b/internal/db/redis/acct.go new file mode 100644 index 0000000..72df741 --- /dev/null +++ b/internal/db/redis/acct.go @@ -0,0 +1,44 @@ +package redis + +import ( + "fmt" + + "github.com/gomodule/redigo/redis" + "github.com/pkg/errors" + + "git.ofmax.li/iserv/internal/acct" +) + +// AcctRepo account +type AcctRepo struct { + db *redis.Pool +} + +var ( + acctProfileKey string = "acct:email:%s" +) + +// NewAcctRepo account repo +func NewAcctRepo(conn *redis.Pool) *AcctRepo { + return &AcctRepo{ + conn, + } +} + +// UpdateAcctProfile write profile to redis +func (db *AcctRepo) UpdateAcctProfile(p acct.Profile) error { + conn := db.db.Get() + defer conn.Close() + profileID, profileKeyValues := p.ProfileKeyValues() + acctProfileKey := fmt.Sprintf(acctProfileKey, profileID) + profileArgs := redis.Args{}.Add(acctProfileKey).AddFlat(profileKeyValues) + res, err := redis.String(conn.Do("HMSET", profileArgs...)) + if err != nil { + fmt.Print(err) + return err + } + if res != "OK" { + return errors.Errorf("%s acct was not saved", acctProfileKey) + } + return nil +} diff --git a/internal/db/redis/auth.go b/internal/db/redis/auth.go index 0c5246c..1f99fac 100644 --- a/internal/db/redis/auth.go +++ b/internal/db/redis/auth.go @@ -1,12 +1,14 @@ package redis import ( + "fmt" "log" "github.com/gomodule/redigo/redis" "golang.org/x/oauth2" "git.ofmax.li/iserv/internal/auth" + "git.ofmax.li/iserv/internal/goog" ) var ( @@ -16,6 +18,14 @@ var ( end return nil `) + checkActiveAuthLua = redis.NewScript(1, ` + local email = redis.call("HMGET",KEYS[1],"email") + if email == nil then + return false + end + return redis.call("SISMEMBER",email) + `) + authProfileKey = func(id string) string { return fmt.Sprintf("auth:%s") } ) // AuthRepo supporting auth @@ -32,11 +42,11 @@ func NewRedisAuthRepo(conn *redis.Pool) *AuthRepo { } // IsAuthorized is member of invites -func (db *AuthRepo) IsAuthorized(gp *auth.GoogleAuthProfile) (bool, error) { +func (db *AuthRepo) IsAuthorized(gp *goog.GoogleProfile) (bool, error) { conn := db.db.Get() defer conn.Close() - authProfileKey := "auth:goog:" + gp.Email - reply, err := redis.Bool(conn.Do("SISMEMBER", "invites", authProfileKey)) + inviteKey := "goog:" + gp.Email + reply, err := redis.Bool(conn.Do("SISMEMBER", "invites", inviteKey)) if err != nil { return reply, err } @@ -44,16 +54,12 @@ func (db *AuthRepo) IsAuthorized(gp *auth.GoogleAuthProfile) (bool, error) { } // LookUpAuthProfileID get internal profileid -func (db *AuthRepo) LookUpAuthProfileID(gp *auth.GoogleAuthProfile) (string, error) { +func (db *AuthRepo) LookUpAuthProfileID(gp *goog.GoogleProfile) (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 { + reply, err := redis.Values(conn.Do("HMGET", authProfileKey(gp.ProfileID), "id")) + if err != nil { // some other error return "", err } @@ -64,24 +70,35 @@ func (db *AuthRepo) LookUpAuthProfileID(gp *auth.GoogleAuthProfile) (string, err } // SaveAuthProfile save profile, validate against invites -func (db *AuthRepo) SaveAuthProfile(ap *auth.Profile) error { +func (db *AuthRepo) SaveAuthProfile(email string, 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) + prof := redis.Args{}.Add(email).Add(ap.ID).AddFlat(ap) + _, err := createAuthLua.Do(conn, prof...) conn.Flush() return err } +// CheckProfileID return true if the profile exists and authorized +func (db *AuthRepo) CheckProfileID(id string) (bool, error) { + conn := db.db.Get() + defer conn.Close() + res, err := redis.Int(checkActiveAuthLua.Do(conn, authProfileKey(id))) + if err == redis.ErrNil { + return false, nil + } else if err != nil { + return false, err + } + // there could be profile created but later revoked authorization + return res == 1, nil +} + 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)) + res, err := redis.Values(conn.Do("HGETALL", authProfileKey(id))) if err != nil { log.Fatal(err) } diff --git a/internal/db/redis/image.go b/internal/db/redis/image.go index f216531..3622728 100644 --- a/internal/db/redis/image.go +++ b/internal/db/redis/image.go @@ -48,7 +48,7 @@ func (r *ImageRepo) GetFile(fileUrl string) (*image.PostMeta, error) { key := fileKey(fileUrl, V1FilePathFmt) res, err := redis.Values(conn.Do("HGETALL", key)) if err != nil { - return &image.PostMeta{}, ErrNotFound + return &image.PostMeta{}, err } err = redis.ScanStruct(res, imageMeta) if imageMeta.FilePath == "" { |