-
-
Save alan89/1725860df7a0d28cc7732eae4894741b to your computer and use it in GitHub Desktop.
Script to delete Storage rulesets using the "firebaserules" REST API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const admin = require('firebase-admin'); | |
const {sleep} = require('sleep'); | |
// asumes the existance of the GOOGLE_APPLICATION_CREDENCIAL env variable | |
const firebaseApp = admin.initializeApp(); | |
async function getRulesets(projectId, firebaseApp, pageToken) { | |
pageToken = pageToken || ''; | |
let token = await firebaseApp.options.credential.getAccessToken(); | |
let accessToken = token.access_token; | |
let url = `https://firebaserules.googleapis.com/v1/projects/${projectId}/rulesets?pageToken=${pageToken}`; | |
const request = { | |
url: url, | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': `Bearer ${accessToken}` | |
}, | |
method: 'GET' | |
}; | |
let response = null; | |
try { | |
response = await firebaseApp.options.credential.credential_.httpClient.send(request); | |
} catch (err) { | |
console.error(err); | |
} | |
rules = response ? response.parsedData : {}; | |
return rules; | |
} // getRulesets | |
/** | |
* | |
* @param {Firebase App instance} firebaseApp | |
* @param {Ruleset name, as received in the JSON response} rulesetName | |
*/ | |
async function deleteRuleset(firebaseApp, rulesetName) { | |
if (!firebaseApp || !rulesetName) { | |
throw new Exception("firebaseApp and ruleset name required"); | |
} | |
let token = await firebaseApp.options.credential.getAccessToken(); | |
let accessToken = token.access_token; | |
let url = `https://firebaserules.googleapis.com/v1/${rulesetName}`; | |
const request = { | |
url: url, | |
headers: { | |
'Authorization': `Bearer ${accessToken}` | |
} | |
}; | |
let response = null; | |
try { | |
let result = await firebaseApp.options.credential.credential_.httpClient.send(request); | |
response = result.parsedData; | |
} catch (err) { | |
console.error(err); | |
} | |
return response; | |
} // deleteRuleset | |
// WARNING: deleting storage rulesets | |
// make sure to backup the current ruleset | |
(async () => { | |
// NOTE: set the Firebase projectId | |
const projectId = "YOUR_PROJECT_ID"; | |
let pageToken = null; | |
let pageCounter = 0; | |
let rulesCounter = 0; | |
while (true) { | |
// skip Firestore rulesets | |
let rules = await getRulesets(projectId, firebaseApp, pageToken); | |
if (rules.rulesets) { | |
pageCounter++; | |
for (let ruleset of rules.rulesets) { | |
//console.log(ruleset); | |
// we just remove the Storage rulesets | |
if (ruleset.metadata.services == 'firebase.storage') { | |
// we keep the first entry | |
if (rulesCounter > 0) { | |
console.log(`DELETING ${ruleset.name}`); | |
// WARNING: the following line will remove the entry from the history | |
// This cannot be undone, so make sure you have a backup of the Storage ruleset | |
let result = await deleteRuleset(firebaseApp, ruleset.name); | |
console.log(result); | |
// TODO: manage error states (like 429 on firebaserules.googleapis.com) | |
} | |
rulesCounter++; | |
} else { | |
console.log('...skipping Firestore ruleset...'); | |
} | |
} | |
pageToken = rules.nextPageToken || null; | |
} | |
if (!pageToken) { | |
// finish the cycle | |
break; | |
} | |
// small pause to avoid hitting a query limit | |
console.log(`---- 10s pause to prevent hitting limits ----`); | |
sleep(10); | |
} // while | |
console.log(`PAGES: ${pageCounter}`); | |
console.log(`DELETED STORAGE RULESETS: ${rulesCounter - 1}`); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "rulesets", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"firebase-admin": "^8.7.0", | |
"sleep": "^6.1.0", | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment