Skip to content

Instantly share code, notes, and snippets.

@matthewgream
Created October 14, 2023 11:20
Show Gist options
  • Save matthewgream/cbcc605d21c84fda432be479ed0bf526 to your computer and use it in GitHub Desktop.
Save matthewgream/cbcc605d21c84fda432be479ed0bf526 to your computer and use it in GitHub Desktop.
// -----------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------
const GCLOUD_DEFAULT_CONFIG = {
'location': 'us-central1',
'project' : APPLICATION_PROJECT,
'service' : APPLICATION_NAME + '-appsscript-app',
'jobname' : APPLICATION_NAME + '-appsscript-job',
'storage' : APPLICATION_NAME + '-appsscript-bld',
'handler' : APPLICATION_URL,
'options' : { 'profiling': 0 },
'appnode' : '20',
'appdeps' : { '@google-cloud/profiler': '^5.0.4', 'adm-zip': '^0.5.10' },
'appconf' : { 'memory': '2048', 'timeout': '1800' }
}
// -----------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------
function gcloud_access_test () { __TEST_SETUP ();
debugLog (gcloud_auth_token_header ());
debugLog (util_date_string_niceSecs ((gcloud_auth_token_expiry () - Date.now ())/ 1000));
const jwt = new JsonWebToken ('https://oauth2.googleapis.com/token', CLOUD_DEFAULT_AUTH_EMAIL, CLOUD_DEFAULT_AUTH_KEY, CLOUD_DEFAULT_AUTH_SCOPES);
debugLog (jwt.token);
debugLog ([jwt.expiry, jwt.expiry - Date.now (), util_date_string_niceSecs ((jwt.expiry - Date.now ())/ 1000)]);
}
// -----------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------
class JsonWebTokenRequest {
constructor (url, client_email, private_key, scopes) { Object.assign (this, { url, client_email, private_key, scopes }); }
__base64fix (s) { return s.replace ('+', '-').replace ('/', '_').replace (/=+$/, ''); }
__jwtEncode (s) { return this.__base64fix (util_base64_encode (s)) }
__jwtHeader () { return this.__jwtEncode (JSON.stringify ({ alg: 'RS256', typ: 'JWT' })); }
__jwtPayload (url, email, scopes) { const t = Math.floor (Date.now () / 1000); return this.__jwtEncode (JSON.stringify ({ iss: email, scope: scopes, aud: url, exp: t + 3600, iat: t })); }
__jwtSigned (header, payload, key) { return this.__base64fix (util_base64_encode (util_sign_rsasha256 ([header, payload].join ('.'), key))); }
_grant_type () { return 'urn:ietf:params:oauth:grant-type:jwt-bearer'; }
_assertion () { const h = this.__jwtHeader (), p = this.__jwtPayload (this.url, this.client_email, this.scopes); return [h, p, this.__jwtSigned (h, p, this.private_key)].join ('.'); }
payload () { return { grant_type: this._grant_type (), assertion: this._assertion () }; }
}
class JsonWebToken {
constructor (url, client_email, private_key, scopes) {
const response = connect_urlResponseJson ('JsonWebToken', url, { method: 'POST',
payload: JSON.stringify ((new JsonWebTokenRequest (url, client_email, private_key, util_array_always (scopes).join (' '))).payload ()) });
this.token = response.access_token, this.expiry = Date.now () + (response.expires_in * 1000);
}
}
// -----------------------------------------------------------------------------------------------------------------------------------------
function __gcloud_auth_token_cached_key (scopes, client_email) {
return ['jwtToken', client_email, scopes.join (';')].join ('/'); }
function __gcloud_auth_token_cached_token (scopes, client_email) {
const data = cache2.read (__gcloud_auth_token_cached_key (scopes, client_email)); return data ? JSON.parse (data) : undefined; }
function __gcloud_auth_token_cached_expiry (scopes, client_email) {
return __gcloud_auth_token_cached_token (scopes, client_email)?.expiry; }
function __gcloud_auth_token_cached_or_renewed (scopes, client_email, private_key) { var jwt;
if (!(jwt = __gcloud_auth_token_cached_token (scopes, client_email)) || jwt?.expiry < Date.now () || !jwt?.token) {
jwt = new JsonWebToken ('https://oauth2.googleapis.com/token', client_email, private_key, scopes);
cache2.write (__gcloud_auth_token_cached_key (scopes, client_email), JSON.stringify ({ token: jwt.token, expiry: jwt.expiry - (5 * 60 * 1000) }));
}
return jwt?.token;
}
// -----------------------------------------------------------------------------------------------------------------------------------------
function gcloud_auth_header_bearer (token) {
return { 'Authorization': 'Bearer ' + token };
}
function gcloud_auth_token_expiry (scopes = CLOUD_DEFAULT_AUTH_SCOPES, client_email = CLOUD_DEFAULT_AUTH_EMAIL) {
return __gcloud_auth_token_cached_expiry (scopes, client_email);
}
function gcloud_auth_token_header (scopes = CLOUD_DEFAULT_AUTH_SCOPES, client_email = CLOUD_DEFAULT_AUTH_EMAIL, private_key = CLOUD_DEFAULT_AUTH_KEY) {
return gcloud_auth_header_bearer (__gcloud_auth_token_cached_or_renewed (scopes, client_email, private_key));
}
// -----------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------
const __gcloud_path = (project, location) => `projects/${project}/locations/${location}/`;
const __gcloud_request = (path, method = 'GET', payload = undefined) =>
connect_urlResponseJson ('cloud_api', path, connect_urlResponseJson_payloadInsert ({ method, headers: gcloud_auth_token_header () }, payload));
const __gcloud_request_media_get = (path, method = 'GET', type) =>
connect_urlResponseRaw ('cloud_api', path, { method, headers: gcloud_auth_token_header () }, type);
const __gcloud_request_media_put = (path, method = 'POST', payload = undefined, type = 'application/octet-stream') =>
connect_urlResponseJson ('cloud_api', path, { method, headers: { ...gcloud_auth_token_header (), 'Content-Type': type }, payload });
const __gcloud_request_paged__encode_path = ([path, opts], para) => [util_str_url_args_append (path, para), opts];
const __gcloud_request_paged = (path, request = (path, method, opts) => __gcloud_request (path, method, opts.payload), callback = (page, x) => [...x, page], x = Array (),
pageSize = 1000, method = 'GET', opts = {}, f_encode = __gcloud_request_paged__encode_path) => {
var page, pageToken = undefined; do { [path, opts] = f_encode ([path, opts], { pageSize, pageToken }); page = request (path, method, opts);
} while (!util_is_null (page) && !util_is_null (x = callback (page, x)) && !util_is_null (pageToken = page.nextPageToken)); return x;
}
// -----------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment