Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • MKCLOS/coredevelopmentplatform/corepkgv2
Show changes
Commits on Source (2)
Showing with 109 additions and 0 deletions
package otpmanagermdl
import (
"errors"
"time"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/cachemdl"
)
// Entry is a data to be stored against a key.
type Entry struct {
Data gjson.Result `json:"data,omitempty"`
Expiration int64 `json:"expiration,omitempty"`
ExpiredAT int64 `json:"expiredAt,omitempty"`
}
const (
// keys for the entry object
KEY_DATA = "data"
KEY_EXPIREDAT = "expiredAt"
KEY_EXPIRATION = "expiration"
)
var store cachemdl.Cacher
var ErrOtpNotFound = errors.New("OTP_NOT_FOUND")
var ErrInvalidDataType = errors.New("INVALID_DATA_Type")
// Init initializes otp manager with provided cache. Subsequent calls will not have any effect after first initialization.
func Init(cache cachemdl.Cacher) {
if store != nil {
return
}
store = cache
}
// NewEntry prepares the object required to store data in session.
//
// The `exp` field interprets time in seconds. Ex. For 5 seconds, set `5`
func NewOTPEntry(val gjson.Result, exp int64) Entry {
duration := time.Duration(exp) * time.Second
deadLine := time.Now().Add(duration).Unix()
return Entry{
Data: val,
Expiration: exp,
ExpiredAT: deadLine,
}
}
// NewRedisEntry prepares the entry for redis cache. This is required because redis accepts a byte array.
func NewRedisEntry(entry Entry) string {
var data string
data, _ = sjson.Set(data, KEY_DATA, entry.Data.Value())
data, _ = sjson.Set(data, KEY_EXPIRATION, entry.Expiration)
data, _ = sjson.Set(data, KEY_EXPIREDAT, entry.ExpiredAT)
return data
}
// Store adds/ updates the entry against the provided key.
func Store(key string, entry Entry) {
duration := time.Duration(entry.Expiration) * time.Second
// if otp manager uses redis cache, the data field (gjson.Result) is saved as is.
// This adds irrelevant fields in redis cache and we get them on retrieve operation.
// The following operation needs to be performed so that the data is marshaled correctly. Redis only accepts []byte{}.
if store.Type() == cachemdl.TypeRedisCache {
store.SetWithExpiration(key, NewRedisEntry(entry), duration)
return
}
store.SetWithExpiration(key, entry, duration)
}
// // Delete removes the otp entry. If the key is not present, error `ErrOtpNotFound` will be thrown. Caller can ignore error if this is acceptable.
func DeleteOTP(key string) error {
_, ok := store.Get(key)
if !ok {
return ErrOtpNotFound
}
store.Delete(key)
return nil
}
func GetOTP(key string) (Entry, bool) {
data, ok := store.Get(key)
if !ok {
return Entry{}, false
}
switch v := data.(type) {
case string: // for result from redis cache
res := gjson.Parse(v)
return Entry{
Data: res.Get(KEY_DATA),
Expiration: res.Get(KEY_EXPIRATION).Int(),
ExpiredAT: res.Get(KEY_EXPIREDAT).Int(),
}, true
case Entry: // for result from fastcache
return v, true
default:
return Entry{}, false
}
}