forked from ytgov/internal-data-portal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from icefoganalytics/issue-44/user-dataset-des…
…cription-read-page User: Dataset Description Read Page
- Loading branch information
Showing
43 changed files
with
2,227 additions
and
172 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
api/src/controllers/qa-scenarios/cycle-user-role-type-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { isNil } from "lodash" | ||
|
||
import { Role } from "@/models" | ||
import { RoleTypes } from "@/models/role" | ||
|
||
import BaseController from "@/controllers/base-controller" | ||
|
||
// Keep in sync with web/src/components/qa-scenarios/QaScenariosCard.vue | ||
const ORDERED_ROLE_TYPES = [ | ||
RoleTypes.USER, | ||
RoleTypes.DATA_OWNER, | ||
RoleTypes.BUSINESS_ANALYST, | ||
RoleTypes.SYSTEM_ADMIN, | ||
] | ||
|
||
export class CycleUserRoleTypeController extends BaseController { | ||
async create() { | ||
console.warn("This should not be running in production!") | ||
|
||
try { | ||
const newRoleType = this.determineNextRole() | ||
await this.replaceUserRolesWith(newRoleType) | ||
return this.response.status(201).json({ message: `Cycled user role to ${newRoleType}` }) | ||
} catch (error) { | ||
return this.response.status(422).json({ message: `Could not cycle user role: ${error}` }) | ||
} | ||
} | ||
|
||
private async replaceUserRolesWith(newRoleType: RoleTypes): Promise<void> { | ||
await Role.destroy({ where: { userId: this.currentUser.id }, force: true }) | ||
await Role.create({ | ||
userId: this.currentUser.id, | ||
role: newRoleType, | ||
}) | ||
return | ||
} | ||
|
||
private determineNextRole(): RoleTypes { | ||
if (isNil(this.currentUser)) { | ||
throw new Error("No current user") | ||
} | ||
|
||
const { roleTypes } = this.currentUser | ||
const currentRoleType = roleTypes[0] | ||
if (isNil(currentRoleType)) { | ||
throw new Error("Current user has no roles") | ||
} | ||
|
||
const currentIndex = ORDERED_ROLE_TYPES.indexOf(currentRoleType) | ||
const nextIndex = (currentIndex + 1) % 4 | ||
return ORDERED_ROLE_TYPES[nextIndex] | ||
} | ||
} | ||
|
||
export default CycleUserRoleTypeController |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { LinkRandomTagsController } from "./link-random-tags-controller" | ||
export { ApplyRandomAccessGrantsController } from "./apply-random-access-grants-controller" | ||
export { AddRandomAccessRequestsController } from "./add-random-access-requests-controller" | ||
export { CycleUserRoleTypeController } from "./cycle-user-role-type-controller" |
15 changes: 15 additions & 0 deletions
15
api/src/db/migrations/2024.02.21T20.33.00.remove-dataset-is-subscribable-field.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { DataTypes } from "sequelize" | ||
|
||
import type { Migration } from "@/db/umzug" | ||
|
||
export const up: Migration = async ({ context: queryInterface }) => { | ||
await queryInterface.removeColumn("datasets", "is_subscribable") | ||
} | ||
|
||
export const down: Migration = async ({ context: queryInterface }) => { | ||
await queryInterface.addColumn("datasets", "is_subscribable", { | ||
type: DataTypes.BOOLEAN, | ||
allowNull: false, | ||
defaultValue: false, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
api/src/models/datasets/accessible-via-access-grants-by.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { Op, WhereAttributeHash, literal } from "sequelize" | ||
import { isNil } from "lodash" | ||
|
||
import User from "@/models/user" | ||
|
||
const NON_EXISTENT_ID = -1 | ||
|
||
// TODO: make this less fragile and more easily testable | ||
export function accessibleViaAccessGrantsBy(user: User): { | ||
where: WhereAttributeHash | ||
} { | ||
const { groupMembership } = user | ||
if (isNil(groupMembership)) { | ||
throw new Error("User must have groupMembership to use accessibleViaAccessGrantsBy") | ||
} | ||
|
||
const departmentId = groupMembership.departmentId || NON_EXISTENT_ID | ||
const divisionId = groupMembership.divisionId || NON_EXISTENT_ID | ||
const branchId = groupMembership.branchId || NON_EXISTENT_ID | ||
const unitId = groupMembership.unitId || NON_EXISTENT_ID | ||
|
||
const query = ` | ||
( | ||
SELECT DISTINCT | ||
datasets.id | ||
FROM | ||
datasets | ||
INNER JOIN user_group_memberships AS owner_group_membership ON | ||
owner_group_membership.deleted_at IS NULL | ||
AND owner_group_membership.user_id = datasets.owner_id | ||
INNER JOIN access_grants ON | ||
access_grants.deleted_at IS NULL | ||
AND access_grants.dataset_id = datasets.id | ||
WHERE | ||
( | ||
access_grants.access_type IN ('open_access', 'self_serve_access', 'screened_access') | ||
AND access_grants.grant_level = 'government_wide' | ||
) | ||
OR | ||
( | ||
access_grants.access_type IN ('open_access', 'self_serve_access', 'screened_access') | ||
AND access_grants.grant_level = 'department' | ||
AND owner_group_membership.department_id IS NOT NULL | ||
AND owner_group_membership.department_id = ${departmentId} | ||
) | ||
OR | ||
( | ||
access_grants.access_type IN ('open_access', 'self_serve_access', 'screened_access') | ||
AND access_grants.grant_level = 'division' | ||
AND owner_group_membership.department_id IS NOT NULL | ||
AND owner_group_membership.division_id IS NOT NULL | ||
AND owner_group_membership.department_id = ${departmentId} | ||
AND owner_group_membership.division_id = ${divisionId} | ||
) | ||
OR | ||
( | ||
access_grants.access_type IN ('open_access', 'self_serve_access', 'screened_access') | ||
AND access_grants.grant_level = 'branch' | ||
AND owner_group_membership.department_id IS NOT NULL | ||
AND owner_group_membership.division_id IS NOT NULL | ||
AND owner_group_membership.branch_id IS NOT NULL | ||
AND owner_group_membership.department_id = ${departmentId} | ||
AND owner_group_membership.division_id = ${divisionId} | ||
AND owner_group_membership.branch_id = ${branchId} | ||
) | ||
OR | ||
( | ||
access_grants.access_type IN ('open_access', 'self_serve_access', 'screened_access') | ||
AND access_grants.grant_level = 'unit' | ||
AND owner_group_membership.department_id IS NOT NULL | ||
AND owner_group_membership.division_id IS NOT NULL | ||
AND owner_group_membership.branch_id IS NOT NULL | ||
AND owner_group_membership.unit_id IS NOT NULL | ||
AND owner_group_membership.department_id = ${departmentId} | ||
AND owner_group_membership.division_id = ${divisionId} | ||
AND owner_group_membership.branch_id = ${branchId} | ||
AND owner_group_membership.unit_id = ${unitId} | ||
) | ||
) | ||
` | ||
.replace(/\s+/g, " ") | ||
.trim() | ||
|
||
return { | ||
where: { | ||
id: { | ||
[Op.in]: literal(query), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
export default accessibleViaAccessGrantsBy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { mostPermissiveAccessGrantFor } from "./most-permissive-access-grant-for" | ||
export { accessibleViaAccessGrantsBy } from "./accessible-via-access-grants-by" |
Oops, something went wrong.