Skip to content

Commit 92d08bc

Browse files
author
CCF [bot]
authored
[release/4.x] Cherry pick: Update TypeScript to expose COSE authentication policies (#5403) (#5404)
1 parent 959ed5d commit 92d08bc

File tree

9 files changed

+117
-1
lines changed

9 files changed

+117
-1
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [4.0.4]
9+
10+
[4.0.4]: https://github.com/microsoft/CCF/releases/tag/ccf-4.0.4
11+
12+
- Added TypeScript interfaces `UserCOSESign1AuthnIdentity` and `MemberCOSESign1AuthnIdentity`, to be used with `user_cose_sign1` and `member_cose_sign1` authentication policies.
13+
814
## [4.0.3]
915

1016
[4.0.3]: https://github.com/microsoft/CCF/releases/tag/ccf-4.0.3

doc/build_apps/api.rst

+18
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ Policies
6060
.. doxygenvariable:: ccf::user_cert_auth_policy
6161
:project: CCF
6262

63+
.. doxygenvariable:: ccf::member_cert_auth_policy
64+
:project: CCF
65+
66+
.. doxygenvariable:: ccf::member_cose_sign1_auth_policy
67+
:project: CCF
68+
6369
.. doxygenvariable:: ccf::user_cose_sign1_auth_policy
6470
:project: CCF
6571

@@ -73,6 +79,18 @@ Identities
7379
:project: CCF
7480
:members:
7581

82+
.. doxygenstruct:: ccf::MemberCertAuthnIdentity
83+
:project: CCF
84+
:members:
85+
86+
.. doxygenstruct:: ccf::UserCOSESign1AuthnIdentity
87+
:project: CCF
88+
:members:
89+
90+
.. doxygenstruct:: ccf::MemberCOSESign1AuthnIdentity
91+
:project: CCF
92+
:members:
93+
7694
.. doxygenstruct:: ccf::JwtAuthnIdentity
7795
:project: CCF
7896
:members:

include/ccf/endpoint.h

+3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ namespace ccf::endpoints
132132
* Identity of the caller to be used by the endpoint. This can be
133133
* retrieved inside the endpoint with ctx.get_caller<IdentType>(),
134134
* @see ccf::UserCertAuthnIdentity
135+
* @see ccf::MemberCertAuthnIdentity
136+
* @see ccf::UserCOSESign1tAuthnIdentity
137+
* @see ccf::MemberCOSESign1AuthnIdentity
135138
* @see ccf::JwtAuthnIdentity
136139
*
137140
* @see ccf::empty_auth_policy

js/ccf-app/src/endpoints.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ export interface MemberCertAuthnIdentity extends UserMemberAuthnIdentityCommon {
141141
policy: "member_cert";
142142
}
143143

144+
export interface MemberCOSESign1AuthnIdentity
145+
extends UserMemberAuthnIdentityCommon {
146+
policy: "member_cose_sign1";
147+
}
148+
149+
export interface UserCOSESign1AuthnIdentity
150+
extends UserMemberAuthnIdentityCommon {
151+
policy: "user_cose_sign1";
152+
}
153+
144154
export interface JwtAuthnIdentity extends AuthnIdentityCommon {
145155
policy: "jwt";
146156

@@ -175,7 +185,9 @@ export type AuthnIdentity =
175185
| EmptyAuthnIdentity
176186
| UserCertAuthnIdentity
177187
| MemberCertAuthnIdentity
178-
| JwtAuthnIdentity;
188+
| JwtAuthnIdentity
189+
| MemberCOSESign1AuthnIdentity
190+
| UserCOSESign1AuthnIdentity;
179191

180192
/** See {@linkcode Response.body}. */
181193
export type ResponseBodyType<T> = string | ArrayBuffer | JsonCompatible<T>;

src/apps/js_generic/named_auth_policies.h

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ namespace ccfapp
7070
{
7171
return ccf::UserCOSESign1AuthnPolicy::SECURITY_SCHEME_NAME;
7272
}
73+
else if constexpr (std::is_same_v<T, ccf::MemberCOSESign1AuthnIdentity>)
74+
{
75+
return ccf::MemberCOSESign1AuthnPolicy::SECURITY_SCHEME_NAME;
76+
}
7377
else if constexpr (std::is_same_v<T, ccf::EmptyAuthnIdentity>)
7478
{
7579
return ccf::EmptyAuthnPolicy::SECURITY_SCHEME_NAME;

tests/js-modules/modules.py

+24
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,29 @@ def test_js_exception_output(network, args):
10771077
return network
10781078

10791079

1080+
@reqs.description("Test User Cose authentication")
1081+
def test_user_cose_authentication(network, args):
1082+
primary, _ = network.find_nodes()
1083+
1084+
with primary.client() as c:
1085+
r = c.put("/app/cose", {})
1086+
assert r.status_code == http.HTTPStatus.UNAUTHORIZED, r
1087+
1088+
with primary.client("user0") as c:
1089+
r = c.put("/app/cose", {})
1090+
assert r.status_code == http.HTTPStatus.UNAUTHORIZED, r
1091+
1092+
with primary.client("user0", headers={"content-type": "application/cose"}) as c:
1093+
r = c.put("/app/cose", {})
1094+
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r
1095+
1096+
with primary.client(None, None, "user0") as c:
1097+
r = c.put("/app/cose", {})
1098+
assert r.status_code == http.HTTPStatus.OK, r
1099+
assert r.body.text() == network.users[0].service_id
1100+
return network
1101+
1102+
10801103
def run(args):
10811104
with infra.network.network(
10821105
args.nodes, args.binary_dir, args.debug_nodes, args.perf_nodes, pdb=args.pdb
@@ -1090,6 +1113,7 @@ def run(args):
10901113
network = test_npm_app(network, args)
10911114
network = test_js_execution_time(network, args)
10921115
network = test_js_exception_output(network, args)
1116+
network = test_user_cose_authentication(network, args)
10931117

10941118

10951119
if __name__ == "__main__":

tests/npm-app/app.json

+29
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,35 @@
12841284
}
12851285
}
12861286
}
1287+
},
1288+
"/cose": {
1289+
"put": {
1290+
"js_module": "endpoints/auth.js",
1291+
"js_function": "checkUserCOSESign1Auth",
1292+
"forwarding_required": "sometimes",
1293+
"authn_policies": ["user_cose_sign1"],
1294+
"mode": "readwrite",
1295+
"openapi": {
1296+
"requestBody": {
1297+
"required": true,
1298+
"content": {
1299+
"application/cose": {
1300+
"schema": {}
1301+
}
1302+
}
1303+
},
1304+
"responses": {
1305+
"200": {
1306+
"description": "",
1307+
"content": {
1308+
"application/json": {
1309+
"schema": {}
1310+
}
1311+
}
1312+
}
1313+
}
1314+
}
1315+
}
12871316
}
12881317
}
12891318
}

tests/npm-app/src/endpoints/all.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from "./partition";
55
export * from "./proto";
66
export * from "./log";
77
export * from "./rpc";
8+
export * from "./auth";

tests/npm-app/src/endpoints/auth.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as ccfapp from "@microsoft/ccf-app";
2+
3+
// Note: this is also tested more generically on the multi_auth endpoint
4+
// of the logging application, but not with TypeScript types.
5+
export function checkUserCOSESign1Auth(
6+
request: ccfapp.Request
7+
): ccfapp.Response {
8+
if (request.caller === null || request.caller === undefined) {
9+
return { status: 401 };
10+
}
11+
12+
const caller = request.caller;
13+
if (caller.policy !== "user_cose_sign1") {
14+
return { status: 401 };
15+
}
16+
17+
const id: ccfapp.UserCOSESign1AuthnIdentity = caller;
18+
return { status: 200, body: id.id };
19+
}

0 commit comments

Comments
 (0)