/
doc.go
115 lines (94 loc) · 3.24 KB
/
doc.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
// Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package mgostore
import (
"time"
"github.com/juju/loggo"
"gopkg.in/macaroon-bakery.v2/bakery"
"gopkg.in/mgo.v2/bson"
"github.com/CanonicalLtd/blues-identity/store"
)
var logger = loggo.GetLogger("identity.store.mgostore")
// fieldNames provides the name used in the mongo documents for each
// field.
var fieldNames = []string{
store.ProviderID: "providerid",
store.Username: "username",
store.Name: "name",
store.Email: "email",
store.Groups: "groups",
store.PublicKeys: "publickeys",
store.LastLogin: "lastlogin",
store.LastDischarge: "lastdischarge",
store.ProviderInfo: "providerinfo",
store.ExtraInfo: "extrainfo",
}
// identityDocument holds the in-database representation of a user in the identities
// Mongo collection.
type identityDocument struct {
// ID is the internal mongodb id for the identity.
ID bson.ObjectId `bson:"_id"`
// ProviderID holds the identity provider specific id for the user.
ProviderID string
// Username holds the unique name for the user of the system, which is
// associated to the URL accessed through jaas.io/u/username.
Username string
// Email holds the email address of the user.
Email string
// Name holds the display name of the user.
Name string
// Groups holds a list of group names to which the user belongs.
Groups []string
// PublicKeys contains a list of public keys associated with this account.
PublicKeys_ [][]byte `bson:"publickeys"`
// LastLoginTime holds the time of the last login for this identity.
LastLogin time.Time
// LastDischargeTime holds the time of the last discharge for this identity.
LastDischarge time.Time
// ProviderInfo holds additional information about the user that
// is provider specific.
ProviderInfo map[string][]string
// ExtraInfo holds additional information about the user that is
// required by other parts of the system.
ExtraInfo map[string][]string
}
// PublicKeys converts the stored public keys into the format used by the
// bakery.
func (d identityDocument) PublicKeys() []bakery.PublicKey {
pks := make([]bakery.PublicKey, len(d.PublicKeys_))
i := 0
for _, data := range d.PublicKeys_ {
// Filter out any keys that cannot be unmarshaled; there
// shouldn't be any anyway.
if err := pks[i].UnmarshalBinary(data); err != nil {
logger.Warningf("cannot unmarshal public key: %s", err)
continue
}
i++
}
return pks[:i]
}
type updateDocument struct {
Set bson.D `bson:"$set,omitempty"`
Unset bson.D `bson:"$unset,omitempty"`
AddToSet bson.D `bson:"$addToSet,omitempty"`
PullAll bson.D `bson:"$pullAll,omitempty"`
}
func (d *updateDocument) addUpdate(op store.Operation, name string, v interface{}) {
switch op {
case store.NoUpdate:
case store.Set:
d.Set = append(d.Set, bson.DocElem{name, v})
case store.Clear:
d.Unset = append(d.Unset, bson.DocElem{name, ""})
case store.Push:
d.AddToSet = append(d.AddToSet, bson.DocElem{name, bson.D{{"$each", v}}})
case store.Pull:
d.PullAll = append(d.PullAll, bson.DocElem{name, v})
default:
panic("invalid update operation")
}
}
func (d *updateDocument) IsZero() bool {
return len(d.Set)+len(d.Unset)+len(d.AddToSet)+len(d.PullAll) == 0
}