115 lines
2.5 KiB
Go
115 lines
2.5 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"errors"
|
|
"math/rand"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"repositories.action2quare.com/ayo/gocommon"
|
|
)
|
|
|
|
const (
|
|
communication_channel_name_prefix = "_sess_comm_chan_name"
|
|
session_collection_name = gocommon.CollectionName("session")
|
|
)
|
|
|
|
type Authorization struct {
|
|
Account primitive.ObjectID `bson:"a" json:"a"`
|
|
|
|
// by authorization provider
|
|
Platform string `bson:"p" json:"p"`
|
|
Uid string `bson:"u" json:"u"`
|
|
Email string `bson:"em" json:"em"`
|
|
}
|
|
|
|
type Provider interface {
|
|
New(*Authorization) (string, error)
|
|
Delete(primitive.ObjectID) error
|
|
Query(string) (*Authorization, error)
|
|
}
|
|
|
|
type Consumer interface {
|
|
Query(string) (*Authorization, error)
|
|
Touch(string) (*Authorization, error)
|
|
}
|
|
|
|
type storagekey string
|
|
type publickey string
|
|
|
|
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
func make_storagekey(acc primitive.ObjectID) storagekey {
|
|
bs := [4]byte{}
|
|
binary.LittleEndian.PutUint32(bs[:], r.Uint32())
|
|
|
|
return storagekey(acc.Hex() + hex.EncodeToString(bs[2:]))
|
|
}
|
|
|
|
func storagekey_to_publickey(sk storagekey) publickey {
|
|
bs, _ := hex.DecodeString(string(sk))
|
|
|
|
acc := bs[:12]
|
|
cs := bs[12:]
|
|
|
|
encoded := [14]byte{}
|
|
for i, v := range acc[:] {
|
|
encoded[i] = (v ^ cs[0]) ^ cs[1]
|
|
}
|
|
encoded[12] = cs[0]
|
|
encoded[13] = cs[1]
|
|
|
|
return publickey(hex.EncodeToString(encoded[:]))
|
|
}
|
|
|
|
func publickey_to_storagekey(pk publickey) storagekey {
|
|
bs, _ := hex.DecodeString(string(pk))
|
|
|
|
acc := bs[:12]
|
|
cs := bs[12:]
|
|
|
|
decoded := [14]byte{}
|
|
for i, v := range acc[:] {
|
|
decoded[i] = (v ^ cs[1]) ^ cs[0]
|
|
}
|
|
decoded[12] = cs[0]
|
|
decoded[13] = cs[1]
|
|
|
|
return storagekey(hex.EncodeToString(decoded[:]))
|
|
}
|
|
|
|
var errInvalidScheme = errors.New("storageAddr is not valid scheme")
|
|
|
|
func NewConsumer(ctx context.Context, storageAddr string, ttl time.Duration) (Consumer, error) {
|
|
if strings.HasPrefix(storageAddr, "mongodb") {
|
|
return newConsumerWithMongo(ctx, storageAddr, ttl)
|
|
}
|
|
|
|
if strings.HasPrefix(storageAddr, "redis") {
|
|
return newConsumerWithRedis(ctx, storageAddr, ttl)
|
|
}
|
|
|
|
return nil, errInvalidScheme
|
|
}
|
|
|
|
func NewProvider(ctx context.Context, storageAddr string, ttl time.Duration) (Provider, error) {
|
|
if strings.HasPrefix(storageAddr, "mongodb") {
|
|
return newProviderWithMongo(ctx, storageAddr, ttl)
|
|
}
|
|
|
|
if strings.HasPrefix(storageAddr, "redis") {
|
|
return newProviderWithRedis(ctx, storageAddr, ttl)
|
|
}
|
|
|
|
return nil, errInvalidScheme
|
|
}
|
|
|
|
type SessionConfig struct {
|
|
SessionTTL int64 `json:"session_ttl"`
|
|
SessionStorage string `json:"session_storage"`
|
|
}
|