Skip to content

Commit 6a264f0

Browse files
author
Horacio Duran
committed
Made controlleruser and permissions global.
ControllerUser and Permissions collections where being used in an incorrect manner, by user ForModel, I instead changed them to be global and started adding the modelID where required.
1 parent 01e39ac commit 6a264f0

9 files changed

+54
-43
lines changed

state/allcollections.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ func allCollections() collectionSchema {
195195
// This collection is basically a standard SQL intersection table; it
196196
// references the global records of the users allowed access to a
197197
// given operation.
198-
permissionsC: {},
198+
permissionsC: {
199+
global: true,
200+
},
199201

200202
// This collection holds the last time the model user connected
201203
// to the model.

state/controller.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package state
55

66
import (
7+
"fmt"
8+
79
"github.com/juju/errors"
810

911
jujucontroller "github.com/juju/juju/controller"
@@ -17,6 +19,12 @@ const (
1719
controllerGlobalKey = "c"
1820
)
1921

22+
// controllerKey will return the key for a given controller using the
23+
// controller uuid and the controllerGlobalKey.
24+
func controllerKey(controllerUUID string) string {
25+
return fmt.Sprintf("%s#%s", controllerGlobalKey, controllerUUID)
26+
}
27+
2028
// ControllerConfig returns the config values for the controller.
2129
func (st *State) ControllerConfig() (jujucontroller.Config, error) {
2230
settings, err := readSettings(st, controllersC, controllerSettingsGlobalKey)

state/controlleruser.go

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,9 @@ func (st *State) setControllerAccess(access description.Access, userGlobalKey st
2222
if err := description.ValidateControllerAccess(access); err != nil {
2323
return errors.Trace(err)
2424
}
25-
op := updatePermissionOp(controllerGlobalKey, userGlobalKey, access)
26-
controllerSt, err := st.ForModel(st.controllerModelTag)
27-
if err != nil {
28-
return errors.Trace(err)
29-
}
30-
defer controllerSt.Close()
25+
op := updatePermissionOp(controllerKey(st.ControllerUUID()), userGlobalKey, access)
3126

32-
err = controllerSt.runTransaction([]txn.Op{op})
27+
err := st.runTransaction([]txn.Op{op})
3328
if err == txn.ErrAborted {
3429
return errors.NotFoundf("existing permissions")
3530
}
@@ -39,16 +34,11 @@ func (st *State) setControllerAccess(access description.Access, userGlobalKey st
3934
// controllerUser a model userAccessDoc.
4035
func (st *State) controllerUser(user names.UserTag) (userAccessDoc, error) {
4136
controllerUser := userAccessDoc{}
42-
controllerSt, err := st.ForModel(st.controllerModelTag)
43-
if err != nil {
44-
return controllerUser, errors.Trace(err)
45-
}
46-
defer controllerSt.Close()
47-
controllerUsers, closer := controllerSt.getCollection(controllerUsersC)
37+
controllerUsers, closer := st.getCollection(controllerUsersC)
4838
defer closer()
4939

5040
username := strings.ToLower(user.Canonical())
51-
err = controllerUsers.FindId(username).One(&controllerUser)
41+
err := controllerUsers.FindId(username).One(&controllerUser)
5242
if err == mgo.ErrNotFound {
5343
return userAccessDoc{}, errors.NotFoundf("controller user %q", user.Canonical())
5444
}
@@ -69,7 +59,7 @@ func createControllerUserOps(controllerUUID string, user, createdBy names.UserTa
6959
DateCreated: dateCreated,
7060
}
7161
ops := []txn.Op{
72-
createPermissionOp(controllerGlobalKey, userGlobalKey(userAccessID(user)), access),
62+
createPermissionOp(controllerKey(controllerUUID), userGlobalKey(userAccessID(user)), access),
7363
{
7464
C: controllerUsersC,
7565
Id: userAccessID(user),
@@ -83,7 +73,7 @@ func createControllerUserOps(controllerUUID string, user, createdBy names.UserTa
8373
// RemoveControllerUser removes a user from the database.
8474
func (st *State) removeControllerUser(user names.UserTag) error {
8575
ops := []txn.Op{
86-
removePermissionOp(controllerGlobalKey, userGlobalKey(userAccessID(user))),
76+
removePermissionOp(controllerKey(st.ControllerUUID()), userGlobalKey(userAccessID(user))),
8777
{
8878
C: controllerUsersC,
8979
Id: userAccessID(user),

state/model.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ import (
2828
// settings and constraints.
2929
const modelGlobalKey = "e"
3030

31+
// modelKey will create the kei for a given model using the modelGlobalKey.
32+
func modelKey(modelUUID string) string {
33+
return fmt.Sprintf("%s#%s", modelGlobalKey, modelUUID)
34+
}
35+
3136
// MigrationMode specifies where the Model is with respect to migration.
3237
type MigrationMode string
3338

state/modeluser.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (st *State) setModelAccess(access description.Access, userGlobalKey string)
3434
if err := description.ValidateModelAccess(access); err != nil {
3535
return errors.Trace(err)
3636
}
37-
op := updatePermissionOp(modelGlobalKey, userGlobalKey, access)
37+
op := updatePermissionOp(modelKey(st.ModelUUID()), userGlobalKey, access)
3838
err := st.runTransaction([]txn.Op{op})
3939
if err == txn.ErrAborted {
4040
return errors.NotFoundf("existing permissions")
@@ -131,7 +131,7 @@ func createModelUserOps(modelUUID string, user, createdBy names.UserTag, display
131131
DateCreated: dateCreated,
132132
}
133133
ops := []txn.Op{
134-
createPermissionOp(modelGlobalKey, userGlobalKey(userAccessID(user)), access),
134+
createPermissionOp(modelKey(modelUUID), userGlobalKey(userAccessID(user)), access),
135135
{
136136
C: modelUsersC,
137137
Id: userAccessID(user),
@@ -146,7 +146,7 @@ func createModelUserOps(modelUUID string, user, createdBy names.UserTag, display
146146
// removeModelUser removes a user from the database.
147147
func (st *State) removeModelUser(user names.UserTag) error {
148148
ops := []txn.Op{
149-
removePermissionOp(modelGlobalKey, userGlobalKey(userAccessID(user))),
149+
removePermissionOp(modelKey(st.ModelUUID()), userGlobalKey(userAccessID(user))),
150150
{
151151
C: modelUsersC,
152152
Id: userAccessID(user),

state/state_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (s *StateSuite) TestModelUUID(c *gc.C) {
176176

177177
func (s *StateSuite) TestNoModelDocs(c *gc.C) {
178178
c.Assert(s.State.EnsureModelRemoved(), gc.ErrorMatches,
179-
fmt.Sprintf("found documents for model with uuid %s: 1 constraints doc, 2 leases doc, 1 modelusers doc, 2 permissions doc, 1 settings doc, 1 statuses doc", s.State.ModelUUID()))
179+
fmt.Sprintf("found documents for model with uuid %s: 1 constraints doc, 2 leases doc, 1 modelusers doc, 1 settings doc, 1 statuses doc", s.State.ModelUUID()))
180180
}
181181

182182
func (s *StateSuite) TestMongoSession(c *gc.C) {

state/user_internal_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ func (s *internalUserSuite) TestCreateInitialUserOps(c *gc.C) {
3434
op = ops[1]
3535
permdoc := op.Insert.(*permissionDoc)
3636
c.Assert(permdoc.Access, gc.Equals, string(description.SuperuserAccess))
37-
c.Assert(permdoc.ID, gc.Equals, permissionID(controllerGlobalKey, userGlobalKey(strings.ToLower(tag.Canonical()))))
37+
c.Assert(permdoc.ID, gc.Equals, permissionID(controllerKey(s.state.ControllerUUID()), userGlobalKey(strings.ToLower(tag.Canonical()))))
3838
c.Assert(permdoc.SubjectGlobalKey, gc.Equals, userGlobalKey(strings.ToLower(tag.Canonical())))
39-
c.Assert(permdoc.ObjectGlobalKey, gc.Equals, controllerGlobalKey)
39+
c.Assert(permdoc.ObjectGlobalKey, gc.Equals, controllerKey(s.state.ControllerUUID()))
4040

4141
// controller user
4242
op = ops[2]

state/useraccess.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func userAccessID(user names.UserTag) string {
113113
// NewModelUserAccess returns a new description.UserAccess for the given userDoc and
114114
// current Model.
115115
func NewModelUserAccess(st *State, userDoc userAccessDoc) (description.UserAccess, error) {
116-
perm, err := st.userPermission(modelGlobalKey, userGlobalKey(strings.ToLower(userDoc.UserName)))
116+
perm, err := st.userPermission(modelKey(st.ModelUUID()), userGlobalKey(strings.ToLower(userDoc.UserName)))
117117
if err != nil {
118118
return description.UserAccess{}, errors.Annotate(err, "obtaining model permission")
119119
}
@@ -123,7 +123,7 @@ func NewModelUserAccess(st *State, userDoc userAccessDoc) (description.UserAcces
123123
// NewControllerUserAccess returns a new description.UserAccess for the given userDoc and
124124
// current Controller.
125125
func NewControllerUserAccess(st *State, userDoc userAccessDoc) (description.UserAccess, error) {
126-
perm, err := st.controllerUserPermission(controllerGlobalKey, userGlobalKey(strings.ToLower(userDoc.UserName)))
126+
perm, err := st.controllerUserPermission(controllerKey(st.ControllerUUID()), userGlobalKey(strings.ToLower(userDoc.UserName)))
127127
if err != nil {
128128
return description.UserAccess{}, errors.Annotate(err, "obtaining controller permission")
129129
}

state/userpermission.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,28 @@ func accessToString(a description.Access) string {
4040
}
4141

4242
// userPermission returns a Permission for the given Subject and User.
43-
func (st *State) userPermission(objectKey, subjectKey string) (*permission, error) {
43+
func (st *State) userPermission(objectGlobalKey, subjectGlobalKey string) (*permission, error) {
4444
userPermission := &permission{}
4545
permissions, closer := st.getCollection(permissionsC)
4646
defer closer()
4747

48-
id := permissionID(objectKey, subjectKey)
49-
err := permissions.FindId(st.docID(id)).One(&userPermission.doc)
48+
id := permissionID(objectGlobalKey, subjectGlobalKey)
49+
err := permissions.FindId(id).One(&userPermission.doc)
5050
if err == mgo.ErrNotFound {
5151
return nil, errors.NotFoundf("user permissions for user %q", id)
5252
}
5353
return userPermission, nil
5454
}
5555

5656
// controllerUserPermission returns a Permission for the given Subject and User.
57-
func (st *State) controllerUserPermission(objectKey, subjectKey string) (*permission, error) {
57+
func (st *State) controllerUserPermission(objectGlobalKey, subjectGlobalKey string) (*permission, error) {
5858
userPermission := &permission{}
59-
controllerSt, err := st.ForModel(st.controllerModelTag)
60-
if err != nil {
61-
return nil, errors.Trace(err)
62-
}
63-
defer controllerSt.Close()
6459

65-
permissions, closer := controllerSt.getCollection(permissionsC)
60+
permissions, closer := st.getCollection(permissionsC)
6661
defer closer()
6762

68-
id := permissionID(objectKey, subjectKey)
69-
err = permissions.FindId(controllerSt.docID(id)).One(&userPermission.doc)
63+
id := permissionID(objectGlobalKey, subjectGlobalKey)
64+
err := permissions.FindId(id).One(&userPermission.doc)
7065
if err == mgo.ErrNotFound {
7166
return nil, errors.NotFoundf("user permissions for user %q", id)
7267
}
@@ -95,12 +90,23 @@ func (p *permission) access() description.Access {
9590
return stringToAccess(p.doc.Access)
9691
}
9792

98-
func permissionID(objectKey, subjectKey string) string {
99-
// example: e#us#jim
100-
// e: model global key (its always e).
101-
// us: user key prefix.
102-
// jim: an arbitrary username.
103-
return fmt.Sprintf("%s#%s", objectKey, subjectKey)
93+
func permissionID(objectGlobalKey, subjectGlobalKey string) string {
94+
// example: e#:deadbeef#us#jim
95+
// e: object global key
96+
// deadbeef: object uuid
97+
// us#jim: subject global key
98+
// the first element (e in this example) is the global key for the object
99+
// (model in this example)
100+
// the second, is the : prefixed model uuid
101+
// the third, in this example is a user with name jim, hence the globalKey
102+
// ( a user global key) being us#jim.
103+
// another example, now with controller and user maria:
104+
// c#:deadbeef#us#maria
105+
// c: object global key, in this case controller.
106+
// :deadbeef controller uuid
107+
// us#maria: its the user global key for maria.
108+
// if this where for model, it would be e#us#maria
109+
return fmt.Sprintf("%s#%s", objectGlobalKey, subjectGlobalKey)
104110
}
105111

106112
func updatePermissionOp(objectGlobalKey, subjectGlobalKey string, access description.Access) txn.Op {

0 commit comments

Comments
 (0)