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