mirror of
https://github.com/graphql-hive/console
synced 2026-05-23 09:08:34 +00:00
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com>
161 lines
5 KiB
TypeScript
161 lines
5 KiB
TypeScript
import { TargetAccessScope, ProjectType } from '@app/gql/graphql';
|
|
import {
|
|
createOrganization,
|
|
joinOrganization,
|
|
createProject,
|
|
createToken,
|
|
updateMemberAccess,
|
|
inviteToOrganization,
|
|
readTokenInfo,
|
|
} from '../../../testkit/flow';
|
|
import { authenticate } from '../../../testkit/auth';
|
|
|
|
test('setting no scopes equals to readonly for organization, project, target', async () => {
|
|
const { access_token: owner_access_token } = await authenticate('main');
|
|
const orgResult = await createOrganization(
|
|
{
|
|
name: 'foo',
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
|
|
|
|
const projectResult = await createProject(
|
|
{
|
|
organization: org.cleanId,
|
|
type: ProjectType.Single,
|
|
name: 'foo',
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
const project = projectResult.body.data!.createProject.ok!.createdProject;
|
|
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
|
|
|
|
// member should not have access to target:registry:write
|
|
const tokenResult = await createToken(
|
|
{
|
|
name: 'test',
|
|
organization: org.cleanId,
|
|
project: project.cleanId,
|
|
target: target.cleanId,
|
|
organizationScopes: [],
|
|
projectScopes: [],
|
|
targetScopes: [],
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
expect(tokenResult.body.errors).not.toBeDefined();
|
|
const secret = tokenResult.body.data?.createToken.ok?.secret;
|
|
expect(secret).toBeDefined();
|
|
|
|
const tokenInfoResult = await readTokenInfo(secret!);
|
|
expect(tokenInfoResult.body.errors).not.toBeDefined();
|
|
|
|
if (tokenInfoResult.body.data?.tokenInfo.__typename === 'TokenNotFoundError') {
|
|
throw new Error('Token not found');
|
|
}
|
|
|
|
const tokenInfo = tokenInfoResult.body.data?.tokenInfo;
|
|
// organization
|
|
expect(tokenInfo?.hasOrganizationRead).toBe(true);
|
|
expect(tokenInfo?.hasOrganizationDelete).toBe(false);
|
|
expect(tokenInfo?.hasOrganizationIntegrations).toBe(false);
|
|
expect(tokenInfo?.hasOrganizationMembers).toBe(false);
|
|
expect(tokenInfo?.hasOrganizationSettings).toBe(false);
|
|
// project
|
|
expect(tokenInfo?.hasProjectRead).toBe(true);
|
|
expect(tokenInfo?.hasProjectDelete).toBe(false);
|
|
expect(tokenInfo?.hasProjectAlerts).toBe(false);
|
|
expect(tokenInfo?.hasProjectOperationsStoreRead).toBe(false);
|
|
expect(tokenInfo?.hasProjectOperationsStoreWrite).toBe(false);
|
|
expect(tokenInfo?.hasProjectSettings).toBe(false);
|
|
// target
|
|
expect(tokenInfo?.hasTargetRead).toBe(true);
|
|
expect(tokenInfo?.hasTargetDelete).toBe(false);
|
|
expect(tokenInfo?.hasTargetSettings).toBe(false);
|
|
expect(tokenInfo?.hasTargetRegistryRead).toBe(false);
|
|
expect(tokenInfo?.hasTargetRegistryWrite).toBe(false);
|
|
expect(tokenInfo?.hasTargetTokensRead).toBe(false);
|
|
expect(tokenInfo?.hasTargetTokensWrite).toBe(false);
|
|
});
|
|
|
|
test('cannot set a scope on a token if user has no access to that scope', async () => {
|
|
const { access_token: owner_access_token } = await authenticate('main');
|
|
const orgResult = await createOrganization(
|
|
{
|
|
name: 'foo',
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
// Join
|
|
const { access_token: member_access_token } = await authenticate('extra');
|
|
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
|
|
|
|
const invitationResult = await inviteToOrganization(
|
|
{
|
|
email: 'some@email.com',
|
|
organization: org.cleanId,
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
const inviteCode = invitationResult.body.data?.inviteToOrganizationByEmail.ok?.code;
|
|
expect(inviteCode).toBeDefined();
|
|
|
|
const joinResult = await joinOrganization(inviteCode!, member_access_token);
|
|
|
|
const projectResult = await createProject(
|
|
{
|
|
organization: org.cleanId,
|
|
type: ProjectType.Single,
|
|
name: 'foo',
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
if (joinResult.body.data!.joinOrganization.__typename !== 'OrganizationPayload') {
|
|
throw new Error(`Join failed: ${joinResult.body.data!.joinOrganization.message}`);
|
|
}
|
|
|
|
const member = joinResult.body.data!.joinOrganization.organization.me;
|
|
const project = projectResult.body.data!.createProject.ok!.createdProject;
|
|
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
|
|
|
|
// Give access to tokens
|
|
await updateMemberAccess(
|
|
{
|
|
organization: org.cleanId,
|
|
organizationScopes: [],
|
|
projectScopes: [],
|
|
targetScopes: [
|
|
TargetAccessScope.Read,
|
|
TargetAccessScope.RegistryRead,
|
|
TargetAccessScope.TokensRead,
|
|
TargetAccessScope.TokensWrite,
|
|
],
|
|
user: member.id,
|
|
},
|
|
owner_access_token,
|
|
);
|
|
|
|
// member should not have access to target:registry:write
|
|
const tokenResult = await createToken(
|
|
{
|
|
name: 'test',
|
|
organization: org.cleanId,
|
|
project: project.cleanId,
|
|
target: target.cleanId,
|
|
organizationScopes: [],
|
|
projectScopes: [],
|
|
targetScopes: [TargetAccessScope.RegistryWrite],
|
|
},
|
|
member_access_token,
|
|
);
|
|
|
|
expect(tokenResult.body.errors).toHaveLength(1);
|
|
expect(tokenResult.body.errors![0].message).toMatch('target:registry:write');
|
|
});
|