Skip to content

Commit

Permalink
Address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaSBrown committed Jan 17, 2025
1 parent cdb0dca commit fb99dc2
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 272 deletions.
83 changes: 33 additions & 50 deletions core/database/foxx/api/controllers/record.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,70 +182,53 @@ class Record {
* @returns {boolean} True if consistent, otherwise false.
*/
isPathConsistent(a_path) {
// This function will populate the this.#loc member and the this.#alloc
// member
if (!this.isManaged()) {
return false;
}

// If there is a new repo we need to check the path there and use that
if (this.#loc.hasOwnProperty("new_repo") && this.#loc.new_repo) {
// Below we get the allocation associated with data item by
// 1. Checking if the data item is in flight, is in the process
// of being moved to a new location or new owner and using that
// oweners id.
// 2. Using the loc.uid parameter if not inflight to get the owner
// id.
const new_alloc = g_db.alloc.firstExample({
_from: this.#loc.new_owner ? this.#loc.new_owner : this.#loc.uid,
_to: this.#loc.new_repo,
});

// If no allocation is found for the item throw an error
// if the paths do not align also throw an error.
if (!new_alloc) {
this.#error = g_lib.ERR_PERM_DENIED;
this.#err_msg =
"Permission denied, '" + this.#key + "' is not part of an allocation '";
return false;
}

this.#repo = g_db._document(this.#loc.new_repo);
const handleError = (errorCode, errorMessage) => {
this.#error = errorCode;
this.#err_msg = errorMessage;
return false;
};

if (!this.#repo) {
this.#error = g_lib.ERR_INTERNAL_FAULT;
this.#err_msg =
"Unable to find repo that record is meant to be allocated too, '" +
this.#loc.new_repo +
"' record '" +
this.#data_id;
return false;
}
const getRepo = (repoId) =>
g_db._document(repoId) ||
handleError(
g_lib.ERR_INTERNAL_FAULT,
`Unable to find repo for allocation: '${repoId}', record: '${this.#data_id}'`,
);

// If path is missing the starting "/" add it back in
if (!a_path.startsWith("/") && this.#repo.path.startsWith("/")) {
a_path = "/" + a_path;
}
const formatPath = (path, repoPath) =>
!path.startsWith("/") && repoPath.startsWith("/") ? `/${path}` : path;

let stored_path = this._pathToRecord(this.#loc, this.#repo.path);
const validatePath = (loc, repoPath, inputPath) =>
this._comparePaths(this._pathToRecord(loc, repoPath), inputPath);

if (!this._comparePaths(stored_path, a_path)) {
const processRepo = (repoId, loc, inputPath) => {
this.#repo = getRepo(repoId);
if (!this.#repo) {
return false;
}
} else {
this.#repo = g_db._document(this.#loc._to);

if (!a_path.startsWith("/") && this.#repo.path.startsWith("/")) {
a_path = "/" + a_path;
}
let stored_path = this._pathToRecord(this.#loc, this.#repo.path);
inputPath = formatPath(inputPath, this.#repo.path);
return validatePath(loc, this.#repo.path, inputPath);
};

// If there is no new repo check that the paths align
if (!this._comparePaths(stored_path, a_path)) {
return false;
if (this.#loc.new_repo) {
const ownerId = this.#loc.new_owner || this.#loc.uid;
const newAlloc = g_db.alloc.firstExample({ _from: ownerId, _to: this.#loc.new_repo });

if (!newAlloc) {
return handleError(
g_lib.ERR_PERM_DENIED,
`Permission denied, '${this.#key}' is not part of an allocation.`,
);
}
return processRepo(this.#loc.new_repo, this.#loc, a_path);
}
return true;

return processRepo(this.#loc._to, this.#loc, a_path);
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/database/foxx/api/controllers/repo.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Repo {
pathType(a_path) {
// Ensure the repo exists
if (!this.#exists) {
throw [g_lib.ERR_PERM_DENIED, "Repo does not exist " + this.#repo_id];
throw [g_lib.ERR_NOT_FOUND, "Repo does not exist " + this.#repo_id];
}

let repo = g_db._document(this.#repo_id);
Expand Down
192 changes: 76 additions & 116 deletions core/database/foxx/tests/authz.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,11 @@ describe("Authz functions", () => {

let req_perm = g_lib.PERM_CREATE;

expect(() =>
authzModule.isRecordActionAuthorized(client, data_key, req_perm),
).to.throw().and.satisfy((error) => {
return Array.isArray(error) &&
error[0] === g_lib.ERR_NOT_FOUND;
});
expect(() => authzModule.isRecordActionAuthorized(client, data_key, req_perm))
.to.throw()
.and.satisfy((error) => {
return Array.isArray(error) && error[0] === g_lib.ERR_NOT_FOUND;
});
});
});

Expand Down Expand Up @@ -170,14 +169,11 @@ describe("Authz functions", () => {
let data_key = "bananas";
let data_id = "d/" + data_key;

g_db.d.save(
{
_key: data_key,
_id: data_id,
creator: "u/george",
},
{ waitForSync: true },
);
g_db.d.save({
_key: data_key,
_id: data_id,
creator: "u/george",
});

let bob = {
_key: "bob",
Expand All @@ -191,16 +187,13 @@ describe("Authz functions", () => {
is_admin: false,
};

g_db.u.save(bob, { waitForSync: true });
g_db.u.save(george, { waitForSync: true });
g_db.u.save(bob);
g_db.u.save(george);

g_db.owner.save(
{
_from: data_id,
_to: "u/george",
},
{ waitForSync: true },
);
g_db.owner.save({
_from: data_id,
_to: "u/george",
});
let req_perm = g_lib.PERM_CREATE;

expect(authzModule.isRecordActionAuthorized(bob, data_key, req_perm)).to.be.false;
Expand All @@ -212,84 +205,63 @@ describe("Authz functions", () => {
let data_key = "apples";
let data_id = "d/" + data_key;

g_db.d.save(
{
_key: data_key,
_id: data_id,
creator: "u/jack",
},
{ waitForSync: true },
);
g_db.d.save({
_key: data_key,
_id: data_id,
creator: "u/jack",
});

let jack = {
_key: "jack",
_id: "u/jack",
is_admin: false,
};

g_db.u.save(jack, { waitForSync: true });
g_db.u.save(jack);

let fruity_project_id = "p/fruity";
g_db.p.save(
{
_key: "fruity",
_id: fruity_project_id,
name: "Project Fruity",
},
{ waitForSync: true },
);
g_db.p.save({
_key: "fruity",
_id: fruity_project_id,
name: "Project Fruity",
});

let condiments_project_id = "p/condiments";
g_db.p.save(
{
_key: "condiments",
_id: condiments_project_id,
name: "Project Condiments",
},
{ waitForSync: true },
);
g_db.p.save({
_key: "condiments",
_id: condiments_project_id,
name: "Project Condiments",
});

let mandy_admin_id = "u/mandy";
let mandy = {
_key: "mandy",
_id: mandy_admin_id,
is_admin: false,
};
g_db.u.save(mandy, { waitForSync: true });
g_db.u.save(mandy);

let amy_admin_id = "u/amy";
g_db.u.save(
{
_key: "amy",
_id: amy_admin_id,
is_admin: false,
},
{ waitForSync: true },
);

g_db.owner.save(
{
_from: data_id,
_to: fruity_project_id,
},
{ waitForSync: true },
);

g_db.admin.save(
{
_from: fruity_project_id,
_to: amy_admin_id,
},
{ waitForSync: true },
);

g_db.admin.save(
{
_from: condiments_project_id,
_to: mandy_admin_id,
},
{ waitForSync: true },
);
g_db.u.save({
_key: "amy",
_id: amy_admin_id,
is_admin: false,
});

g_db.owner.save({
_from: data_id,
_to: fruity_project_id,
});

g_db.admin.save({
_from: fruity_project_id,
_to: amy_admin_id,
});

g_db.admin.save({
_from: condiments_project_id,
_to: mandy_admin_id,
});
let req_perm = g_lib.PERM_CREATE;

// Non-project admin should not have permission
Expand All @@ -302,14 +274,11 @@ describe("Authz functions", () => {
let data_key = "cherry";
let data_id = "d/" + data_key;

g_db.d.save(
{
_key: data_key,
_id: data_id,
creator: "tim",
},
{ waitForSync: true },
);
g_db.d.save({
_key: data_key,
_id: data_id,
creator: "tim",
});

let tim = {
_key: "tim",
Expand All @@ -319,14 +288,11 @@ describe("Authz functions", () => {

// A project is the owner
let project_id = "p/red_fruit";
g_db.p.save(
{
_key: "red_fruit",
_id: project_id,
name: "Project Red Fruit",
},
{ waitForSync: true },
);
g_db.p.save({
_key: "red_fruit",
_id: project_id,
name: "Project Red Fruit",
});

let bob_id = "u/bob";

Expand All @@ -336,25 +302,19 @@ describe("Authz functions", () => {
is_admin: false,
};

g_db.u.save(bob, { waitForSync: true });

g_db.owner.save(
{
_from: data_id,
_to: project_id,
},
{ waitForSync: true },
);

g_db.admin.save(
{
_from: project_id,
_to: bob_id,
},
{ waitForSync: true },
);

g_db.u.save(tim, { waitForSync: true });
g_db.u.save(bob);

g_db.owner.save({
_from: data_id,
_to: project_id,
});

g_db.admin.save({
_from: project_id,
_to: bob_id,
});

g_db.u.save(tim);

let req_perm = g_lib.PERM_READ;

Expand Down
4 changes: 2 additions & 2 deletions core/database/foxx/tests/authz_router.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function defaultWorkingSetup() {
_key: valid_key,
owner: james_id,
});
g_db.repo.save(repo_data, { waitForSync: true });
g_db.repo.save(repo_data);

g_db.u.save(base_user_data);

Expand Down Expand Up @@ -156,7 +156,7 @@ function defaultWorkingSetupProject() {
_key: repo_key,
path: repo_path,
};
g_db.repo.save(repo_data, { waitForSync: true });
g_db.repo.save(repo_data);

// Create edges
g_db.item.save({
Expand Down
Loading

0 comments on commit fb99dc2

Please sign in to comment.