mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Merge pull request #1408 from Unleash/feat/init-client-tokens
Load Client Tokens From Environment on Startup
This commit is contained in:
commit
3910e23d2d
@ -18,7 +18,7 @@ test('should create default config', async () => {
|
|||||||
expect(config).toMatchSnapshot();
|
expect(config).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should add initApiToken from options', async () => {
|
test('should add initApiToken for admin token from options', async () => {
|
||||||
const token = {
|
const token = {
|
||||||
environment: '*',
|
environment: '*',
|
||||||
project: '*',
|
project: '*',
|
||||||
@ -52,7 +52,41 @@ test('should add initApiToken from options', async () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should add initApiToken from env var', async () => {
|
test('should add initApiToken for client token from options', async () => {
|
||||||
|
const token = {
|
||||||
|
environment: 'development',
|
||||||
|
project: 'default',
|
||||||
|
secret: 'default:development.some-random-string',
|
||||||
|
type: ApiTokenType.CLIENT,
|
||||||
|
username: 'admin',
|
||||||
|
};
|
||||||
|
const config = createConfig({
|
||||||
|
db: {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 4242,
|
||||||
|
user: 'unleash',
|
||||||
|
password: 'password',
|
||||||
|
database: 'unleash_db',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 4242,
|
||||||
|
},
|
||||||
|
authentication: {
|
||||||
|
initApiTokens: [token],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(config.authentication.initApiTokens).toHaveLength(1);
|
||||||
|
expect(config.authentication.initApiTokens[0].environment).toBe(
|
||||||
|
token.environment,
|
||||||
|
);
|
||||||
|
expect(config.authentication.initApiTokens[0].project).toBe(token.project);
|
||||||
|
expect(config.authentication.initApiTokens[0].type).toBe(
|
||||||
|
ApiTokenType.CLIENT,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should add initApiToken for admin token from env var', async () => {
|
||||||
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
|
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
|
||||||
|
|
||||||
const config = createConfig({
|
const config = createConfig({
|
||||||
@ -81,7 +115,7 @@ test('should add initApiToken from env var', async () => {
|
|||||||
delete process.env.INIT_ADMIN_API_TOKENS;
|
delete process.env.INIT_ADMIN_API_TOKENS;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should validate initApiToken from env var', async () => {
|
test('should validate initApiToken for admin token from env var', async () => {
|
||||||
process.env.INIT_ADMIN_API_TOKENS = 'invalidProject:*:some-token1';
|
process.env.INIT_ADMIN_API_TOKENS = 'invalidProject:*:some-token1';
|
||||||
|
|
||||||
expect(() => createConfig({})).toThrow(
|
expect(() => createConfig({})).toThrow(
|
||||||
@ -91,8 +125,19 @@ test('should validate initApiToken from env var', async () => {
|
|||||||
delete process.env.INIT_ADMIN_API_TOKENS;
|
delete process.env.INIT_ADMIN_API_TOKENS;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should validate initApiToken for client token from env var', async () => {
|
||||||
|
process.env.INIT_CLIENT_API_TOKENS = '*:*:some-token1';
|
||||||
|
|
||||||
|
expect(() => createConfig({})).toThrow(
|
||||||
|
'Client token cannot be scoped to all environments',
|
||||||
|
);
|
||||||
|
|
||||||
|
delete process.env.INIT_CLIENT_API_TOKENS;
|
||||||
|
});
|
||||||
|
|
||||||
test('should merge initApiToken from options and env vars', async () => {
|
test('should merge initApiToken from options and env vars', async () => {
|
||||||
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
|
process.env.INIT_ADMIN_API_TOKENS = '*:*.some-token1, *:*.some-token2';
|
||||||
|
process.env.INIT_CLIENT_API_TOKENS = 'default:development.some-token1';
|
||||||
const token = {
|
const token = {
|
||||||
environment: '*',
|
environment: '*',
|
||||||
project: '*',
|
project: '*',
|
||||||
@ -116,6 +161,66 @@ test('should merge initApiToken from options and env vars', async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(config.authentication.initApiTokens).toHaveLength(3);
|
expect(config.authentication.initApiTokens).toHaveLength(4);
|
||||||
|
delete process.env.INIT_CLIENT_API_TOKENS;
|
||||||
delete process.env.INIT_ADMIN_API_TOKENS;
|
delete process.env.INIT_ADMIN_API_TOKENS;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should add initApiToken for client token from env var', async () => {
|
||||||
|
process.env.INIT_CLIENT_API_TOKENS =
|
||||||
|
'default:development.some-token1, default:development.some-token2';
|
||||||
|
|
||||||
|
const config = createConfig({
|
||||||
|
db: {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 4242,
|
||||||
|
user: 'unleash',
|
||||||
|
password: 'password',
|
||||||
|
database: 'unleash_db',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 4242,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(config.authentication.initApiTokens).toHaveLength(2);
|
||||||
|
expect(config.authentication.initApiTokens[0].environment).toBe(
|
||||||
|
'development',
|
||||||
|
);
|
||||||
|
expect(config.authentication.initApiTokens[0].project).toBe('default');
|
||||||
|
expect(config.authentication.initApiTokens[0].type).toBe(
|
||||||
|
ApiTokenType.CLIENT,
|
||||||
|
);
|
||||||
|
expect(config.authentication.initApiTokens[0].secret).toBe(
|
||||||
|
'default:development.some-token1',
|
||||||
|
);
|
||||||
|
|
||||||
|
delete process.env.INIT_CLIENT_API_TOKENS;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should handle cases where no env var specified for tokens', async () => {
|
||||||
|
const token = {
|
||||||
|
environment: '*',
|
||||||
|
project: '*',
|
||||||
|
secret: '*:*.some-random-string',
|
||||||
|
type: ApiTokenType.ADMIN,
|
||||||
|
username: 'admin',
|
||||||
|
};
|
||||||
|
const config = createConfig({
|
||||||
|
db: {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 4242,
|
||||||
|
user: 'unleash',
|
||||||
|
password: 'password',
|
||||||
|
database: 'unleash_db',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 4242,
|
||||||
|
},
|
||||||
|
authentication: {
|
||||||
|
initApiTokens: [token],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(config.authentication.initApiTokens).toHaveLength(1);
|
||||||
|
});
|
||||||
|
@ -182,27 +182,39 @@ const formatServerOptions = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadInitApiTokens = () => {
|
const loadTokensFromString = (tokenString: String, tokenType: ApiTokenType) => {
|
||||||
if (process.env.INIT_ADMIN_API_TOKENS) {
|
if (!tokenString) {
|
||||||
const initApiTokens = process.env.INIT_ADMIN_API_TOKENS.split(/,\s?/);
|
|
||||||
const tokens = initApiTokens.map((secret) => {
|
|
||||||
const [project = '*', rest] = secret.split(':');
|
|
||||||
const [environment = '*'] = rest.split('.');
|
|
||||||
const token = {
|
|
||||||
createdAt: undefined,
|
|
||||||
project,
|
|
||||||
environment,
|
|
||||||
secret,
|
|
||||||
type: ApiTokenType.ADMIN,
|
|
||||||
username: 'admin',
|
|
||||||
};
|
|
||||||
validateApiToken(token);
|
|
||||||
return token;
|
|
||||||
});
|
|
||||||
return tokens;
|
|
||||||
} else {
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
const initApiTokens = tokenString.split(/,\s?/);
|
||||||
|
const tokens = initApiTokens.map((secret) => {
|
||||||
|
const [project = '*', rest] = secret.split(':');
|
||||||
|
const [environment = '*'] = rest.split('.');
|
||||||
|
const token = {
|
||||||
|
createdAt: undefined,
|
||||||
|
project,
|
||||||
|
environment,
|
||||||
|
secret,
|
||||||
|
type: tokenType,
|
||||||
|
username: 'admin',
|
||||||
|
};
|
||||||
|
validateApiToken(token);
|
||||||
|
return token;
|
||||||
|
});
|
||||||
|
return tokens;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadInitApiTokens = () => {
|
||||||
|
return [
|
||||||
|
...loadTokensFromString(
|
||||||
|
process.env.INIT_ADMIN_API_TOKENS,
|
||||||
|
ApiTokenType.ADMIN,
|
||||||
|
),
|
||||||
|
...loadTokensFromString(
|
||||||
|
process.env.INIT_CLIENT_API_TOKENS,
|
||||||
|
ApiTokenType.CLIENT,
|
||||||
|
),
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
||||||
|
@ -89,7 +89,7 @@ unleash.start(unleashOptions);
|
|||||||
```
|
```
|
||||||
The tokens can be of any API token type. Note that _admin_ tokens **must** target all environments and projects (i.e. use `'*'` for `environments` and `project` and start the secret with `*:*.`).
|
The tokens can be of any API token type. Note that _admin_ tokens **must** target all environments and projects (i.e. use `'*'` for `environments` and `project` and start the secret with `*:*.`).
|
||||||
|
|
||||||
You can also use the environment variable `INIT_ADMIN_API_TOKENS` to create API tokens on startup. This variable should be set to a comma-separated list of API tokens to initialize (for instance `*:*.some-random-string, *:*.some-other-token`). With the environment variable, all tokens will be created as admin tokens and Unleash will assign a username automatically.
|
You can also use the environment variables `INIT_ADMIN_API_TOKENS` or `INIT_CLIENT_API_TOKENS` to create API admin or client tokens on startup. Both variables require a comma-separated list of API tokens to initialize (for instance `*:*.some-random-string, *:*.some-other-token`). The tokens found in `INIT_ADMIN_API_TOKENS` and `INIT_CLIENT_API_TOKENS` will be created as admin and client tokens respectively and Unleash will assign a username automatically.
|
||||||
- **databaseUrl** - (_deprecated_) the postgres database url to connect to. Only used if _db_ object is not specified, and overrides the _db_ object and any environment variables that change parts of it (like `DATABASE_SSL`). Should include username/password. This value may also be set via the `DATABASE_URL` environment variable. Alternatively, if you would like to read the database url from a file, you may set the `DATABASE_URL_FILE` environment variable with the full file path. The contents of the file must be the database url exactly.
|
- **databaseUrl** - (_deprecated_) the postgres database url to connect to. Only used if _db_ object is not specified, and overrides the _db_ object and any environment variables that change parts of it (like `DATABASE_SSL`). Should include username/password. This value may also be set via the `DATABASE_URL` environment variable. Alternatively, if you would like to read the database url from a file, you may set the `DATABASE_URL_FILE` environment variable with the full file path. The contents of the file must be the database url exactly.
|
||||||
- **db** - The database configuration object taking the following properties:
|
- **db** - The database configuration object taking the following properties:
|
||||||
- _user_ - the database username (`DATABASE_USERNAME`)
|
- _user_ - the database username (`DATABASE_USERNAME`)
|
||||||
|
Loading…
Reference in New Issue
Block a user