Skip to content

Commit 7266a53

Browse files
committed
fix(cloud_auth): Correctly route users/me
Fix routing of `users/me` endpoint to correctly alias to invoking principal.
1 parent 756c48f commit 7266a53

File tree

11 files changed

+91
-133
lines changed

11 files changed

+91
-133
lines changed

apps/cli/fixtures/standalone/auth/goldens/ast.resolved.json

Lines changed: 9 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/cli/fixtures/standalone/auth/goldens/celest.json

Lines changed: 8 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/cli/fixtures/standalone/data/goldens/ast.resolved.json

Lines changed: 9 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/cli/fixtures/standalone/data/goldens/celest.json

Lines changed: 8 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
import 'dart:convert';
2+
13
import 'package:celest_core/celest_core.dart';
24

35
mixin BaseProtocol {
46
Never throwError({
57
required int statusCode,
68
required List<int> bodyBytes,
79
}) {
8-
final jsonBody = JsonUtf8.decodeMap(bodyBytes);
9-
throw CloudException.fromJson(jsonBody, code: statusCode);
10+
try {
11+
final jsonBody = JsonUtf8.decodeMap(bodyBytes);
12+
throw CloudException.fromJson(jsonBody, code: statusCode);
13+
} on FormatException {
14+
throw CloudException.http(
15+
code: statusCode,
16+
message: utf8.decode(bodyBytes),
17+
);
18+
}
1019
}
1120
}

services/celest_cloud_auth/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- feat!: Make database modular
44
- refactor!: Rename `AuthDatabase` to `CloudAuthDatabase`
55
- refactor!: Rename all entities with `cloud_auth_` prefix
6+
- fix: Correctly route `users/me`
67
- chore: Make `Authorizer` a class
78
- chore: Update dependencies
89

services/celest_cloud_auth/lib/src/authorization/cedar/policies.cedar

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ permit (
6666
resource in ?resource
6767
);
6868

69+
// Anonymous functions and APIs.
70+
@id("cloud.functions.anonymous")
71+
permit (
72+
principal in Celest::Role::"anonymous",
73+
action == Celest::Action::"invoke",
74+
resource in ?resource
75+
);
76+
6977
// Public functions and APIs.
7078
@id("cloud.functions.public")
7179
permit (

services/celest_cloud_auth/lib/src/authorization/policy_set.g.dart

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/celest_cloud_auth/lib/src/context.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ extension type Context._(celest.Context _context) implements celest.Context {
3333
return const EmailOtpProvider();
3434
}
3535

36-
Map<String, String>? get routeParameters =>
37-
_context.get(contextKeyRouteParameters);
36+
Map<String, String> get routeParameters =>
37+
_context.expect(contextKeyRouteParameters);
3838
}
3939

4040
const celest.ContextKey<CedarCork> contextKeyCork = celest.ContextKey('cork');

services/celest_cloud_auth/lib/src/users/users_service.dart

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'package:cedar/ast.dart' hide Value;
21
import 'package:cedar/cedar.dart' hide Value;
32
// ignore: invalid_use_of_internal_member
43
import 'package:celest/src/runtime/http/cloud_middleware.dart';
@@ -120,18 +119,13 @@ extension type UsersService._(_Deps _deps) implements Object {
120119
),
121120
},
122121
policySet: PolicySet(
123-
policies: {
124-
apiId: Policy(
125-
effect: Effect.permit,
126-
principal: const PrincipalIs('Celest::User'),
127-
action: const ActionEquals(CelestAction.invoke),
128-
annotations: Annotations({
129-
'id': apiId,
130-
}),
131-
resource: const ResourceIn(apiUid),
132-
conditions: [],
122+
templateLinks: [
123+
TemplateLink(
124+
templateId: 'cloud.functions.anonymous',
125+
newId: apiId,
126+
values: {SlotId.resource: apiUid},
133127
),
134-
},
128+
],
135129
),
136130
);
137131

@@ -165,16 +159,22 @@ extension type UsersService._(_Deps _deps) implements Object {
165159

166160
Future<Response> handleGetUser(Request request) async {
167161
final principal = context.get(ContextKey.principal);
168-
// TODO: Handle users/me
162+
final user = await getUser(
163+
userId: switch (context.routeParameters['name']!.split('/')) {
164+
['users', 'me'] when principal != null => principal.id,
165+
['users', final userId] => userId,
166+
final badName => throw BadRequestException(
167+
'Invalid user: $badName. Expected users/{user_id}',
168+
),
169+
},
170+
);
169171

170-
final resource = _getResource(request);
171172
await _authorizer.expectAuthorized(
172173
principal: principal?.uid,
173-
resource: resource,
174+
resource: EntityUid.of('Celest::User', user.id),
174175
action: CelestAction.get,
175176
);
176-
final response = await getUser(userId: principal!.userId);
177-
return response.toProto().jsonResponse();
177+
return user.toProto().jsonResponse();
178178
}
179179

180180
@visibleForTesting

0 commit comments

Comments
 (0)