mirror of
https://github.com/fleetdm/fleet
synced 2026-04-26 16:07:21 +00:00
Related to: https://github.com/fleetdm/fleet/issues/40127 Changes: - Updated errors logged by Android proxy endpoints to include more information about the error. - Added a `deviceNoLongerManaged` exit to the `delete-android-device` endpoint that is used when the Google API returns a "Device is no longer being managed" error. - Added a `policyNotFound` exit to the `modify-android-policies` and `modify-enterprise-app-policy` endpoints that is used when the Google API returns a 404 response - Added a `invalidPolicyName` exit to the `modify-android-device` endpoint that is used when the Google API returns an error related to the policy name sent in the request body.
107 lines
4.1 KiB
JavaScript
Vendored
107 lines
4.1 KiB
JavaScript
Vendored
module.exports = {
|
|
|
|
|
|
friendlyName: 'Delete one android enterprise',
|
|
|
|
|
|
description: 'Deletes an android enterprise and the associated database record.',
|
|
|
|
|
|
inputs: {
|
|
androidEnterpriseId: {
|
|
type: 'string',
|
|
required: true,
|
|
},
|
|
},
|
|
|
|
|
|
exits: {
|
|
success: { description: 'An Android enterprise was successfully deleted.' },
|
|
missingAuthHeader: { description: 'This request was missing an authorization header.', responseType: 'unauthorized'},
|
|
unauthorized: { description: 'Invalid authentication token.', responseType: 'unauthorized'},
|
|
notFound: { description: 'No Android enterprise found for this Fleet server.', responseType: 'notFound'},
|
|
},
|
|
|
|
|
|
fn: async function ({androidEnterpriseId}) {
|
|
|
|
// Extract fleetServerSecret from the Authorization header
|
|
let authHeader = this.req.get('authorization');
|
|
let fleetServerSecret;
|
|
|
|
if (authHeader && authHeader.startsWith('Bearer')) {
|
|
fleetServerSecret = authHeader.replace('Bearer', '').trim();
|
|
} else {
|
|
throw 'missingAuthHeader';
|
|
}
|
|
|
|
// Look up the database record for this Android enterprise
|
|
let thisAndroidEnterprise = await AndroidEnterprise.findOne({
|
|
androidEnterpriseId: androidEnterpriseId,
|
|
});
|
|
|
|
// Return a 404 response if no records are found.
|
|
if(!thisAndroidEnterprise) {
|
|
throw 'notFound';
|
|
}
|
|
|
|
// Return an unauthorized response if the provided secret does not match.
|
|
if(thisAndroidEnterprise.fleetServerSecret !== fleetServerSecret) {
|
|
throw 'unauthorized';
|
|
}
|
|
|
|
// Delete the Android enterprise from Google (if it still exists)
|
|
// Note: If the enterprise is already deleted in Google, we still want to clean up proxy database
|
|
try {
|
|
await sails.helpers.flow.build(async ()=>{
|
|
let { google } = require('googleapis');
|
|
let androidmanagement = google.androidmanagement('v1');
|
|
let googleAuth = new google.auth.GoogleAuth({
|
|
scopes: [
|
|
'https://www.googleapis.com/auth/androidmanagement',
|
|
'https://www.googleapis.com/auth/pubsub'
|
|
],
|
|
credentials: {
|
|
client_email: sails.config.custom.androidEnterpriseServiceAccountEmailAddress,// eslint-disable-line camelcase
|
|
private_key: sails.config.custom.androidEnterpriseServiceAccountPrivateKey,// eslint-disable-line camelcase
|
|
},
|
|
});
|
|
// Acquire the google auth client, and bind it to all future calls
|
|
let authClient = await googleAuth.getClient();
|
|
google.options({auth: authClient});
|
|
// Delete the android enterprise.
|
|
await androidmanagement.enterprises.delete({
|
|
name: `enterprises/${androidEnterpriseId}`,
|
|
});
|
|
let pubsub = google.pubsub('v1');
|
|
// Delete the enterprise's pubsub topic
|
|
await pubsub.projects.topics.delete({
|
|
topic: thisAndroidEnterprise.pubsubTopicName,
|
|
});
|
|
// Delete the topic's subscription, which should have the same name as the topic.
|
|
await pubsub.projects.subscriptions.delete({
|
|
subscription: thisAndroidEnterprise.pubsubSubscriptionName,
|
|
});
|
|
return;
|
|
}).intercept({status: 429}, (err)=>{
|
|
// If the Android management API returns a 429 response, log an additional warning that will trigger a help-p1 alert.
|
|
sails.log.warn(`p1: Android management API rate limit exceeded! Error: ${require('util').inspect(err)}`);
|
|
return new Error(`When attempting to delete android enterprise from Google (${androidEnterpriseId}), an error occurred. Error: ${err}`);
|
|
}).intercept((err)=>{
|
|
return new Error(`When attempting to delete android enterprise from Google (${androidEnterpriseId}), an error occurred. Error: ${require('util').inspect(err)}`);
|
|
});
|
|
} catch (unusedErr) {
|
|
// If Google API deletion fails (e.g., enterprise already deleted), continue with proxy cleanup
|
|
}
|
|
|
|
// Delete the database record for this Android enterprise
|
|
await AndroidEnterprise.destroyOne({ id: thisAndroidEnterprise.id });
|
|
|
|
|
|
// All done. Send back an empty JSON object as expected by Android Management API.
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
};
|