mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 10:32:40 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { test } = require('node:test');
|
||||
|
||||
const {
|
||||
LocalOwnerPepperKeyringFileProvider,
|
||||
provisionLocalOwnerPepperKey,
|
||||
} = require('@qinglong/local-owner-console/pepper-custody');
|
||||
const {
|
||||
apiCredentialSecretDigest,
|
||||
formatApiCredentialToken,
|
||||
} = require('@qinglong/runtime-core/api-credential-token');
|
||||
const {
|
||||
LocalApiCredentialAuthenticationUnavailableError,
|
||||
createLocalApiCredentialAuthenticator,
|
||||
} = require('../dist/authentication/credentialAuthenticator.js');
|
||||
|
||||
const NOW = 1_800_000_000_000;
|
||||
const CREDENTIAL_ID = 'local-api-owner';
|
||||
const PEPPER_KEY_ID = 'owner-pepper-v1';
|
||||
const SECRET = Buffer.alloc(32, 42).toString('base64url');
|
||||
const PEPPER = Buffer.alloc(32, 43).toString('base64url');
|
||||
const TOKEN = formatApiCredentialToken(CREDENTIAL_ID, SECRET);
|
||||
|
||||
function fixture(t) {
|
||||
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-api-auth-'));
|
||||
fs.chmodSync(directory, 0o700);
|
||||
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
||||
const summary = provisionLocalOwnerPepperKey({
|
||||
keyringDirectory: directory,
|
||||
pepperKeyId: PEPPER_KEY_ID,
|
||||
randomBytes: () => Buffer.alloc(32, 43),
|
||||
});
|
||||
const credential = {
|
||||
credentialId: CREDENTIAL_ID,
|
||||
version: 1,
|
||||
pepperKeyId: PEPPER_KEY_ID,
|
||||
state: 'active',
|
||||
subject: { type: 'user', id: 'user-local-api' },
|
||||
subjectStatus: 'active',
|
||||
secretDigest: apiCredentialSecretDigest(
|
||||
PEPPER,
|
||||
CREDENTIAL_ID,
|
||||
SECRET,
|
||||
),
|
||||
createdAtMs: NOW - 1_000,
|
||||
notBeforeAtMs: NOW - 1_000,
|
||||
expiresAtMs: NOW + 60_000,
|
||||
};
|
||||
const pepperKey = {
|
||||
pepperKeyId: PEPPER_KEY_ID,
|
||||
materialDigest: summary.digest,
|
||||
backupDigest: 'b'.repeat(64),
|
||||
state: 'active',
|
||||
version: 2,
|
||||
registeredAtMs: NOW - 2_000,
|
||||
activatedAtMs: NOW - 1_500,
|
||||
};
|
||||
const authority = {
|
||||
profile: 'edge',
|
||||
runs: {},
|
||||
apiCredentials: {
|
||||
async resolve(credentialId) {
|
||||
return credentialId === CREDENTIAL_ID ? { ...credential } : null;
|
||||
},
|
||||
},
|
||||
ownerPepper: {
|
||||
async resolveKey(pepperKeyId) {
|
||||
return pepperKeyId === PEPPER_KEY_ID ? { ...pepperKey } : null;
|
||||
},
|
||||
},
|
||||
projectPolicy: {},
|
||||
securityAudit: {},
|
||||
};
|
||||
return {
|
||||
authority,
|
||||
credential,
|
||||
pepperKey,
|
||||
provider: new LocalOwnerPepperKeyringFileProvider(directory),
|
||||
};
|
||||
}
|
||||
|
||||
test('authenticates one exact Bearer credential and re-confirms its authority fence', async (t) => {
|
||||
const value = fixture(t);
|
||||
const authenticator = createLocalApiCredentialAuthenticator(
|
||||
value.authority,
|
||||
value.provider,
|
||||
{ now: () => NOW },
|
||||
);
|
||||
assert.equal(await authenticator.authenticate(`Basic ${TOKEN}`), null);
|
||||
assert.equal(await authenticator.authenticate('Bearer malformed'), null);
|
||||
|
||||
const authentication = await authenticator.authenticate(`Bearer ${TOKEN}`);
|
||||
assert.deepEqual(authentication.principal.subject, {
|
||||
type: 'user',
|
||||
id: 'user-local-api',
|
||||
});
|
||||
await authentication.confirm();
|
||||
});
|
||||
|
||||
test('fails closed when credential or pepper authority changes after audit', async (t) => {
|
||||
const value = fixture(t);
|
||||
const authenticator = createLocalApiCredentialAuthenticator(
|
||||
value.authority,
|
||||
value.provider,
|
||||
{ now: () => NOW },
|
||||
);
|
||||
const credentialRevoked = await authenticator.authenticate(`Bearer ${TOKEN}`);
|
||||
value.credential.state = 'revoked';
|
||||
await assert.rejects(
|
||||
credentialRevoked.confirm(),
|
||||
LocalApiCredentialAuthenticationUnavailableError,
|
||||
);
|
||||
|
||||
value.credential.state = 'active';
|
||||
const pepperChanged = await authenticator.authenticate(`Bearer ${TOKEN}`);
|
||||
value.pepperKey.materialDigest = 'f'.repeat(64);
|
||||
await assert.rejects(
|
||||
pepperChanged.confirm(),
|
||||
LocalApiCredentialAuthenticationUnavailableError,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user