github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/app/plugin_key_value_store.go (about) 1 // Copyright (c) 2015-present Xenia, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "crypto/sha256" 8 "encoding/base64" 9 "net/http" 10 11 "github.com/xzl8028/xenia-server/mlog" 12 "github.com/xzl8028/xenia-server/model" 13 ) 14 15 func getKeyHash(key string) string { 16 hash := sha256.New() 17 hash.Write([]byte(key)) 18 return base64.StdEncoding.EncodeToString(hash.Sum(nil)) 19 } 20 21 func (a *App) SetPluginKey(pluginId string, key string, value []byte) *model.AppError { 22 return a.SetPluginKeyWithExpiry(pluginId, key, value, 0) 23 } 24 25 func (a *App) SetPluginKeyWithExpiry(pluginId string, key string, value []byte, expireInSeconds int64) *model.AppError { 26 if expireInSeconds > 0 { 27 expireInSeconds = model.GetMillis() + (expireInSeconds * 1000) 28 } 29 30 kv := &model.PluginKeyValue{ 31 PluginId: pluginId, 32 Key: key, 33 Value: value, 34 ExpireAt: expireInSeconds, 35 } 36 37 if result := <-a.Srv.Store.Plugin().SaveOrUpdate(kv); result.Err != nil { 38 mlog.Error("Failed to set plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 39 return result.Err 40 } 41 42 // Clean up a previous entry using the hashed key, if it exists. 43 if result := <-a.Srv.Store.Plugin().Delete(pluginId, getKeyHash(key)); result.Err != nil { 44 mlog.Error("Failed to clean up previously hashed plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 45 } 46 47 return nil 48 } 49 50 func (a *App) CompareAndSetPluginKey(pluginId string, key string, oldValue, newValue []byte) (bool, *model.AppError) { 51 kv := &model.PluginKeyValue{ 52 PluginId: pluginId, 53 Key: key, 54 Value: newValue, 55 } 56 57 updated, err := a.Srv.Store.Plugin().CompareAndSet(kv, oldValue) 58 if err != nil { 59 mlog.Error("Failed to compare and set plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(err)) 60 return updated, err 61 } 62 63 // Clean up a previous entry using the hashed key, if it exists. 64 if result := <-a.Srv.Store.Plugin().Delete(pluginId, getKeyHash(key)); result.Err != nil { 65 mlog.Error("Failed to clean up previously hashed plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 66 } 67 68 return updated, nil 69 } 70 71 func (a *App) GetPluginKey(pluginId string, key string) ([]byte, *model.AppError) { 72 if result := <-a.Srv.Store.Plugin().Get(pluginId, key); result.Err == nil { 73 return result.Data.(*model.PluginKeyValue).Value, nil 74 } else if result.Err.StatusCode != http.StatusNotFound { 75 mlog.Error("Failed to query plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 76 return nil, result.Err 77 } 78 79 // Lookup using the hashed version of the key for keys written prior to v5.6. 80 if result := <-a.Srv.Store.Plugin().Get(pluginId, getKeyHash(key)); result.Err == nil { 81 return result.Data.(*model.PluginKeyValue).Value, nil 82 } else if result.Err.StatusCode != http.StatusNotFound { 83 mlog.Error("Failed to query plugin key value using hashed key", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 84 return nil, result.Err 85 } 86 87 return nil, nil 88 } 89 90 func (a *App) DeletePluginKey(pluginId string, key string) *model.AppError { 91 if result := <-a.Srv.Store.Plugin().Delete(pluginId, getKeyHash(key)); result.Err != nil { 92 mlog.Error("Failed to delete plugin key value", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 93 return result.Err 94 } 95 96 // Also delete the key without hashing 97 if result := <-a.Srv.Store.Plugin().Delete(pluginId, key); result.Err != nil { 98 mlog.Error("Failed to delete plugin key value using hashed key", mlog.String("plugin_id", pluginId), mlog.String("key", key), mlog.Err(result.Err)) 99 return result.Err 100 } 101 102 return nil 103 } 104 105 func (a *App) DeleteAllKeysForPlugin(pluginId string) *model.AppError { 106 if result := <-a.Srv.Store.Plugin().DeleteAllForPlugin(pluginId); result.Err != nil { 107 mlog.Error("Failed to delete all plugin key values", mlog.String("plugin_id", pluginId), mlog.Err(result.Err)) 108 return result.Err 109 } 110 111 return nil 112 } 113 114 func (a *App) DeleteAllExpiredPluginKeys() *model.AppError { 115 if a.Srv == nil { 116 return nil 117 } 118 119 if result := <-a.Srv.Store.Plugin().DeleteAllExpired(); result.Err != nil { 120 mlog.Error("Failed to delete all expired plugin key values", mlog.Err(result.Err)) 121 return result.Err 122 } 123 124 return nil 125 } 126 127 func (a *App) ListPluginKeys(pluginId string, page, perPage int) ([]string, *model.AppError) { 128 result := <-a.Srv.Store.Plugin().List(pluginId, page*perPage, perPage) 129 130 if result.Err != nil { 131 mlog.Error("Failed to list plugin key values", mlog.Int("page", page), mlog.Int("perPage", perPage), mlog.Err(result.Err)) 132 return nil, result.Err 133 } 134 135 return result.Data.([]string), nil 136 }