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/3330 Metadata creation tool & Storage api #3334

Merged
merged 70 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ccb5706
related to #3331, remove unused policy files
t83714 Mar 11, 2022
3e4529c
#3330 add access control aspect to distributions
t83714 Mar 11, 2022
c1b6bd2
fix: no need & should not return user's current org as root node -- i…
t83714 Mar 14, 2022
d11d3c0
remove obsolete resource `registry/record` & relevant records defined…
t83714 Mar 14, 2022
25040d9
remove obsolete `object/dataset/published/updateLicenseInfo` & `objec…
t83714 Mar 14, 2022
147685f
re-setup default roles
t83714 Mar 14, 2022
897743e
fix sql migration script
t83714 Mar 14, 2022
b4ee839
fixed sql migration script: incorrect id
t83714 Mar 14, 2022
60aabbd
refine tune default roles setup
t83714 Mar 15, 2022
65292fe
more accurately control my dataset section access
t83714 Mar 15, 2022
a45c4d2
explicitly remove 'object/dataset/published/updateLicenseInfo' & 'ob…
t83714 Mar 15, 2022
3483df0
- remove userId based query so all datasets the user has access will …
t83714 Mar 15, 2022
f9e3a37
check user access to metadata creation function by permissions to all…
t83714 Mar 15, 2022
5f69586
adjust draft dataset definition in policy: allow records without `dat…
t83714 Mar 15, 2022
0328123
add Read Org Units with own org units permission to default roles
t83714 Mar 16, 2022
b623c74
correct typo
t83714 Mar 16, 2022
176ad03
- move record auth logic to parametered rule
t83714 Mar 16, 2022
e83ca72
#3333 Rename access-control aspect orgUnitOwnerId field to orgUnitId
t83714 Mar 16, 2022
bfea4f9
format the code
t83714 Mar 16, 2022
624d474
- skip ensure aspect for now
t83714 Mar 16, 2022
eddc7cb
- add skipAuth option to storage api chart
t83714 Mar 16, 2022
1ed3604
fix policies: import breakdownOperationUri
t83714 Mar 16, 2022
7fb7d0b
Merge remote-tracking branch 'origin/next' into issue/3330
t83714 Mar 16, 2022
46bc984
- add registry api `getByIdInFull`
t83714 Mar 21, 2022
b9f74c4
related to #3335, remove `/v0/storage/upload/{bucket}/{path}` API
t83714 Mar 21, 2022
b7ab276
fixed: registry router
t83714 Mar 21, 2022
868c3b2
fixed test cases
t83714 Mar 21, 2022
ee5086b
fixed: getUserId middleware incorrect retrieve userId from req
t83714 Mar 21, 2022
82a7caf
fix test cases
t83714 Mar 22, 2022
14a1a9c
remove obsolete auth test cases -- new test cases to be added
t83714 Mar 22, 2022
166445a
bump index version number
t83714 Mar 22, 2022
1c1c41e
add presign url methods
t83714 Mar 23, 2022
a3ba4f3
fix: create userId for storage api pod
t83714 Mar 24, 2022
007ea5f
- add storage resource / operations to sql migration file
t83714 Mar 24, 2022
622abd2
- restore POST /upload/:bucket* as we still need it for UI for now
t83714 Mar 24, 2022
c724bc8
add policy entry point for storage objects
t83714 Mar 24, 2022
38c8031
adjust how auth decision context data is created for storage/object
t83714 Mar 24, 2022
0731a46
adjust storage auth middleware logic
t83714 Mar 27, 2022
6f4295b
make sure `getDownloadUrl` always generate valid s3 object keys from …
t83714 Mar 27, 2022
976aa2c
move getDownloadUrl to magda-typescript-common and rename to getStora…
t83714 Mar 27, 2022
c41e0f4
add test cases for getStorageUrl
t83714 Mar 27, 2022
65e258c
adjust storage related policies
t83714 Mar 27, 2022
e6a0ef2
- code refactoring
t83714 Mar 28, 2022
355370f
- make sure delete storage response 200 when the storage object doesn…
t83714 Mar 28, 2022
e453206
- #3339 update DB migration script for default role setup
t83714 Mar 28, 2022
b235334
#3339 fix sql migration incorrect resource id
t83714 Mar 28, 2022
91862b7
use requirePermission in storageAuthMiddleware
t83714 Mar 28, 2022
17bcbc8
- fix: orgUnit read API should use partial eval
t83714 Mar 28, 2022
7e68718
increase registry request timeout time to 60s (from 30s)
t83714 Mar 29, 2022
86c11ae
add rsuite default theme to metadata creation tool
t83714 Mar 29, 2022
8a25a9e
decideion endpoint will print execution time in logs when debug mode …
t83714 Mar 29, 2022
0de510c
- update helm docs
t83714 Mar 29, 2022
7d0d230
#3340 speed up the opa AST evaluate by proactively set `input.` refer…
t83714 Mar 30, 2022
b89a801
#3340 remove duplicated rules to reduce the processing time by 200ms
t83714 Mar 30, 2022
ac6e58e
#3340 add extra large response sample to decision endpoint test case
t83714 Mar 30, 2022
a6d1081
- upgrade redux to 4.1.2
t83714 Mar 30, 2022
40b5a01
fix NestedSetModelQueryer table ref case issue
t83714 Mar 30, 2022
98dd521
- use "@magda/typescript-common/dist/ServerError" instead to avoid du…
t83714 Mar 31, 2022
2947dd0
add more comments & test cases
t83714 Mar 31, 2022
55ab007
- adjust the feature behinds the feature flags
t83714 Mar 31, 2022
c9a0c2e
move `custodianOrgUnitId` & `managingOrgUnitId` to publishing aspect
t83714 Mar 31, 2022
dd2516c
set default access level to `creatorOrgUnit" (within creator's orgnis…
t83714 Mar 31, 2022
666a50f
dataset access control settings
t83714 Mar 31, 2022
ead4559
enable edit page for non-admin users
t83714 Mar 31, 2022
72d80b9
add nice loading bar for add/edit metadata tool
t83714 Mar 31, 2022
09d27c3
turned off approval workflow & publish to dga for test site deploymen…
t83714 Mar 31, 2022
56d3c76
fix should process file name before upload files
t83714 Apr 1, 2022
c850404
#3340 reduce no. of rules in PE result further by filter out "impossi…
t83714 Apr 1, 2022
648b710
#3340 update auth decision test case sample file
t83714 Apr 1, 2022
8582752
update changes.md
t83714 Apr 2, 2022
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
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
- #3308 Policy enforcement on auth objects APIs
- related #3250: Rewrite decision enforcement logic for search API
- #3326 Build OPA docker image with builtin policies & Run OPA as a side car
- #3330 Fine-tune Metadata creation tool workflow for the new auth model
- #3332 Policy Enforcement on Storage API using new auth model
- #3333 Rename access-control aspect orgUnitOwnerId field to orgUnitId
- #3335 Reshape Storage API (in progress)
- #3340 OPA AST parser takes too long to evaluate large response
- Increase registry default request timeout to 60s (from 30s)
- Bump Dataset index version to 49 & publishers index version to 7

## 1.2.1

Expand Down
8 changes: 4 additions & 4 deletions deploy/helm/internal-charts/registry-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ Kubernetes: `>= 1.14.0-0`
| defaultImage.pullPolicy | string | `"IfNotPresent"` | |
| defaultImage.pullSecrets | bool | `false` | |
| defaultImage.repository | string | `"docker.io/data61"` | |
| deployments.full | object | `{"idleTimeout":"60s","replicas":1,"requestTimeout":"30s"}` | deployment config for full registry instance. You can also specify different `resources` config under this key. |
| deployments.full | object | `{"idleTimeout":"60s","replicas":1,"requestTimeout":"60s"}` | deployment config for full registry instance. You can also specify different `resources` config under this key. |
| deployments.full.idleTimeout | string | `"60s"` | Default idle timeout for full instance. Make sure `idleTimeout` is longer than `requestTimeout` |
| deployments.full.requestTimeout | string | `"30s"` | Default request timeout for full instance |
| deployments.readOnly | object | `{"enable":false,"idleTimeout":"60s","replicas":1,"requestTimeout":"30s"}` | deployment config for readonly registry instances. You can also specify different `resources` config under this key. |
| deployments.full.requestTimeout | string | `"60s"` | Default request timeout for full instance |
| deployments.readOnly | object | `{"enable":false,"idleTimeout":"60s","replicas":1,"requestTimeout":"60s"}` | deployment config for readonly registry instances. You can also specify different `resources` config under this key. |
| deployments.readOnly.idleTimeout | string | `"60s"` | Default idle timeout for readonly instance. Make sure `idleTimeout` is longer than `requestTimeout` |
| deployments.readOnly.replicas | int | `1` | no. of replicates. Its value must no lower than `minReplicas` |
| deployments.readOnly.requestTimeout | string | `"30s"` | Default request timeout for readonly instance |
| deployments.readOnly.requestTimeout | string | `"60s"` | Default request timeout for readonly instance |
| image.name | string | `"magda-registry-api"` | |
| livenessProbe | object | `{}` | |
| printSQlInConsole | bool | `false` | Whether print all SQL in console. For DEBUG only |
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/internal-charts/registry-api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ deployments:
replicas: 1

# -- Default request timeout for full instance
requestTimeout: 30s
requestTimeout: 60s

# -- Default idle timeout for full instance.
# Make sure `idleTimeout` is longer than `requestTimeout`
Expand All @@ -45,7 +45,7 @@ deployments:
replicas: 1

# -- Default request timeout for readonly instance
requestTimeout: 30s
requestTimeout: 60s

# -- Default idle timeout for readonly instance.
# Make sure `idleTimeout` is longer than `requestTimeout`
Expand Down
3 changes: 2 additions & 1 deletion deploy/helm/internal-charts/storage-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ Kubernetes: `>= 1.14.0-0`
| minioRegion | string | "unspecified-region" | specify bucket region |
| resources.limits.cpu | string | `"50m"` | |
| resources.requests.cpu | string | `"10m"` | |
| resources.requests.memory | string | `"30Mi"` | |
| resources.requests.memory | string | `"30Mi"` | |
| skipAuth | bool | `false` | when set to true, API will not query policy engine for auth decision but assume it's always permitted. It's for debugging only. |
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ spec:
"--minioPort", "9000",
{{- if .Values.minioRegion }}
"--minioRegion", {{ .Values.minioRegion | quote }},
{{- end }}
{{- if .Values.skipAuth }}
"--skipAuth", "true",
{{- end }}
"--authApiUrl", "http://authorization-api/v0",
"--tenantId", "0",
Expand All @@ -56,6 +59,8 @@ spec:
secretKeyRef:
name: storage-secrets
key: accesskey
- name: USER_ID
value: {{ .Values.global.defaultAdminUserId }}
- name: JWT_SECRET
valueFrom:
secretKeyRef:
Expand Down
4 changes: 4 additions & 0 deletions deploy/helm/internal-charts/storage-api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ defaultBuckets: []
# @default -- "unspecified-region"
minioRegion: ""

# -- when set to true, API will not query policy engine for auth decision but assume it's always permitted.
# It's for debugging only.
skipAuth: false

minio:
host: "minio"
port: 9000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ test_deny_read_if_permission_is_incorrect {
"registry": {
"record": {
"esri-access-control": {
"orgUnitOwnerId": ["G1", "G2"],
"orgUnitId": ["G1", "G2"],
"expiration": 9569380434535153100
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package object.registry.record

# "access-control" is the aspect id defined in the registry database.
orgunit {
input.object.registry.record["access-control"].orgUnitOwnerId == input.user.managingOrgUnitIds[_]
input.object.registry.record["access-control"].orgUnitId == input.user.managingOrgUnitIds[_]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test_allow_correct_orgunit {
"registry": {
"record": {
"access-control": {
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand All @@ -26,7 +26,7 @@ test_deny_wrong_orgunit {
"registry": {
"record": {
"access-control": {
"orgUnitOwnerId": "5"
"orgUnitId": "5"
}
}
}
Expand Down Expand Up @@ -57,7 +57,7 @@ test_deny_empty_managing_orgunit_ids {
"registry": {
"record": {
"access-control": {
"orgUnitOwnerId": "5"
"orgUnitId": "5"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test_allow_read_if_owner_and_permission_are_correct_regardless_orgunit {
"record": {
"access-control": {
"ownerId": "personA",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down Expand Up @@ -50,7 +50,7 @@ test_deny_read_if_owner_and_permission_are_incorrect {
"record": {
"access-control": {
"ownerId": "personB",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test_allow_read_if_owner_and_permission_are_correct {
"record": {
"access-control": {
"ownerId": "personA",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down Expand Up @@ -59,7 +59,7 @@ test_allow_read_if_orgunit_and_permission_are_correct {
"record": {
"access-control": {
"ownerId": "personB",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down Expand Up @@ -89,7 +89,7 @@ test_deny_read_if_both_owner_and_orgunit_are_incorrect {
"record": {
"access-control": {
"ownerId": "personB",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down Expand Up @@ -119,7 +119,7 @@ test_deny_read_if_permission_is_incorrect {
"record": {
"access-control": {
"ownerId": "personA",
"orgUnitOwnerId": "3"
"orgUnitId": "3"
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ magda:
fallbackUrl: "https://data.gov.au"
featureFlags:
cataloguing: true
publishToDga: true
publishToDga: false
placeholderWorkflowsOn: false
datasetApprovalWorkflowOn: true
datasetApprovalWorkflowOn: false
useStorageApi: true
vocabularyApiEndpoints:
- "https://vocabs.ands.org.au/repository/api/lda/abares/australian-land-use-and-management-classification/version-8/concept.json"
Expand Down
41 changes: 25 additions & 16 deletions magda-authorization-api/src/NestedSetModelQueryer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,14 @@ class NestedSetModelQueryer {
async getNodes(
nodesQuery: NodesQuery = {},
fields: string[] = null,
client: pg.Client = null
client: pg.Client = null,
authDecision: AuthDecision = UnconditionalTrueDecision
): Promise<NodeRecord[]> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"]
});
const clauses = [
authConditions,
nodesQuery.name
? sqls`"name" = ${nodesQuery.name}`
: SQLSyntax.empty,
Expand Down Expand Up @@ -225,7 +230,7 @@ class NestedSetModelQueryer {

/**
* Get the root node of the tree
* Return null if empty tree
* Return null if empty tree or the user has no access to the root node
*
* @param {string[]} [fields=null] Selected Fields; If null, use this.defaultSelectFieldList
* @param {pg.Client} [client=null] Optional pg client; Use supplied client connection for query rather than a random connection from Pool
Expand Down Expand Up @@ -277,7 +282,7 @@ class NestedSetModelQueryer {
): Promise<NodeRecord[]> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Children"
tableRef: "children"
});
const tbl = escapeIdentifier(this.tableName);
const conditions = [
Expand Down Expand Up @@ -320,7 +325,7 @@ class NestedSetModelQueryer {
): Promise<NodeRecord[]> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Parents"
tableRef: "parents"
});
const tbl = escapeIdentifier(this.tableName);
const conditions = [
Expand Down Expand Up @@ -360,7 +365,7 @@ class NestedSetModelQueryer {
): Promise<NodeRecord[]> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Children"
tableRef: "children"
});
const tbl = escapeIdentifier(this.tableName);
const result = await (client ? client : this.pool).query(
Expand Down Expand Up @@ -401,7 +406,7 @@ class NestedSetModelQueryer {
): Promise<Maybe<NodeRecord>> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Parents"
tableRef: "parents"
});
const tbl = escapeIdentifier(this.tableName);
const result = await (client ? client : this.pool).query(
Expand Down Expand Up @@ -474,7 +479,7 @@ class NestedSetModelQueryer {
): Promise<number> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Parents"
tableRef: "parents"
});
const tbl = escapeIdentifier(this.tableName);
const result = await this.pool.query(
Expand Down Expand Up @@ -548,7 +553,7 @@ class NestedSetModelQueryer {
): Promise<Maybe<NodeRecord>> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Children"
tableRef: "children"
});
const tbl = escapeIdentifier(this.tableName);
const result = await this.pool.query(
Expand Down Expand Up @@ -579,7 +584,7 @@ class NestedSetModelQueryer {
): Promise<Maybe<NodeRecord>> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "Children"
tableRef: "children"
});
const tbl = escapeIdentifier(this.tableName);
const result = await this.pool.query(
Expand All @@ -599,9 +604,11 @@ class NestedSetModelQueryer {

/**
* Get all nodes on the top to down path between the `higherNode` to the `lowerNode`
* Sort from higher level nodes to lower level node
* If a path doesn't exist, null will be returned
* If you pass a lower node to the `higherNodeId` and a higher node to `lowerNodeId`, null will be returned
* Sort from higher level nodes to lower level node.
* Result will include `higherNode` and the `lowerNode`.
* If `higherNode` and the `lowerNode` is the same node, an array contains the single node will be return.
* If a path doesn't exist, empty array (`[]`) will be returned
* If you pass a lower node to the `higherNodeId` and a higher node to `lowerNodeId`, empty array will be returned
*
* @param {string} higherNodeId
* @param {string} lowerNodeId
Expand All @@ -612,7 +619,7 @@ class NestedSetModelQueryer {
higherNodeId: string,
lowerNodeId: string,
authDecision: AuthDecision = UnconditionalTrueDecision
): Promise<Maybe<NodeRecord[]>> {
): Promise<NodeRecord[]> {
const authConditions = authDecision.toSql({
prefixes: ["input.authObject.orgUnit"],
tableRef: "t2"
Expand All @@ -631,9 +638,11 @@ class NestedSetModelQueryer {
}
ORDER BY (t2.right-t2.left) DESC`.toQuery()
);
if (!result || !result.rows || !result.rows.length)
return Maybe.nothing();
return Maybe.just(result.rows);
if (!result?.rows?.length) {
return [];
} else {
return result.rows;
}
}

/**
Expand Down
Loading