diff --git a/README_did_web.md b/README_did_web.md
new file mode 100644
index 000000000..9a3d3b32b
--- /dev/null
+++ b/README_did_web.md
@@ -0,0 +1,191 @@
+# !!! Under Contruction !!!
+
+# Managed Identity Wallets
+
+The Managed Identity Wallets (MIW) service implements the Self-Sovereign-Identity (SSI)
+readiness by providing a wallet hosting platform including a DID resolver,
+service endpoints and the company wallets itself.
+
+> **Warning**
+> Heavily under development
+>
+# Developer Documentation
+
+To run MIW locally, this section describes the tooling as well as
+the local development setup.
+
+## Tooling
+To be added
+
+## Environment Variables
+
+| name | description | default value |
+|----------------------------|-----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|
+| APPLICATION_PORT | port number of application | 8087 |
+| APPLICATION_ENVIRONMENT | Environment of the application ie. local, dev, int and prod | local |
+| DB_HOST | Database host | localhost |
+| DB_PORT | Port of database | 5432 |
+| DB_NAME | Database name | miw |
+| USE_SSL | Whether SSL is enabled in database server | false |
+| DB_USER_NAME | Database username | |
+| DB_PASSWORD | Database password | |
+| DB_POOL_SIZE | Max number of database connection acquired by application | 10 |
+| KEYCLOAK_MIW_PUBLIC_CLIENT | Only needed if we want enable login with keyalock in swagger | miw_public |
+| MANAGEMENT_PORT | Spring actuator port | 8090 |
+| MIW_HOST_NAME | Application host name, this will be used in creation of did ie. did:web:MIW_HOST_NAME:BPN | localhost |
+| ENCRYPTION_KEY | encryption key used to encrypt and decrypt private and public key of wallet | |
+| AUTHORITY_WALLET_BPN | base wallet BPN number | BPNL000000000000 |
+| AUTHORITY_WALLET_NAME | Base wallet name | Catena-X |
+| AUTHORITY_WALLET_DID | Base wallet web did | web:did:host:BPNL000000000000 |
+| VC_SCHEMA_LINK | Comma separated list of VC schema URL | https://www.w3.org/2018/credentials/v1, https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData |
+| VC_EXPIRY_DATE | Expiry date of VC (dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC) | 01-01-2025 |
+| KEYCLOAK_REALM | Realm name of keycloak | miw_test |
+| KEYCLOAK_CLIENT_ID | Keycloak private client id | |
+| AUTH_SERVER_URL | Keycloak server url | |
+| | | |
+## Local Development Setup
+
+*Work in progress*
+
+## Setup Summary
+
+| Service | URL | Description |
+|-----------------------|-------------------------|-------------|
+| postgreSQL database | port 5432 on `localhost`| within the Docker Compose setup |
+| Keycloak | http://localhost:8081/ | within the Docker Compose setup, username: `admin` and password: `changeme`, client id: `ManagedIdentityWallets` and client secret can be found under the Clients > ManagedIdentityWallets > Credentials |
+| MIW service | http://localhost:8080/ | |
+
+
+# Administrator Documentation
+
+## Manual Keycloak Configuration
+
+Within the development setup the Keycloak is initially prepared with the
+values in `./dev-assets/dev-containers/keycloak`. The realm could also be
+manually added and configured at http://localhost:8081 via the "Add realm"
+button. It can be for example named `localkeycloak`. Also add an additional client,
+e.g. named `ManagedIdentityWallets` with *valid redirect url* set to
+`http://localhost:8080/*`. The roles
+ * add_wallets
+ * view_wallets
+ * update_wallets
+ * delete_wallets
+ * view_wallet
+ * update_wallet
+can be added under *Clients > ManagedIdentityWallets > Roles* and then
+assigned to the client using *Clients > ManagedIdentityWallets > Client Scopes*
+*> Service Account Roles > Client Roles > ManagedIdentityWallets*. The
+available scopes/roles are:
+
+1. Role `add_wallets` to create a new wallet
+
+1. Role `view_wallets`:
+ * to get a list of all wallets
+ * to retrieve one wallet by its identifier
+ * to validate a Verifiable Presentation
+ * to get all stored Verifiable Credentials
+
+1. Role `update_wallets` for the following actions:
+ * to store Verifiable Credential
+ * to set the wallet DID to public on chain
+ * to issue a Verifiable Credential
+ * to issue a Verifiable Presentation
+ * to add, update and delete service endpoint of DIDs
+ * to trigger the update of Business Partner Data of all existing wallets
+
+1. Role `delete_wallets` to remove a wallet
+
+1. Role `view_wallet` requires the BPN of Caller and it can be used:
+ * to get the Wallet of the related BPN
+ * to get stored Verifiable Credentials of the related BPN
+ * to validate any Verifiable Presentation
+
+1. Role `update_wallet` requires the BPN of Caller and it can be used:
+ * to issue Verifiable Credentials (The BPN of issuer will be checked)
+ * to issue Verifiable Presentations (The BPN of holder will be checked)
+ * to store Verifiable Credentials (The BPN of holder will be checked)
+ * to trigger Business Partner Data update for its own BPN
+
+Additionally a Token mapper can to be created under *Clients* >
+*ManagedIdentityWallets* > *Mappers* > *create* with the following
+configuration (using as example `BPNL000000001`):
+
+| Key | Value |
+|---------------------|---------------------------|
+| Name | StaticBPN |
+| Mapper Type | Hardcoded claim |
+| Token Claim Name | BPN |
+| Claim value | BPNL000000001 |
+| Claim JSON Type | String |
+| Add to ID token | OFF |
+| Add to access token | ON |
+| Add to userinfo | OFF |
+| includeInAccessTokenResponse.label | ON |
+
+If you receive an error message, that the client secret is not valid, please go into
+keycloak admin and within *Clients > Credentials* recreate the secret.
+
+
+## Local docker deployment
+
+First step is to create the distribution of the application:
+
+```bash
+./gradlew installDist
+```
+
+Next step is to build and tag the Docker image, replacing the
+`` with the app version:
+
+```
+docker build -t managed-identity-wallets: .
+```
+
+Finally, start the image (please make sure that there are no quotes around the
+values in the env file):
+
+```
+docker run --env-file .env.docker -p 8080:8080 managed-identity-wallets:
+```
+
+## Deployment on Kubernetes
+
+*Work in progress*
+
+# End Users
+
+See OpenAPI documentation, which is automatically created from
+the source and available on each deployment at the `/docs` endpoint
+(e.g. locally at http://localhost:8080/docs).
+
+
+## Test Coverage
+
+Jacoco is used to generate the coverage report. The report generation
+and the coverage verification are automatically executed after tests.
+
+The generated HTML report can be found under `jacoco-report/html/`
+
+To generate the report run the command
+
+```
+./gradlew jacocoTestReport
+```
+
+To check the coverage run the command
+
+```
+./gradlew jacocoTestCoverageVerification
+```
+
+Currently the minimum is 80%
+
+Files to be excluded from the coverage calculation can be set in
+`gradle.properties` using a comma-separated list of files or directories
+with possible wildcards as the value for the property `coverage_excludes`.
+The files in `models` and `entities` should be excluded as long as they
+don't have any logic. The services that are mocked in unit tests must be
+excluded. Also their interfaces need to be excluded because they have a
+`companion object` that is used to create those services. Files like
+`Application.kt` which are tested or simulated indirectly for example
+using `withTestApplication` should also be excluded.
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/CredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/CredentialController.java
index 89fb4cd79..5f3343ead 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/CredentialController.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/CredentialController.java
@@ -63,12 +63,12 @@ public class CredentialController extends BaseController {
*/
@Operation(description = "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", summary = "Query Verifiable Credentials")
@GetMapping(path = RestURI.CREDENTIALS, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity> getCredentials(@RequestParam(required = false) String id,
+ public ResponseEntity> getCredentials(@RequestParam(required = false) String credentialId,
@RequestParam(required = false) String issuerIdentifier,
@RequestParam(required = false) List type,
@RequestParam(required = false, defaultValue = "createdAt") String sortColumn,
@RequestParam(required = false, defaultValue = "desc") String sortTpe, Principal principal) {
- return ResponseEntity.status(HttpStatus.OK).body(service.getCredentials(id, issuerIdentifier, type, sortColumn, sortTpe, getBPNFromToken(principal)));
+ return ResponseEntity.status(HttpStatus.OK).body(service.getCredentials(credentialId, issuerIdentifier, type, sortColumn, sortTpe, getBPNFromToken(principal)));
}
/**
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Credential.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Credential.java
index f0a72315b..d1888dc0a 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Credential.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Credential.java
@@ -58,4 +58,7 @@ public class Credential extends MIWBaseEntity {
@Column(nullable = false)
@Convert(converter = StringToCredentialConverter.class)
private VerifiableCredential data;
+
+ @Column(nullable = false)
+ private String credentialId;
}
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java
index 879b42f72..370f7b696 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java
@@ -87,7 +87,7 @@ protected SpecificationUtil getSpecificationUtil() {
/**
* Gets credentials.
*
- * @param id the id
+ * @param credentialId the credentialId
* @param issuerIdentifier the issuer identifier
* @param type the type
* @param sortColumn the sort column
@@ -95,7 +95,7 @@ protected SpecificationUtil getSpecificationUtil() {
* @param callerBPN the caller bpn
* @return the credentials
*/
- public List getCredentials(String id, String issuerIdentifier, List type, String sortColumn, String sortType, String callerBPN) {
+ public List getCredentials(String credentialId, String issuerIdentifier, List type, String sortColumn, String sortType, String callerBPN) {
FilterRequest filterRequest = new FilterRequest();
@@ -107,6 +107,10 @@ public List getCredentials(String id, String issuerIdentif
filterRequest.appendNewCriteria("issuerDid", Operator.EQUALS, issuerWallet.getDid());
}
+ if (StringUtils.hasText(credentialId)) {
+ filterRequest.appendNewCriteria("credentialId", Operator.EQUALS, credentialId);
+ }
+
if (!CollectionUtils.isEmpty(type)) {
filterRequest.appendNewCriteria("type", Operator.IN, type);
}
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java
index a881f2c7f..c4c7e63ae 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java
@@ -46,12 +46,10 @@
import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl;
import org.springframework.stereotype.Service;
+import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* The type Presentation service.
@@ -127,8 +125,8 @@ public Map createPresentation(Map data, boolean
//Build JWT
SignedJWT presentation = presentationFactory.createPresentation(
issuerDid, verifiableCredentials, audience, walletKeyService.getEd25519Key(holderWallet.getId()));
-
- response.put("vp", presentation);
+
+ response.put("vp", presentation.serialize());
} else {
VerifiablePresentationBuilder verifiablePresentationBuilder =
new VerifiablePresentationBuilder();
@@ -136,7 +134,7 @@ public Map createPresentation(Map data, boolean
// Build VP
VerifiablePresentation verifiablePresentation =
verifiablePresentationBuilder
- .id(issuerDid.toUri())
+ .id(URI.create(UUID.randomUUID().toString()))
.type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION))
.verifiableCredentials(verifiableCredentials)
.build();
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java
index e8018959e..af847f950 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java
@@ -136,6 +136,7 @@ public Map storeCredential(Map data, String iden
.issuerDid(URLDecoder.decode(verifiableCredential.getIssuer().toString(), Charset.defaultCharset()))
.type(verifiableCredential.getTypes().get(0))
.data(verifiableCredential)
+ .credentialId(verifiableCredential.getId().toString())
.build());
return Map.of("message", String.format("Credential with id %s has been successfully stored", verifiableCredential.getId()));
}
diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java
index 445df4358..2cb021e90 100644
--- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java
+++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java
@@ -87,6 +87,7 @@ public static Credential getCredential(Map subject, String type,
.holderDid(holderDid)
.issuerDid(issuerDid)
.type(type)
+ .credentialId(verifiableCredential.getId().toString())
.data(verifiableCredential)
.build();
}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index ef773d810..db7af002a 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -1,17 +1,17 @@
server:
- port: ${APPLICATION_PORT:8087}
+ port: ${APPLICATION_PORT:8080}
shutdown: graceful
compression:
enabled: true
spring:
profiles:
- active: ${APPLICATION_ENVIRONMENT:dev}
+ active: ${APPLICATION_ENVIRONMENT:local}
liquibase:
change-log: classpath:/db/changelog/changelog-master.xml
application:
- name: ${APPLICATION_NAME:miw}
+ name: miw
datasource:
- url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5433}/${DB_NAME:miw}?useSSL=${USE_SSL:false}
+ url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:miw}?useSSL=${USE_SSL:false}
username: ${DB_USER_NAME:root}
password: ${DB_PASSWORD:smart}
initialization-mode: always
@@ -60,7 +60,7 @@ management:
enabled: true
miw:
- host: ${HOST_NAME:localhost}
+ host: ${MIW_HOST_NAME:localhost}
encryptionKey: ${ENCRYPTION_KEY:Woh9waid4Ei5eez0aitieghoow9so4oe}
authorityWalletBpn: ${AUTHORITY_WALLET_BPN:BPNL000000000000}
authorityWalletName: ${AUTHORITY_WALLET_NAME:Catena-X}
diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql
index aa933e5b1..b491937ca 100644
--- a/src/main/resources/db/changelog/changes/init.sql
+++ b/src/main/resources/db/changelog/changes/init.sql
@@ -38,6 +38,7 @@ CREATE TABLE public.credential (
id bigserial NOT NULL,
holder_did varchar(255) NOT NULL,
issuer_did varchar(255) NOT NULL,
+ credential_id varchar(255) NOT NULL,
"data" text NOT NULL,
"type" varchar(255) NULL,
created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,