mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Let CredentialsExtractors specify what type of Credentials they generate
This commit is contained in:
@@ -4,12 +4,10 @@ import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { HttpRequest } from '../server/HttpRequest';
|
||||
import { BadRequestHttpError } from '../util/errors/BadRequestHttpError';
|
||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||
import type { Credentials } from './Credentials';
|
||||
import { CredentialGroup } from './Credentials';
|
||||
import type { CredentialSet } from './Credentials';
|
||||
import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
|
||||
/**
|
||||
* Credentials extractor that extracts a WebID from a Bearer access token.
|
||||
*/
|
||||
export class BearerWebIdExtractor extends CredentialsExtractor {
|
||||
protected readonly logger = getLoggerFor(this);
|
||||
private readonly verify: SolidTokenVerifierFunction;
|
||||
@@ -26,13 +24,13 @@ export class BearerWebIdExtractor extends CredentialsExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
public async handle(request: HttpRequest): Promise<Credentials> {
|
||||
public async handle(request: HttpRequest): Promise<CredentialSet> {
|
||||
const { headers: { authorization }} = request;
|
||||
|
||||
try {
|
||||
const { webid: webId } = await this.verify(authorization!);
|
||||
this.logger.info(`Verified WebID via Bearer access token: ${webId}`);
|
||||
return { webId };
|
||||
return { [CredentialGroup.agent]: { webId }};
|
||||
} catch (error: unknown) {
|
||||
const message = `Error verifying WebID via Bearer access token: ${(error as Error).message}`;
|
||||
this.logger.warn(message);
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
/**
|
||||
* Credentials identifying an entity accessing or owning data.
|
||||
*/
|
||||
export interface Credentials {
|
||||
export interface Credential {
|
||||
webId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific groups that can have credentials.
|
||||
*/
|
||||
export enum CredentialGroup {
|
||||
public = 'public',
|
||||
agent = 'agent',
|
||||
}
|
||||
|
||||
/**
|
||||
* A combination of multiple credentials, where their group is specified by the key.
|
||||
*/
|
||||
export type CredentialSet = Partial<Record<CredentialGroup, Credential>>;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { HttpRequest } from '../server/HttpRequest';
|
||||
import { AsyncHandler } from '../util/handlers/AsyncHandler';
|
||||
import type { Credentials } from './Credentials';
|
||||
import type { CredentialSet } from './Credentials';
|
||||
|
||||
/**
|
||||
* Responsible for extracting credentials from an incoming request.
|
||||
*/
|
||||
export abstract class CredentialsExtractor extends AsyncHandler<HttpRequest, Credentials> {}
|
||||
export abstract class CredentialsExtractor extends AsyncHandler<HttpRequest, CredentialSet> {}
|
||||
|
||||
@@ -5,7 +5,8 @@ import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { HttpRequest } from '../server/HttpRequest';
|
||||
import { BadRequestHttpError } from '../util/errors/BadRequestHttpError';
|
||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||
import type { Credentials } from './Credentials';
|
||||
import { CredentialGroup } from './Credentials';
|
||||
import type { CredentialSet } from './Credentials';
|
||||
import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,7 @@ export class DPoPWebIdExtractor extends CredentialsExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
public async handle(request: HttpRequest): Promise<Credentials> {
|
||||
public async handle(request: HttpRequest): Promise<CredentialSet> {
|
||||
const { headers: { authorization, dpop }, method } = request;
|
||||
if (!dpop) {
|
||||
throw new BadRequestHttpError('No DPoP header specified.');
|
||||
@@ -53,7 +54,7 @@ export class DPoPWebIdExtractor extends CredentialsExtractor {
|
||||
},
|
||||
);
|
||||
this.logger.info(`Verified WebID via DPoP-bound access token: ${webId}`);
|
||||
return { webId };
|
||||
return { [CredentialGroup.agent]: { webId }};
|
||||
} catch (error: unknown) {
|
||||
const message = `Error verifying WebID via DPoP-bound access token: ${(error as Error).message}`;
|
||||
this.logger.warn(message);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { HttpRequest } from '../server/HttpRequest';
|
||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||
import type { Credentials } from './Credentials';
|
||||
import { CredentialGroup } from './Credentials';
|
||||
import type { CredentialSet } from './Credentials';
|
||||
import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
|
||||
/**
|
||||
@@ -14,7 +15,7 @@ export class EmptyCredentialsExtractor extends CredentialsExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
public async handle(): Promise<Credentials> {
|
||||
return {};
|
||||
public async handle(): Promise<CredentialSet> {
|
||||
return { [CredentialGroup.public]: {}};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { Credentials } from './Credentials';
|
||||
import { CredentialGroup } from './Credentials';
|
||||
import type { Credential, CredentialSet } from './Credentials';
|
||||
import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
|
||||
/**
|
||||
@@ -7,18 +8,18 @@ import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
* (useful for development or debugging purposes).
|
||||
*/
|
||||
export class UnsecureConstantCredentialsExtractor extends CredentialsExtractor {
|
||||
private readonly agent: Credentials;
|
||||
private readonly credentials: CredentialSet;
|
||||
private readonly logger = getLoggerFor(this);
|
||||
|
||||
public constructor(agent: string);
|
||||
public constructor(agent: Credentials);
|
||||
public constructor(agent: string | Credentials) {
|
||||
public constructor(agent: Credential);
|
||||
public constructor(agent: string | Credential) {
|
||||
super();
|
||||
this.agent = typeof agent === 'string' ? { webId: agent } : agent;
|
||||
this.credentials = { [CredentialGroup.agent]: typeof agent === 'string' ? { webId: agent } : agent };
|
||||
}
|
||||
|
||||
public async handle(): Promise<Credentials> {
|
||||
this.logger.info(`Agent unsecurely claims to be ${this.agent.webId}`);
|
||||
return this.agent;
|
||||
public async handle(): Promise<CredentialSet> {
|
||||
this.logger.info(`Agent unsecurely claims to be ${this.credentials.agent!.webId}`);
|
||||
return this.credentials;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { HttpRequest } from '../server/HttpRequest';
|
||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
||||
import type { Credentials } from './Credentials';
|
||||
import { CredentialGroup } from './Credentials';
|
||||
import type { CredentialSet } from './Credentials';
|
||||
import { CredentialsExtractor } from './CredentialsExtractor';
|
||||
|
||||
/**
|
||||
@@ -17,9 +18,9 @@ export class UnsecureWebIdExtractor extends CredentialsExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
public async handle({ headers }: HttpRequest): Promise<Credentials> {
|
||||
public async handle({ headers }: HttpRequest): Promise<CredentialSet> {
|
||||
const webId = /^WebID\s+(.*)/u.exec(headers.authorization!)![1];
|
||||
this.logger.info(`Agent unsecurely claims to be ${webId}`);
|
||||
return { webId };
|
||||
return { [CredentialGroup.agent]: { webId }};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user