Skip to content

Commit

Permalink
Merge pull request juju#16768 from hmlanigan/permissions-schema
Browse files Browse the repository at this point in the history
juju#16768

Permissions are related to user for a variety of things: models, controllers, appliation offers, and clouds.

There is a typed list of access values both in juju and now in the schema. The combination of the user id and the object key must be unique within the table - they are combined to become the primary key. This helps ensure that we do not have competing references to a user's access.

The user should exist before a permission is added for it. And only the typed values should be used for access values.

## Checklist

- [x] Code style: imports ordered, good names, simple structure, etc
- [x] Comments saying why design decisions were made
- [x] Go unit tests, with comments saying what you're testing
- ~[ ] [Integration tests](https://github.com/juju/juju/tree/main/tests), with comments saying what you're testing~
- ~[ ] [doc.go](https://discourse.charmhub.io/t/readme-in-packages/451) added or updated in changed packages~

## QA steps
``` sh
cd domain/schema
go test -check.f schemaSuite
```
## Links

JUJU-5096
  • Loading branch information
jujubot authored Jan 23, 2024
2 parents 49c60a3 + e97e169 commit 2992cb5
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
81 changes: 81 additions & 0 deletions domain/schema/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func ControllerDDL() *schema.Schema {
changeLogTriggersForTable("object_store_metadata_path", "path", tableObjectStoreMetadata),
userSchema,
flagSchema,
userPermissionSchema,
}

schema := schema.New()
Expand Down Expand Up @@ -591,3 +592,83 @@ CREATE TABLE flag (
);
`)
}

func userPermissionSchema() schema.Patch {
return schema.MakePatch(`
CREATE TABLE permission_access_type (
id INT PRIMARY KEY,
type TEXT NOT NULL
);
CREATE UNIQUE INDEX idx_permission_access_type
ON permission_access_type (type);
-- Maps to the Access type in core/permission package.
INSERT INTO permission_access_type VALUES
(0, 'read'),
(1, 'write'),
(2, 'consume'),
(3, 'admin'),
(4, 'login'),
(5, 'addmodel'),
(6, 'superuser');
CREATE TABLE permission_object_type (
id INT PRIMARY KEY,
type TEXT NOT NULL
);
CREATE UNIQUE INDEX idx_permission_object_type
ON permission_object_type (type);
INSERT INTO permission_object_type VALUES
(0, 'controller'),
(1, 'cloud'),
(2, 'model'),
(3, 'offer');
CREATE TABLE permission_object_access (
id INT PRIMARY KEY,
access_type_id INT NOT NULL,
object_type_id INT NOT NULL,
CONSTRAINT fk_permission_access_type
FOREIGN KEY (access_type_id)
REFERENCES permission_access_type(id),
CONSTRAINT fk_permission_object_type
FOREIGN KEY (object_type_id)
REFERENCES permission_object_type(id)
);
CREATE UNIQUE INDEX idx_permission_object_access
ON permission_object_access (access_type_id, object_type_id);
INSERT INTO permission_object_access VALUES
(0, 4, 0), -- login, controller
(1, 6, 0), -- superuser, controller
(2, 3, 1), -- admin, cloud
(3, 5, 1), -- addmodel, cloud
(4, 0, 2), -- read, model
(5, 1, 2), -- write, model
(6, 3, 2), -- admin, model
(7, 0, 3), -- read, offer
(8, 2, 3), -- consume, offer
(9, 3, 3); -- admin, offer
CREATE TABLE user_permission (
uuid TEXT PRIMARY KEY,
object_identifier TEXT NOT NULL, -- name or uuid of the object
object_access_id INT NOT NULL,
user_uuid TEXT NOT NULL,
CONSTRAINT fk_permission_user_uuid
FOREIGN KEY (user_uuid)
REFERENCES user(uuid),
CONSTRAINT fk_permission_object_access
FOREIGN KEY (object_access_id)
REFERENCES permission_object_access(id)
);
CREATE UNIQUE INDEX idx_user_permission
ON user_permission (user_uuid, object_identifier);
`)
}
6 changes: 6 additions & 0 deletions domain/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ func (s *schemaSuite) TestControllerDDLApply(c *gc.C) {

// Flags
"flag",

// Permissions
"permission_access_type",
"permission_object_access",
"permission_object_type",
"user_permission",
)
c.Assert(readTableNames(c, s.DB()), jc.SameContents, expected.Union(internalTableNames).SortedValues())
}
Expand Down

0 comments on commit 2992cb5

Please sign in to comment.