Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/3253 Add New /auth/opa/decision Endpoint #3254

Merged
merged 20 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ buildtest:opa-policies:
services:
- docker:dind
script:
- docker run -v $PWD/deploy/helm/internal-charts/opa/policies:/policies openpolicyagent/opa:0.33.0 test -v ./policies
- docker run -v $PWD/deploy/helm/internal-charts/opa/policies:/policies openpolicyagent/opa:0.33.1 test -v ./policies

buildtest:helm-charts:
stage: buildtest
Expand Down
6 changes: 5 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

## Next

- #3231 Upgraded to Open Policy Agent v0.33.0
- #3231 Upgraded to Open Policy Agent v0.33.x
- #3251 Fixed akka HTTP client POST request racing conditions
- #3253 Add New /auth/opa/decision Endpoint
- move pre-defined role ids into a single contants file in magda-typescript-common
- Rewrote the OPA AST parser for better evaluation & reference handling
- Added common policy entry point: entrypoint/allow.rego

## 1.1.0

Expand Down
2 changes: 1 addition & 1 deletion deploy/helm/internal-charts/opa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Kubernetes: `>= 1.14.0-0`
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.pullSecrets | bool | `false` | |
| image.repository | string | `"openpolicyagent"` | |
| image.tag | string | `"0.33.0"` | |
| image.tag | string | `"0.33.1"` | |
| loaderImage.name | string | `"magda-configmap-dir-loader"` | |
| loaderImage.pullPolicy | string | `"IfNotPresent"` | |
| loaderImage.pullSecrets | bool | `false` | |
Expand Down
2 changes: 1 addition & 1 deletion deploy/helm/internal-charts/opa/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3"
services:
test-opa:
image: openpolicyagent/opa:0.33.0
image: openpolicyagent/opa:0.33.1
ports:
- 8181:8181
volumes:
Expand Down
28 changes: 28 additions & 0 deletions deploy/helm/internal-charts/opa/policies/entrypoint/allow.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package entrypoint

import data.object.dataset.allow as dataset_allow
import data.object.content.allowRead as content_allowRead

# When no rule match, the decision will be `denied`
default allow = false

allow {
# users with admin roles will have access to everything
input.user.roles[_].id == "00000000-0000-0003-0000-000000000000"
}

allow {
## delegate dataset related decision to dataset_allow
startswith(input.operationUri, "object/dataset/")
dataset_allow
}

