func grantControllerAccess(accessor *state.State, targetUserTag, apiUser names.UserTag, access permission.Access) error { _, err := accessor.AddControllerUser(state.UserAccessSpec{User: targetUserTag, CreatedBy: apiUser, Access: access}) if errors.IsAlreadyExists(err) { controllerTag := accessor.ControllerTag() controllerUser, err := accessor.UserAccess(targetUserTag, controllerTag) if errors.IsNotFound(err) { // Conflicts with prior check, must be inconsistent state. err = txn.ErrExcessiveContention } if err != nil { return errors.Annotate(err, "could not look up controller access for user") } // Only set access if greater access is being granted. if controllerUser.Access.EqualOrGreaterControllerAccessThan(access) { return errors.Errorf("user already has %q access or greater", access) } if _, err = accessor.SetUserAccess(controllerUser.UserTag, controllerUser.Object, access); err != nil { return errors.Annotate(err, "could not set controller access for user") } return nil } if err != nil { return errors.Trace(err) } return nil }
func revokeControllerAccess(accessor *state.State, targetUserTag, apiUser names.UserTag, access permission.Access) error { controllerTag := accessor.ControllerTag() switch access { case permission.LoginAccess: // Revoking login access removes all access. err := accessor.RemoveUserAccess(targetUserTag, controllerTag) return errors.Annotate(err, "could not revoke controller access") case permission.AddModelAccess: // Revoking add-model access sets login. controllerUser, err := accessor.UserAccess(targetUserTag, controllerTag) if err != nil { return errors.Annotate(err, "could not look up controller access for user") } _, err = accessor.SetUserAccess(controllerUser.UserTag, controllerUser.Object, permission.LoginAccess) return errors.Annotate(err, "could not set controller access to read-only") case permission.SuperuserAccess: // Revoking superuser sets add-model. controllerUser, err := accessor.UserAccess(targetUserTag, controllerTag) if err != nil { return errors.Annotate(err, "could not look up controller access for user") } _, err = accessor.SetUserAccess(controllerUser.UserTag, controllerUser.Object, permission.AddModelAccess) return errors.Annotate(err, "could not set controller access to add-model") default: return errors.Errorf("don't know how to revoke %q access", access) } }
// UserAccess returns the access the user has on the model state // and the host controller. func UserAccess(st *state.State, utag names.UserTag) (modelUser, controllerUser permission.UserAccess, err error) { var none permission.UserAccess modelUser, err = st.UserAccess(utag, st.ModelTag()) if err != nil && !errors.IsNotFound(err) { return none, none, errors.Trace(err) } controllerUser, err = state.ControllerAccess(st, utag) if err != nil && !errors.IsNotFound(err) { return none, none, errors.Trace(err) } // TODO(perrito666) remove the following section about everyone group // when groups are implemented, this accounts only for the lack of a local // ControllerUser when logging in from an external user that has not been granted // permissions on the controller but there are permissions for the special // everyone group. if !utag.IsLocal() { controllerUser, err = maybeUseGroupPermission(st.UserAccess, controllerUser, st.ControllerTag(), utag) if err != nil { return none, none, errors.Annotatef(err, "obtaining ControllerUser for everyone group") } } if permission.IsEmptyUserAccess(modelUser) && permission.IsEmptyUserAccess(controllerUser) { return none, none, errors.NotFoundf("model or controller user") } return modelUser, controllerUser, nil }
func addModelUsers(c *gc.C, st *state.State) (expected []permission.UserAccess) { // get the model owner testAdmin := names.NewUserTag("test-admin") owner, err := st.UserAccess(testAdmin, st.ModelTag()) c.Assert(err, jc.ErrorIsNil) f := factory.NewFactory(st) return []permission.UserAccess{ // we expect the owner to be an existing model user owner, // add new users to the model f.MakeModelUser(c, nil), f.MakeModelUser(c, nil), f.MakeModelUser(c, nil), } }