Skip to content

Commit 776dc0f

Browse files
authored
Support organization source and unscoped requests (#2079)
Part of OPS-3862.
1 parent 661b886 commit 776dc0f

7 files changed

Lines changed: 110 additions & 62 deletions

File tree

packages/server/api/src/app/core/security/route-policies/project-id-source-factory.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/server/api/src/app/core/security/route-policies/project-id-source.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { PropertyLocation, PropertySource } from './property-source';
2+
3+
const DEFAULT_PROJECT_KEY = 'projectId';
4+
const DEFAULT_ORGANIZATION_KEY = 'organizationId';
5+
6+
type PropertyHelpers = {
7+
fromParams: (key?: string) => PropertySource;
8+
fromQuery: (key?: string) => PropertySource;
9+
fromBody: (key?: string) => PropertySource;
10+
};
11+
12+
function createPropertySource(
13+
location: PropertyLocation,
14+
defaultKey: string,
15+
key?: string,
16+
): PropertySource {
17+
return {
18+
location,
19+
key: key ?? defaultKey,
20+
};
21+
}
22+
23+
function createPropertyHelpers(defaultKey: string): PropertyHelpers {
24+
return {
25+
fromParams: (key?: string): PropertySource =>
26+
createPropertySource(PropertyLocation.PARAMS, defaultKey, key),
27+
28+
fromQuery: (key?: string): PropertySource =>
29+
createPropertySource(PropertyLocation.QUERY, defaultKey, key),
30+
31+
fromBody: (key?: string): PropertySource =>
32+
createPropertySource(PropertyLocation.BODY, defaultKey, key),
33+
};
34+
}
35+
36+
export const projectIdResolver = createPropertyHelpers(DEFAULT_PROJECT_KEY);
37+
export const organizationIdResolver = createPropertyHelpers(
38+
DEFAULT_ORGANIZATION_KEY,
39+
);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export enum PropertyLocation {
2+
PARAMS = 'PARAMS',
3+
TOKEN = 'TOKEN',
4+
QUERY = 'QUERY',
5+
BODY = 'BODY',
6+
}
7+
8+
type BasePropertySource = {
9+
key: string;
10+
};
11+
12+
export type ParamsPropertySource = BasePropertySource & {
13+
location: PropertyLocation.PARAMS;
14+
};
15+
16+
export type TokenPropertySource = {
17+
location: PropertyLocation.TOKEN;
18+
};
19+
20+
export type QueryPropertySource = BasePropertySource & {
21+
location: PropertyLocation.QUERY;
22+
};
23+
24+
export type BodyPropertySource = BasePropertySource & {
25+
location: PropertyLocation.BODY;
26+
};
27+
28+
export type PropertySource =
29+
| TokenPropertySource
30+
| QueryPropertySource
31+
| BodyPropertySource
32+
| ParamsPropertySource;

packages/server/api/src/app/core/security/route-policies/route-security-policy-factory.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,40 @@ import {
44
PrincipalType,
55
RouteAccessType,
66
} from '@openops/shared';
7-
import { ProjectIdLocation, ProjectIdSource } from './project-id-source';
7+
import { PropertyLocation, PropertySource } from './property-source';
88
import { AuthenticatedRoutePolicy } from './route-security-policy';
99

10-
const defaultProjectIdSource: ProjectIdSource = {
11-
location: ProjectIdLocation.TOKEN,
10+
const defaultSource: PropertySource = {
11+
location: PropertyLocation.TOKEN,
1212
};
1313

14-
export function getOrganizationScopedRoutePolicy(
15-
allowedPrincipals: readonly PrincipalType[],
16-
): AuthenticatedRoutePolicy {
14+
export function getOrganizationScopedRoutePolicy({
15+
organizationIdSource = defaultSource,
16+
allowedPrincipals,
17+
permission,
18+
}: {
19+
allowedPrincipals: readonly PrincipalType[];
20+
organizationIdSource?: PropertySource;
21+
permission?: Permission;
22+
}): AuthenticatedRoutePolicy {
1723
return {
1824
routeAccessType: RouteAccessType.AUTHENTICATED,
1925
authorization: {
2026
authorizationScope: AuthorizationScope.ORGANIZATION,
27+
organizationIdSource,
2128
allowedPrincipals,
29+
permission,
2230
},
2331
};
2432
}
2533

2634
export function getProjectScopedRoutePolicy({
27-
projectIdSource = defaultProjectIdSource,
35+
projectIdSource = defaultSource,
2836
allowedPrincipals,
2937
permission,
3038
}: {
3139
allowedPrincipals: readonly PrincipalType[];
32-
projectIdSource?: ProjectIdSource;
40+
projectIdSource?: PropertySource;
3341
permission?: Permission;
3442
}): AuthenticatedRoutePolicy {
3543
return {
@@ -42,3 +50,15 @@ export function getProjectScopedRoutePolicy({
4250
},
4351
};
4452
}
53+
54+
export function getUnscopedRoutePolicy(
55+
allowedPrincipals: PrincipalType[],
56+
): AuthenticatedRoutePolicy {
57+
return {
58+
routeAccessType: RouteAccessType.AUTHENTICATED,
59+
authorization: {
60+
authorizationScope: AuthorizationScope.UNSCOPED,
61+
allowedPrincipals,
62+
},
63+
};
64+
}

packages/server/api/src/app/core/security/route-policies/route-security-policy.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import {
55
PublicRoutePolicy,
66
RouteAccessType,
77
} from '@openops/shared';
8-
import { ProjectIdSource } from './project-id-source';
8+
import { PropertySource } from './property-source';
99

1010
type AuthorizationPolicy =
1111
| OrganizationAuthorizationPolicy
12-
| ProjectAuthorizationPolicy;
12+
| ProjectAuthorizationPolicy
13+
| UnscopedAuthorizationPolicy;
1314

1415
export type AuthenticatedRoutePolicy = {
1516
routeAccessType: RouteAccessType.AUTHENTICATED;
@@ -19,14 +20,20 @@ export type AuthenticatedRoutePolicy = {
1920
export type OrganizationAuthorizationPolicy = {
2021
authorizationScope: AuthorizationScope.ORGANIZATION;
2122
allowedPrincipals: readonly PrincipalType[];
23+
organizationIdSource: PropertySource;
2224
permission?: Permission;
2325
};
2426

2527
export type ProjectAuthorizationPolicy = {
2628
authorizationScope: AuthorizationScope.PROJECT;
2729
allowedPrincipals: readonly PrincipalType[];
28-
projectIdSource: ProjectIdSource;
30+
projectIdSource: PropertySource;
2931
permission?: Permission;
3032
};
3133

34+
export type UnscopedAuthorizationPolicy = {
35+
authorizationScope: AuthorizationScope.UNSCOPED;
36+
allowedPrincipals: readonly PrincipalType[];
37+
};
38+
3239
export type RouteSecurityPolicy = AuthenticatedRoutePolicy | PublicRoutePolicy;

packages/shared/src/lib/authentication/model/principal-type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const SERVICE_KEY_SECURITY_OPENAPI = {
1717
export enum AuthorizationScope {
1818
ORGANIZATION = 'ORGANIZATION',
1919
PROJECT = 'PROJECT',
20+
UNSCOPED = 'UNSCOPED',
2021
}
2122

2223
export enum RouteAccessType {

0 commit comments

Comments
 (0)