allow to customize the signed CSR return type (#19213)

for #19027, this modifies the website to accept an `deliveryMethod` parameter to
respond with the signed CSR instead of delivering an email.

The current approach also maintains backwards compatibility:

**Response without `deliveryMethod` (unchanged except for custom headers)**

```
$ curl --insecure -v -H 'content-type: application/json' http://localhost:2024/api/v1/deliver-apple-csr -d '{"unsignedCsrData": "foo"}'
*   Trying [::1]:2024...
* Connected to localhost (::1) port 2024
> POST /api/v1/deliver-apple-csr HTTP/1.1
> Host: localhost:2024
> User-Agent: curl/8.4.0
> Accept: */*
> content-type: application/json
> Content-Length: 26
>
< HTTP/1.1 200 OK
< X-Powered-By: Sails <sailsjs.com>
< Cache-Control: no-cache, no-store
< X-Exit: success
< X-Exit-Description: Delivered email to specified email address with certificate signing request attached.
< Content-Type: text/plain; charset=utf-8
< Content-Length: 2
< ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
< Set-Cookie: sails.sid=s%3AqOZoNKY2CCZ6PFb9fIKaAjtiTKjB7Gum.9jodWIUG6DCNnXu%2Bn%2BF8cJmI%2Fn19Tk%2FdIkDPBl%2BILbI; Path=/; HttpOnly
< Date: Wed, 22 May 2024 18:23:16 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
OK
```

**Response with `deliveryMethod=json`**

```
$ curl --insecure -v -H 'content-type: application/json' http://localhost:2024/api/v1/deliver-apple-csr?deliveryMethod=json -d '{"unsignedCsrData": "foo"}'
*   Trying [::1]:2024...
* Connected to localhost (::1) port 2024
> POST /api/v1/deliver-apple-csr?alt=json HTTP/1.1
> Host: localhost:2024
> User-Agent: curl/8.4.0
> Accept: */*
> content-type: application/json
> Content-Length: 26
>
< HTTP/1.1 200 OK
< X-Powered-By: Sails <sailsjs.com>
< Cache-Control: no-cache, no-store
< Content-Type: application/json; charset=utf-8
< X-Exit: success
< X-Exit-Description: Delivered email to specified email address with certificate signing request attached.
< X-Exit-Output-Friendly-Name: RSS feed XML
< Content-Length: 26
< ETag: W/"1a-NnuclRv86ZEKA9WB967iUGlz84s"
< Set-Cookie: sails.sid=s%3AbpaKOTbNe4E911qH4z1-12ABGd_z2d2I.mAimDARoZgnq8zpJHcF95y8qFJXX0iky4Suj0HUKjpI; Path=/; HttpOnly
< Date: Wed, 22 May 2024 18:22:07 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
{"csr":"UEQ5NGJXdy4uLg=="}
```

# Checklist for submitter

- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
This commit is contained in:
Roberto Dip 2024-05-28 10:08:03 -03:00 committed by GitHub
parent 1fd0e3796e
commit d98e1ecf27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -4,9 +4,9 @@ module.exports = {
friendlyName: 'Deliver Apple CSR',
description: 'Generate and deliver a signed certificate signing request to a requesting user\'s email address.',
description: 'Generate and optionally deliver a signed certificate signing request to a requesting user\'s email address.',
extendedDescription: 'Uses the mdm-gen-cert binary to generate a signed CSR for the user and sends the result to the requesting user\'s email address',
extendedDescription: 'Uses the mdm-gen-cert binary to generate a signed CSR for the user and optionally sends the result to the requesting user\'s email address',
inputs: {
@ -14,6 +14,12 @@ module.exports = {
required: true,
type: 'string',
description: 'Base64 encoded CSR submitted from the Fleet server or `fleetctl` on behalf of the user.'
},
deliveryMethod: {
type: 'string',
description: 'How the signed CSR will be delivered to the user. ',
defaultsTo: 'email',
isIn: ['email', 'json']
}
},
@ -21,7 +27,9 @@ module.exports = {
exits: {
success: {
description: 'Delivered email to specified email address with certificate signing request attached.'
description: 'Signed the provided CSR.',
outputType: {csr:'string'},
outputFriendlyName: 'Signed CSR',
},
invalidEmailDomain: {
@ -35,7 +43,7 @@ module.exports = {
},
fn: async function({unsignedCsrData}) {
fn: async function({unsignedCsrData, deliveryMethod}) {
let path = require('path');
let signingToolExists = await sails.helpers.fs.exists(path.resolve(sails.config.appPath, '.tools/mdm-gen-cert'));
@ -113,26 +121,42 @@ module.exports = {
organization: generateCertificateResult.org,
});
// Send an email to the user, with the result from the mdm-gen-cert command attached as a plain text file.
await sails.helpers.sendTemplateEmail.with({
to: generateCertificateResult.email,
subject: 'Your certificate signing request from Fleet',
from: sails.config.custom.fromEmailAddress,
fromName: sails.config.custom.fromName,
template: 'email-signed-csr-for-apns',
templateData: {},
attachments: [{
// When the file is provided as an attachment to the Sails helper, it
// gets decoded, since we need for the signed CSR to be delivered in
// base64 format, we doubly encode the contents before sending the
// email.
contentBytes: Buffer.from(generateCertificateResult.request).toString('base64'),
name: 'apple-apns-csr.txt',
type: 'text/plain',
}],
}).intercept((err)=>{
return new Error(`When trying to send a signed CSR to a user (${generateCertificateResult.email}), an error occured. Full error: ${err}`);
});
// respBody contains the raw response body content, it defaults to
// `undefined` as this was the default behavior of this endpoint before the
// 'deliveryMethod' parameter was introduced.
var respBody;
switch(deliveryMethod) {
case 'json':
this.res.type('application/json');
respBody = JSON.stringify({
csr: Buffer.from(generateCertificateResult.request).toString('base64'),
});
break;
case 'email':
// Send an email to the user, with the result from the mdm-gen-cert command attached as a plain text file.
await sails.helpers.sendTemplateEmail.with({
to: generateCertificateResult.email,
subject: 'Your certificate signing request from Fleet',
from: sails.config.custom.fromEmailAddress,
fromName: sails.config.custom.fromName,
template: 'email-signed-csr-for-apns',
templateData: {},
attachments: [{
// When the file is provided as an attachment to the Sails helper, it
// gets decoded, since we need for the signed CSR to be delivered in
// base64 format, we doubly encode the contents before sending the
// email.
contentBytes: Buffer.from(generateCertificateResult.request).toString('base64'),
name: 'apple-apns-csr.txt',
type: 'text/plain',
}],
}).intercept((err)=>{
return new Error(`When trying to send a signed CSR to a user (${generateCertificateResult.email}), an error occured. Full error: ${err}`);
});
break;
default:
throw 'badRequest';
}
// Send a message to Slack.
await sails.helpers.http.post(sails.config.custom.slackWebhookUrlForMDMSignups, {
@ -140,7 +164,7 @@ module.exports = {
});
return;
return respBody;
}
};