Skip to content

Commit

Permalink
chore: auth unit tests (immich-app#13207)
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldietzler authored Oct 5, 2024
1 parent 0f3b8b6 commit 9d9bf1c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
54 changes: 53 additions & 1 deletion server/src/services/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Issuer, generators } from 'openid-client';
import { AuthDto, SignUpDto } from 'src/dtos/auth.dto';
import { UserMetadataEntity } from 'src/entities/user-metadata.entity';
import { UserEntity } from 'src/entities/user.entity';
import { AuthType } from 'src/enum';
import { AuthType, Permission } from 'src/enum';
import { IKeyRepository } from 'src/interfaces/api-key.interface';
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
import { IEventRepository } from 'src/interfaces/event.interface';
Expand Down Expand Up @@ -288,6 +288,17 @@ describe('AuthService', () => {
).rejects.toBeInstanceOf(UnauthorizedException);
});

it('should not accept a key on a non-shared route', async () => {
sharedLinkMock.getByKey.mockResolvedValue(sharedLinkStub.valid);
await expect(
sut.authenticate({
headers: { 'x-immich-share-key': 'key' },
queryParams: {},
metadata: { adminRoute: false, sharedLinkRoute: false, uri: 'test' },
}),
).rejects.toBeInstanceOf(ForbiddenException);
});

it('should not accept a key without a user', async () => {
sharedLinkMock.getByKey.mockResolvedValue(sharedLinkStub.expired);
userMock.get.mockResolvedValue(null);
Expand Down Expand Up @@ -397,6 +408,17 @@ describe('AuthService', () => {
expect(keyMock.getKey).toHaveBeenCalledWith('auth_token (hashed)');
});

it('should throw an error if api key has insufficient permissions', async () => {
keyMock.getKey.mockResolvedValue({ ...keyStub.admin, permissions: [] });
await expect(
sut.authenticate({
headers: { 'x-api-key': 'auth_token' },
queryParams: {},
metadata: { adminRoute: false, sharedLinkRoute: false, uri: 'test', permission: Permission.ASSET_READ },
}),
).rejects.toBeInstanceOf(ForbiddenException);
});

it('should return an auth dto', async () => {
keyMock.getKey.mockResolvedValue(keyStub.admin);
await expect(
Expand All @@ -422,6 +444,20 @@ describe('AuthService', () => {
});
});

describe('authorize', () => {
it('should fail if oauth is disabled', async () => {
systemMock.get.mockResolvedValue({ oauth: { enabled: false } });
await expect(sut.authorize({ redirectUri: 'https://demo.immich.app' })).rejects.toBeInstanceOf(
BadRequestException,
);
});

it('should authorize the user', async () => {
systemMock.get.mockResolvedValue(systemConfigStub.oauthWithMobileOverride);
await sut.authorize({ redirectUri: 'https://demo.immich.app' });
});
});

describe('callback', () => {
it('should throw an error if OAuth is not enabled', async () => {
await expect(sut.callback({ url: '' }, loginDetails)).rejects.toBeInstanceOf(BadRequestException);
Expand Down Expand Up @@ -479,6 +515,22 @@ describe('AuthService', () => {
expect(userMock.create).toHaveBeenCalledTimes(1);
});

// TODO write once oidc has been moved to a repo and can be mocked.
// it('should throw an error if user should be auto registered but the email claim does not exist', async () => {
// systemMock.get.mockResolvedValue(systemConfigStub.enabled);
// userMock.getByEmail.mockResolvedValue(null);
// userMock.getAdmin.mockResolvedValue(userStub.user1);
// userMock.create.mockResolvedValue(userStub.user1);
// sessionMock.create.mockResolvedValue(sessionStub.valid);

// await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).rejects.toBeInstanceOf(
// BadRequestException,
// );

// expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
// expect(userMock.create).toHaveBeenCalledTimes(1);
// });

for (const url of [
'app.immich:/',
'app.immich://',
Expand Down
4 changes: 0 additions & 4 deletions server/src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ export class AuthService extends BaseService {

async authorize(dto: OAuthConfigDto): Promise<OAuthAuthorizeResponseDto> {
const config = await this.getConfig({ withCache: false });
if (!config.oauth.enabled) {
throw new BadRequestException('OAuth is not enabled');
}

const client = await this.getOAuthClient(config);
const url = client.authorizationUrl({
redirect_uri: this.normalize(config, dto.redirectUri),
Expand Down

0 comments on commit 9d9bf1c

Please sign in to comment.