allow {
## delegate content related decision to content_allowRead
startswith(input.operationUri, "object/content/")

## Operation type must be read
endswith(input.operationUri, "/read")

content_allowRead
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package entrypoint

test_allow_non_admin_should_have_no_permission_to_not_defined_resource {
not allow with input as {
"operationUri": "object/test-any-object/test-any-operation",
"user": {
"displayName": "Jacky Jiang",
"email": "[email protected]",
"id": "80a9dce4-91af-44e2-a2f4-9ddccb3f4c5e",
"permissions": [
{
"id": "72d52505-cf96-47b2-9b74-d0fdc1f5aee7",
"name": "View Draft Dataset (Own)",
"operations": [{
"id": "bf946197-392a-4dbb-a7e1-789424e231a4",
"name": "Read Draft Dataset",
"uri": "object/dataset/draft/read",
}],
"orgUnitOwnershipConstraint": false,
"preAuthorisedConstraint": false,
"resourceId": "ea5d2d58-165a-48cb-9b22-42edd6a3024a",
"resourceUri": "object/dataset/draft",
"userOwnershipConstraint": true,
},
{
"id": "e5ce2fc4-9f38-4f52-8190-b770ed2074e6",
"name": "View Published Dataset",
"operations": [{
"id": "f1e2af3e-5d98-4081-a4ff-7016f43002fa",
"name": "Read Publish Dataset",
"uri": "object/dataset/published/read",
}],
"orgUnitOwnershipConstraint": false,
"preAuthorisedConstraint": false,
"resourceId": "ef3b767f-d06b-46f4-9302-031ae5004275",
"resourceUri": "object/dataset/published",
"userOwnershipConstraint": false,
},
],
"photoURL": "//www.gravatar.com/avatar/bed026a33c154abec6852b4e313bf1ce",
"roles": [
{
"id": "00000000-0000-0002-0000-000000000000",
"name": "Authenticated Users",
"permissionIds": ["e5ce2fc4-9f38-4f52-8190-b770ed2074e6"],
},
{
"id": "14ff3f57-e8ea-4771-93af-c6ea91a798d5",
"name": "Approvers",
"permissionIds": [
"e5ce2fc4-9f38-4f52-8190-b770ed2074e6",
"72d52505-cf96-47b2-9b74-d0fdc1f5aee7",
],
},
],
"source": "ckan",
},
}
}

test_allow_admin_should_have_permission_to_not_defined_resource {
allow with input as {
"operationUri": "object/test-any-object/test-any-operation",
"user": {
"displayName": "Jacky Jiang",
"email": "[email protected]",
"id": "80a9dce4-91af-44e2-a2f4-9ddccb3f4c5e",
"permissions": [],
"photoURL": "//www.gravatar.com/avatar/bed026a33c154abec6852b4e313bf1ce",
"roles": [
{
"id": "00000000-0000-0003-0000-000000000000",
"name": "Admin Users",
"permissionIds": []
}
],
"source": "ckan",
},
}
}
2 changes: 1 addition & 1 deletion deploy/helm/internal-charts/opa/values.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
image:
name: opa
repository: openpolicyagent
tag: 0.33.0
tag: 0.33.1
pullPolicy: IfNotPresent
pullSecrets: false

Expand Down
17 changes: 9 additions & 8 deletions magda-authorization-api/src/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import arrayToMaybe from "magda-typescript-common/src/util/arrayToMaybe";
import pg from "pg";
import _ from "lodash";
import GenericError from "magda-typescript-common/src/authorization-api/GenericError";
import {
ANONYMOUS_USERS_ROLE_ID,
AUTHENTICATED_USERS_ROLE_ID,
ADMIN_USERS_ROLE_ID
} from "magda-typescript-common/src/authorization-api/constants";
import { getUserId } from "magda-typescript-common/src/session/GetUserId";
import NestedSetModelQueryer from "./NestedSetModelQueryer";
import isUuid from "magda-typescript-common/src/util/isUuid";
Expand All @@ -19,11 +24,7 @@ export interface DatabaseOptions {
dbPort: number;
}

const ANONYMOUS_USERS_ROLE = "00000000-0000-0001-0000-000000000000";
const AUTHENTICATED_USERS_ROLE = "00000000-0000-0002-0000-000000000000";
const ADMIN_USERS_ROLE = "00000000-0000-0003-0000-000000000000";

const defaultAnonymousUserInfo: User = {
export const defaultAnonymousUserInfo: User = {
id: "",
displayName: "Anonymous User",
email: "",
Expand All @@ -33,7 +34,7 @@ const defaultAnonymousUserInfo: User = {
isAdmin: false,
roles: [
{
id: ANONYMOUS_USERS_ROLE,
id: ANONYMOUS_USERS_ROLE_ID,
name: "Anonymous Users",
description: "Default role for unauthenticated users",
permissionIds: [] as string[]
Expand Down Expand Up @@ -306,14 +307,14 @@ export default class Database {
//--- add default authenticated role to the newly create user
await this.pool.query(
"INSERT INTO user_roles (role_id, user_id) VALUES($1, $2)",
[AUTHENTICATED_USERS_ROLE, userId]
[AUTHENTICATED_USERS_ROLE_ID, userId]
);

//--- add default Admin role to the newly create user (if isAdmin is true)
if (user.isAdmin) {
await this.pool.query(
"INSERT INTO user_roles (role_id, user_id) VALUES($1, $2)",
[ADMIN_USERS_ROLE, userId]
[ADMIN_USERS_ROLE_ID, userId]
);
}

Expand Down
Loading