@backstage/backend-defaults
Version:
Backend defaults used by Backstage backend apps
141 lines (137 loc) • 4.74 kB
JavaScript
;
var errors = require('@backstage/errors');
var jose = require('jose');
var helpers = require('./helpers.cjs.js');
class DefaultAuthService {
userTokenHandler;
pluginTokenHandler;
externalTokenHandler;
pluginId;
disableDefaultAuthPolicy;
pluginKeySource;
constructor(userTokenHandler, pluginTokenHandler, externalTokenHandler, pluginId, disableDefaultAuthPolicy, pluginKeySource) {
this.userTokenHandler = userTokenHandler;
this.pluginTokenHandler = pluginTokenHandler;
this.externalTokenHandler = externalTokenHandler;
this.pluginId = pluginId;
this.disableDefaultAuthPolicy = disableDefaultAuthPolicy;
this.pluginKeySource = pluginKeySource;
}
async authenticate(token, options) {
const pluginResult = await this.pluginTokenHandler.verifyToken(token);
if (pluginResult) {
if (pluginResult.limitedUserToken) {
const userResult2 = await this.userTokenHandler.verifyToken(
pluginResult.limitedUserToken
);
if (!userResult2) {
throw new errors.AuthenticationError(
"Invalid user token in plugin token obo claim"
);
}
return helpers.createCredentialsWithUserPrincipal(
userResult2.userEntityRef,
pluginResult.limitedUserToken,
this.#getJwtExpiration(pluginResult.limitedUserToken),
pluginResult.subject
);
}
return helpers.createCredentialsWithServicePrincipal(pluginResult.subject);
}
const userResult = await this.userTokenHandler.verifyToken(token);
if (userResult) {
if (!options?.allowLimitedAccess && this.userTokenHandler.isLimitedUserToken(token)) {
throw new errors.AuthenticationError("Illegal limited user token");
}
return helpers.createCredentialsWithUserPrincipal(
userResult.userEntityRef,
token,
this.#getJwtExpiration(token)
);
}
const externalResult = await this.externalTokenHandler.verifyToken(token);
if (externalResult) {
return helpers.createCredentialsWithServicePrincipal(
externalResult.subject,
void 0,
externalResult.accessRestrictions
);
}
throw new errors.AuthenticationError("Illegal token");
}
isPrincipal(credentials, type) {
const principal = credentials.principal;
if (type === "unknown") {
return true;
}
if (principal.type !== type) {
return false;
}
return true;
}
async getNoneCredentials() {
return helpers.createCredentialsWithNonePrincipal();
}
async getOwnServiceCredentials() {
return helpers.createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`);
}
async getPluginRequestToken(options) {
const { targetPluginId } = options;
const internalForward = helpers.toInternalBackstageCredentials(options.onBehalfOf);
const { type } = internalForward.principal;
if (type === "none" && this.disableDefaultAuthPolicy) {
return { token: "" };
}
switch (type) {
// TODO: Check whether the principal is ourselves
case "service":
return this.pluginTokenHandler.issueToken({
pluginId: this.pluginId,
targetPluginId
});
case "user": {
const { token } = internalForward;
if (!token) {
throw new Error("User credentials is unexpectedly missing token");
}
const onBehalfOf = await this.userTokenHandler.createLimitedUserToken(
token
);
return this.pluginTokenHandler.issueToken({
pluginId: this.pluginId,
targetPluginId,
onBehalfOf: {
limitedUserToken: onBehalfOf.token,
expiresAt: onBehalfOf.expiresAt
}
});
}
default:
throw new errors.AuthenticationError(
`Refused to issue service token for credential type '${type}'`
);
}
}
async getLimitedUserToken(credentials) {
const { token: backstageToken } = helpers.toInternalBackstageCredentials(credentials);
if (!backstageToken) {
throw new errors.AuthenticationError(
"User credentials is unexpectedly missing token"
);
}
return this.userTokenHandler.createLimitedUserToken(backstageToken);
}
async listPublicServiceKeys() {
const { keys } = await this.pluginKeySource.listKeys();
return { keys: keys.map(({ key }) => key) };
}
#getJwtExpiration(token) {
const { exp } = jose.decodeJwt(token);
if (!exp) {
throw new errors.AuthenticationError("User token is missing expiration");
}
return new Date(exp * 1e3);
}
}
exports.DefaultAuthService = DefaultAuthService;
//# sourceMappingURL=DefaultAuthService.cjs.js.map