-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Identity Hub participant and participants implementation (#351)
* chore: download multiple openapi specs * feat: identity hub participant and participants contollers * fix: review requests * fix: testcontainer file name * fix: add base path constant * fix: pull request comments
- Loading branch information
1 parent
a8e3f77
commit eba0c0e
Showing
11 changed files
with
458 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,27 @@ | ||
const fs = require('fs/promises'); | ||
const fs = require(`fs/promises`); | ||
|
||
const folder = "node_modules"; | ||
|
||
const context = "management-api"; | ||
const resourceUrl = `https://eclipse-edc.github.io/Connector/openapi/${context}/${context}.yaml`; | ||
const CONTEXTS = [ | ||
{ | ||
name: "management-api", | ||
resourceUrl: "https://eclipse-edc.github.io/Connector/openapi/management-api/management-api.yaml" | ||
}, | ||
{ | ||
name: "identity-api", | ||
resourceUrl: "https://eclipse-edc.github.io/IdentityHub/openapi/identity-api/identity-api.yaml" | ||
} | ||
] | ||
|
||
fetch(resourceUrl) | ||
.then(response => { | ||
if (!response.ok) { | ||
throw new Error(`Failed to download ${context} openapi spec`); | ||
} | ||
return response.text() | ||
}) | ||
.then(text => text | ||
.replaceAll("example: null", "") | ||
.replaceAll("https://w3id.org/edc/v0.0.1/ns/value", "value")) // to make "secrets" test working, will be fixed in the future | ||
.then(text => fs.writeFile(`${folder}/${context}.yml`, text)) | ||
.catch(error => { | ||
console.error('Error downloading openapi specs:', error); | ||
}) | ||
Promise.all(CONTEXTS.map((context) => | ||
fetch(context.resourceUrl) | ||
.then(response => { | ||
if (!response.ok) { | ||
throw new Error(`Failed to download ${context.name} openapi spec`); | ||
} | ||
return response.text() | ||
}) | ||
.then(text => fs.writeFile(`${folder}/${context.name}.yml`, text)) | ||
.catch(error => { | ||
console.error(`Error downloading openapi specs for ${context.name}:`, error); | ||
}))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/controllers/identity-controllers/participant-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { EdcConnectorClientContext } from "../../context"; | ||
import { | ||
ParticipantInput, | ||
ParticipantRoleResponse, | ||
} from "../../entities/participant"; | ||
import { Inner } from "../../inner"; | ||
|
||
export class ParticipantController { | ||
#inner: Inner; | ||
#context?: EdcConnectorClientContext; | ||
static readonly BASE_PATH = "/v1alpha/participants"; | ||
|
||
constructor( | ||
inner: Inner, | ||
public participantId: string, | ||
context?: EdcConnectorClientContext, | ||
) { | ||
this.#inner = inner; | ||
this.#context = context; | ||
} | ||
|
||
async delete(context?: EdcConnectorClientContext) { | ||
const actualContext = context || this.#context!; | ||
|
||
return this.#inner.request<string>(actualContext.identity, { | ||
path: `${ParticipantController.BASE_PATH}/${this.participantId}`, | ||
method: "DELETE", | ||
apiToken: actualContext.apiToken, | ||
}); | ||
} | ||
|
||
updateRoles(roles: string[], context?: EdcConnectorClientContext) { | ||
const actualContext = context || this.#context!; | ||
|
||
return this.#inner.request<ParticipantRoleResponse[]>( | ||
actualContext.identity, | ||
{ | ||
path: `${ParticipantController.BASE_PATH}/${this.participantId}/roles`, | ||
method: "PUT", | ||
body: roles, | ||
apiToken: actualContext.apiToken, | ||
}, | ||
); | ||
} | ||
|
||
updateState( | ||
isActive: boolean, | ||
input: Omit<ParticipantInput, "participantId">, | ||
context?: EdcConnectorClientContext, | ||
) { | ||
const actualContext = context || this.#context!; | ||
// to be fixed in docs | ||
const body: ParticipantInput = { | ||
...input, | ||
participantId: this.participantId, | ||
}; | ||
|
||
return this.#inner.request<string>(actualContext.identity, { | ||
path: `${ParticipantController.BASE_PATH}/${this.participantId}/state`, | ||
method: "POST", | ||
query: { isActive: String(isActive) }, | ||
body, | ||
apiToken: actualContext.apiToken, | ||
}); | ||
} | ||
|
||
regenerateToken( | ||
input: Omit<ParticipantInput, "participantId">, | ||
context?: EdcConnectorClientContext, | ||
) { | ||
const actualContext = context || this.#context!; | ||
|
||
// to be fixed in docs | ||
const body: ParticipantInput = { | ||
...input, | ||
participantId: this.participantId, | ||
}; | ||
|
||
return this.#inner.request<string>(actualContext.identity, { | ||
path: `${ParticipantController.BASE_PATH}/${this.participantId}/token`, | ||
method: "POST", | ||
body, | ||
apiToken: actualContext.apiToken, | ||
}); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/controllers/identity-controllers/participants-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { EdcConnectorClientContext } from "../../context"; | ||
import { Participant, ParticipantInput } from "../../entities/participant"; | ||
import { Inner } from "../../inner"; | ||
|
||
export class ParticipantsController { | ||
#inner: Inner; | ||
#context?: EdcConnectorClientContext; | ||
static readonly BASE_PATH = "/v1alpha/participants"; | ||
|
||
constructor(inner: Inner, context?: EdcConnectorClientContext) { | ||
this.#inner = inner; | ||
this.#context = context; | ||
} | ||
|
||
async queryAll( | ||
query: { offset?: string; limit?: string } = {}, | ||
context?: EdcConnectorClientContext, | ||
) { | ||
const actualContext = context || this.#context!; | ||
|
||
return this.#inner.request<Participant[]>(actualContext.identity, { | ||
path: ParticipantsController.BASE_PATH, | ||
method: "GET", | ||
apiToken: actualContext.apiToken, | ||
query, | ||
}); | ||
} | ||
|
||
async create(input: ParticipantInput, context?: EdcConnectorClientContext) { | ||
const actualContext = context || this.#context!; | ||
|
||
return this.#inner.request<{ | ||
apiKey: string; | ||
clientId: string; | ||
clientSecret: string; | ||
}>(actualContext.identity, { | ||
path: ParticipantsController.BASE_PATH, | ||
method: "POST", | ||
apiToken: actualContext.apiToken, | ||
body: input, | ||
}); | ||
} | ||
|
||
async get(participantId: number, context?: EdcConnectorClientContext) { | ||
const actualContext = context || this.#context!; | ||
|
||
return this.#inner.request<Participant>(actualContext.identity, { | ||
path: `${ParticipantsController.BASE_PATH}/${participantId}`, | ||
method: "GET", | ||
apiToken: actualContext.apiToken, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
export interface Participant { | ||
apiTokenAlias: string; | ||
createdAt: number; | ||
did: string; | ||
lastModified: number; | ||
participantContextId: string; | ||
roles: string[]; | ||
state: number; | ||
} | ||
|
||
export interface ParticipantInput { | ||
active: boolean; | ||
additionalProperties: { | ||
[key: string]: unknown; | ||
}; | ||
did: string; | ||
key: { | ||
active: boolean; | ||
keyGeneratorParams: { | ||
[key: string]: unknown; | ||
}; | ||
keyId: string; | ||
privateKeyAlias: string; | ||
publicKeyJwk: { | ||
[key: string]: unknown; | ||
}; | ||
publicKeyPem: string; | ||
resourceId: string; | ||
type: string; | ||
}; | ||
participantId: string; | ||
roles: string[]; | ||
serviceEndpoints: { | ||
id: string; | ||
serviceEndpoint: string; | ||
type: string; | ||
}[]; | ||
} | ||
|
||
export interface ParticipantRoleResponse { | ||
invalidValue: Record<string, unknown>; | ||
message: string; | ||
path: string; | ||
type: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { ParticipantController } from "../controllers/identity-controllers/participant-controller"; | ||
import { ParticipantsController } from "../controllers/identity-controllers/participants-controller"; | ||
import { EdcController } from "../edc-controller"; | ||
|
||
export class IdentityController extends EdcController { | ||
get participants() { | ||
return new ParticipantsController(this.inner, this.context); | ||
} | ||
|
||
participant(participantId: string) { | ||
return new ParticipantController(this.inner, participantId, this.context); | ||
} | ||
} |
Oops, something went wrong.