From fba613f83c7c6902df7469eea01be1e351fa68dd Mon Sep 17 00:00:00 2001 From: mountain Date: Tue, 23 Apr 2024 11:19:08 +0900 Subject: [PATCH] =?UTF-8?q?=EC=84=B8=EC=85=98=20provider,=20consumer=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- session/common.go | 5 +++-- session/impl_mongo.go | 20 ++++++++++++++++++-- session/impl_redis.go | 23 ++++++++++++++++------- session/session_test.go | 2 +- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/session/common.go b/session/common.go index d0ca336..dda2996 100644 --- a/session/common.go +++ b/session/common.go @@ -49,7 +49,7 @@ func MakeAuthrizationFromStringMap(src map[string]string) Authorization { type Provider interface { New(*Authorization) (string, error) - Invalidate(primitive.ObjectID) error + RevokeAll(primitive.ObjectID) error Query(string) (Authorization, error) Touch(string) (bool, error) } @@ -57,7 +57,8 @@ type Provider interface { type Consumer interface { Query(string) (Authorization, error) Touch(string) (Authorization, error) - IsInvalidated(primitive.ObjectID) bool + IsRevoked(primitive.ObjectID) bool + Revoke(string) RegisterOnSessionInvalidated(func(primitive.ObjectID)) } diff --git a/session/impl_mongo.go b/session/impl_mongo.go index 6823a62..1b69e7c 100644 --- a/session/impl_mongo.go +++ b/session/impl_mongo.go @@ -64,7 +64,7 @@ func (p *provider_mongo) New(input *Authorization) (string, error) { return string(storagekey_to_publickey(sk)), err } -func (p *provider_mongo) Invalidate(acc primitive.ObjectID) error { +func (p *provider_mongo) RevokeAll(acc primitive.ObjectID) error { _, err := p.mongoClient.Delete(session_collection_name, bson.M{ "_id": acc, }) @@ -338,7 +338,23 @@ func (c *consumer_mongo) Touch(pk string) (Authorization, error) { return *si.Auth, nil } -func (c *consumer_mongo) IsInvalidated(id primitive.ObjectID) bool { +func (c *consumer_mongo) Revoke(pk string) { + sk := publickey_to_storagekey(publickey(pk)) + _, err := c.mongoClient.Delete(session_collection_name, bson.M{ + "key": sk, + }) + + if err == nil { + for id, v := range c.ids { + if v == sk { + delete(c.ids, id) + break + } + } + } +} + +func (c *consumer_mongo) IsRevoked(id primitive.ObjectID) bool { _, ok := c.ids[id] return !ok } diff --git a/session/impl_redis.go b/session/impl_redis.go index 3881492..45f46c1 100644 --- a/session/impl_redis.go +++ b/session/impl_redis.go @@ -81,7 +81,7 @@ func (p *provider_redis) New(input *Authorization) (string, error) { return string(pk), err } -func (p *provider_redis) Invalidate(account primitive.ObjectID) error { +func (p *provider_redis) RevokeAll(account primitive.ObjectID) error { prefix := account.Hex() sks, err := p.redisClient.Keys(p.ctx, prefix+"*").Result() if err != nil { @@ -130,7 +130,8 @@ func (p *provider_redis) Touch(pk string) (bool, error) { type consumer_redis struct { consumer_common[*sessionRedis] - redisClient *redis.Client + redisClient *redis.Client + deleteChannel string } func newConsumerWithRedis(ctx context.Context, redisUrl string, ttl time.Duration) (Consumer, error) { @@ -139,6 +140,9 @@ func newConsumerWithRedis(ctx context.Context, redisUrl string, ttl time.Duratio return nil, err } + deleteChannel := fmt.Sprintf("%s_%d_d", communication_channel_name_prefix, redisClient.Options().DB) + sub := redisClient.Subscribe(ctx, deleteChannel) + consumer := &consumer_redis{ consumer_common: consumer_common[*sessionRedis]{ ttl: ttl, @@ -146,12 +150,10 @@ func newConsumerWithRedis(ctx context.Context, redisUrl string, ttl time.Duratio stages: [2]*cache_stage[*sessionRedis]{make_cache_stage[*sessionRedis](), make_cache_stage[*sessionRedis]()}, startTime: time.Now(), }, - redisClient: redisClient, + redisClient: redisClient, + deleteChannel: deleteChannel, } - deleteChannel := fmt.Sprintf("%s_%d_d", communication_channel_name_prefix, redisClient.Options().DB) - sub := redisClient.Subscribe(ctx, deleteChannel) - go func() { stageswitch := time.Now().Add(ttl) tickTimer := time.After(ttl) @@ -317,7 +319,14 @@ func (c *consumer_redis) Touch(pk string) (Authorization, error) { return Authorization{}, nil } -func (c *consumer_redis) IsInvalidated(accid primitive.ObjectID) bool { +func (c *consumer_redis) Revoke(pk string) { + sk := publickey_to_storagekey(publickey(pk)) + + c.redisClient.Del(c.ctx, string(sk)) + c.redisClient.Publish(c.ctx, c.deleteChannel, string(sk)).Result() +} + +func (c *consumer_redis) IsRevoked(accid primitive.ObjectID) bool { sk := make_storagekey(accid) c.lock.Lock() diff --git a/session/session_test.go b/session/session_test.go index 3cc6867..c8cf7ec 100644 --- a/session/session_test.go +++ b/session/session_test.go @@ -75,7 +75,7 @@ func TestExpTable(t *testing.T) { time.Sleep(2 * time.Second) time.Sleep(2 * time.Second) - pv.Invalidate(au1.Account) + pv.RevokeAll(au1.Account) cs.Touch(sk1) time.Sleep(2 * time.Second)