-
Notifications
You must be signed in to change notification settings - Fork 44
/
keeper_app_links.go
124 lines (100 loc) · 4.37 KB
/
keeper_app_links.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
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/desmos-labs/desmos/x/profiles/types"
)
// Connections are stored using three keys:
// 1. UserApplicationLinkKey (user + application + username) -> types.ApplicationLink
// 2. ApplicationLinkClientIDKey (client_id) -> UserApplicationLinkKey
//
// This allows to get connections by client id as well as by app + username quickly
// SaveApplicationLink stores the given connection replacing any existing one for the same user and application
func (k Keeper) SaveApplicationLink(ctx sdk.Context, link types.ApplicationLink) error {
if !k.HasProfile(ctx, link.User) {
return sdkerrors.Wrapf(types.ErrProfileNotFound, "a profile is required to link an application")
}
// Get the keys
userApplicationLinkKey := types.UserApplicationLinkKey(link.User, link.Data.Application, link.Data.Username)
applicationLinkClientIDKey := types.ApplicationLinkClientIDKey(link.OracleRequest.ClientID)
// Store the data
store := ctx.KVStore(k.storeKey)
store.Set(userApplicationLinkKey, types.MustMarshalApplicationLink(k.cdc, link))
store.Set(applicationLinkClientIDKey, userApplicationLinkKey)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypesApplicationLinkSaved,
sdk.NewAttribute(types.AttributeKeyUser, link.User),
sdk.NewAttribute(types.AttributeKeyApplicationName, link.Data.Application),
sdk.NewAttribute(types.AttributeKeyApplicationUsername, link.Data.Username),
),
)
return nil
}
// GetApplicationLink returns the link for the given application and username.
// If the link is not found returns an error instead.
func (k Keeper) GetApplicationLink(ctx sdk.Context, user, application, username string) (types.ApplicationLink, bool, error) {
store := ctx.KVStore(k.storeKey)
// Check to see if the key exists
userApplicationLinkKey := types.UserApplicationLinkKey(user, application, username)
if !store.Has(userApplicationLinkKey) {
return types.ApplicationLink{}, false, nil
}
var link types.ApplicationLink
err := k.cdc.UnmarshalBinaryBare(store.Get(userApplicationLinkKey), &link)
if err != nil {
return types.ApplicationLink{}, false, err
}
return link, true, nil
}
// GetApplicationLinkByClientID returns the application link and user given a specific client id
func (k Keeper) GetApplicationLinkByClientID(ctx sdk.Context, clientID string) (types.ApplicationLink, error) {
store := ctx.KVStore(k.storeKey)
// Get the client request using the client id
clientIDKey := types.ApplicationLinkClientIDKey(clientID)
if !store.Has(clientIDKey) {
return types.ApplicationLink{},
sdkerrors.Wrapf(sdkerrors.ErrNotFound, "link for client id %s not found", clientID)
}
// Get the link key
applicationLinkKey := store.Get(clientIDKey)
// Read the link
var link types.ApplicationLink
err := k.cdc.UnmarshalBinaryBare(store.Get(applicationLinkKey), &link)
if err != nil {
return types.ApplicationLink{}, sdkerrors.Wrap(err, "error while reading application link")
}
return link, nil
}
// DeleteApplicationLink removes the application link associated to the given user,
// for the given application and username
func (k Keeper) DeleteApplicationLink(ctx sdk.Context, user string, application, username string) error {
// Get the link to obtain the client id
link, found, err := k.GetApplicationLink(ctx, user, application, username)
if err != nil {
return err
}
if !found {
return sdkerrors.Wrap(sdkerrors.ErrNotFound, "application link not found")
}
if link.User != user {
return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "cannot delete the application link of another user")
}
// Delete the data
store := ctx.KVStore(k.storeKey)
store.Delete(types.UserApplicationLinkKey(user, application, username))
store.Delete(types.ApplicationLinkClientIDKey(link.OracleRequest.ClientID))
return nil
}
// DeleteAllUserApplicationLinks delete all the applications links associated with the given user
func (k Keeper) DeleteAllUserApplicationLinks(ctx sdk.Context, user string) {
var links []types.ApplicationLink
k.IterateUserApplicationLinks(ctx, user, func(index int64, link types.ApplicationLink) (stop bool) {
links = append(links, link)
return false
})
store := ctx.KVStore(k.storeKey)
for _, link := range links {
store.Delete(types.UserApplicationLinkKey(link.User, link.Data.Application, link.Data.Username))
}
}