diff --git a/Dockerfile b/Dockerfile index d513791f7..55a6d87f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM maven:3-eclipse-temurin-11 as maven # Build the source using maven, source is copied from the 'repo' build. -ADD . /usr/src/OBP-API +COPY . /usr/src/OBP-API RUN cp /usr/src/OBP-API/obp-api/pom.xml /tmp/pom.xml # For Packaging a local repository within the image WORKDIR /usr/src/OBP-API RUN cp obp-api/src/main/resources/props/test.default.props.template obp-api/src/main/resources/props/test.default.props diff --git a/obp-api/src/main/docs/glossary/Dynamic_Resource_Doc.md b/obp-api/src/main/docs/glossary/Dynamic_Resource_Doc.md deleted file mode 100644 index e4cee481f..000000000 --- a/obp-api/src/main/docs/glossary/Dynamic_Resource_Doc.md +++ /dev/null @@ -1,14 +0,0 @@ - -In OBP we largely define our endpoints using an internal case class or model called ResourceDoc - -Using this endpoint, developers can create their own Resource Docs at run time thus creating fully featured -Open Bank Project style endpoints dynamically. - -In order to do this you need to prepare your desired Resource Doc as JSON. -The business logic code can be written in the *method_body* field as encoded Scala code. - -This feature is somewhat work in progress (WIP). - -The following videos are available: -* [Introduction to Dynamic Resource Docs] (https://vimeo.com/623381607) - diff --git a/obp-api/src/main/docs/glossary/OAuth_2.0_Client_Credentials_Flow_Manual.md b/obp-api/src/main/docs/glossary/OAuth_2.0_Client_Credentials_Flow_Manual.md deleted file mode 100644 index ef33be766..000000000 --- a/obp-api/src/main/docs/glossary/OAuth_2.0_Client_Credentials_Flow_Manual.md +++ /dev/null @@ -1,65 +0,0 @@ -# OAuth 2.0 Client Credentials Flow Manual - -## Overview -OAuth 2.0 Client Credentials Flow is used when a client application (such as a backend service) needs to authenticate and request access to resources without user interaction. This flow is typically used for machine-to-machine (M2M) authentication. - -## Prerequisites / Assumptions -Before making requests, ensure you have: -- A valid **client_id** and **client_secret**. -- This example assumes the authorization server (Keycloak) is running on **localhost:7070**. Replace this with the actual auth server URL. -- A realm needs to been configured (e.g. 'master') and respective endpoint available: `/realms/master/protocol/openid-connect/token`. - -## 1. Requesting an Access Token -To obtain an access token, send a **POST** request to the token endpoint with the following details. - -### **Request** -``` -POST /realms/master/protocol/openid-connect/token HTTP/1.1 -Host: localhost:7070 -Content-Type: application/x-www-form-urlencoded -Authorization: Basic Og== -Content-Length: 104 - -client_id=&client_secret=&grant_type=client_credentials -``` - -### **Explanation of Parameters** -| Parameter | Description | -|------------------|-------------| -| `client_id` | The unique identifier for your client application. | -| `client_secret` | The secret key assigned to your client. | -| `grant_type` | Must be set to `client_credentials` to indicate this authentication flow. | - -### **Example cURL Command** -```sh -curl -X POST "http://localhost:7070/realms/master/protocol/openid-connect/token" \ - -H "Content-Type: application/x-www-form-urlencoded" \ - -u "open-bank-project:WWJ04UzMhWmLEqW2KIgBHwD4UNEotzXz" \ - -d "grant_type=client_credentials" -``` - -## 2. Expected Response -A successful request will return a JSON response containing the access token: -```json -{ - "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", - "token_type": "Bearer", - "expires_in": 3600 -} -``` - -### **Response Fields** -| Field | Description | -|----------------|-------------| -| `access_token` | The token required to authenticate API requests. | -| `token_type` | Usually `Bearer`, meaning it should be included in the Authorization header. | -| `expires_in` | The token expiration time in seconds. | - -## 3. Using the Access Token -Once you obtain the access token, include it in the `Authorization` header of your subsequent API requests: - -### **Example API Request with Token** -```sh -curl -X GET "http://localhost:7070/protected/resource" \ - -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." -``` diff --git a/obp-api/src/main/docs/glossary/Run_via_IntelliJ_IDEA.md b/obp-api/src/main/docs/glossary/Run_via_IntelliJ_IDEA.md deleted file mode 100644 index a4e43f9b2..000000000 --- a/obp-api/src/main/docs/glossary/Run_via_IntelliJ_IDEA.md +++ /dev/null @@ -1,51 +0,0 @@ -## To run via IntelliJ IDEA - -* Make sure that Redis is running and properly configured if redis is not running without password protection on default port at localhost - -* Make sure you have the IntelliJ Scala plugin installed. - -* Create a new folder e.g. OpenBankProject and cd there - -* git clone https://github.com/OpenBankProject/OBP-API.git - -* In IntelliJ IDEA do File -> New -> Project from existing sources, navigate to the folder and IMPORTANTLY select pom.xml - -* Alternatively you can do File -> New -> Project from VCS and checkout the project directly from github. - -* When / if prompted for SDK, choose Java 11 (and Scala 2.12) otherwise keep the defaults. Use the Maven options. Do not change the project name etc. - -* If you see a message about an unmanaged pom.xml, click the option to let Maven manage it. - -* Navigate to obp-api/test/scala/code/RunWebApp. You may see a Setup Scala SDK link. Click this and check Scala 2.12.12 or so. - -* In obp-api/src/main/resources/props create a \.props (or default.props) for development. Set connector=mapped - -* Now **Rebuild** the project so everything is compiled. At this point you may need to select the SDK, see above. - -* Once you have rebuilt the project without compile errors, you should be able to RunWebApp/RunTLSWebApp/RunMTLSWebApp in obp-api/src/test/scala - -* If you have trouble (re)building, try using the IntelliJ IDEA terminal: mvn clean test-compile - -### To run via IntelliJ IDEA in development mode without secure connection - -* Run RunWebApp by right clicking on it or selecting Run. The built in jetty server should start on localhost:8080 - -* Browse to http://localhost:8080 but don't try anything else there yet. - -### To run via IntelliJ IDEA in TLS development mode (secure connection) - -* Run RunTLSWebApp by right clicking on it and selecting Run/Debug. The built in jetty server should start on localhost:8080 - -* Browse to https://localhost:8080 but don't try anything else there yet - -In `development` mode we use this option in order to try OpenID Connect functionality. I.e. redirect URI must be `https` one. - -### To run via IntelliJ IDEA in MTLS development mode (secure connection) - -* Run RunMTLSWebApp by right clicking on it and selecting Run/Debug. The built in jetty server should start on localhost:8080 - -* Import certificate obp-api/src/test/resources/cert/localhost_SAN_dns_ip.pfx into your browser. - -* Browse to https://localhost:8080 but don't try anything else there yet - -In `development` mode we use this option in order to try UK Open Banking APIs functionality where mutual TLS is part of that standard. diff --git a/obp-api/src/main/docs/glossary/TPP_Certificate_Verification.md b/obp-api/src/main/docs/glossary/TPP_Certificate_Verification.md deleted file mode 100644 index 099e740fa..000000000 --- a/obp-api/src/main/docs/glossary/TPP_Certificate_Verification.md +++ /dev/null @@ -1,87 +0,0 @@ -### TPP Certificate Verification - -The signing and verification flow of certificates for TPP requests is a follows: - -#### Generation of the Request by TPP - -**Step 1: Calculating the Hash for the Digest Field** - -* TPP creates the body of the request (e.g., JSON containing transaction or consent data). -* TPP applies the SHA-256 algorithm to the body of the request to generate a unique hash. -* The resulting hash is encoded in Base64 and placed in the request header under the `Digest` field. - -**Step 2: Creating the Signing String** - -* TPP prepares a signing string based on specific fields from the request header. -* The signing string is a concatenation of the values of the signed fields in a specific format. -* The order of the fields is critical and follows the specifications. - -**Step 3: Signing the Signing String** - -* TPP uses its RSA private key associated with its certificate to generate a digital signature. -* The signature is applied to the signing string using the RSA-SHA256 algorithm. -* The resulting digital signature is Base64-encoded and placed in the `Signature` field. - -**Step 4: Adding the Certificate to the TPP-Signature-Certificate Field** - -* TPP includes its public certificate in the request header under the `TPP-Signature-Certificate` field. -* The certificate is issued by a trusted certification authority (CA) and contains the TPP's public key. - -**Step 5: Sending the Request to OBP** - -* TPP sends the complete request, including the `Digest`, `Signature`, and `TPP-Signature-Certificate` headers, to the OBP endpoint. - ---- - -#### Verification of the Request by OBP - -**Step 1: Validating the TPP Certificate** - -* OBP verifies the TPP certificate included in the `TPP-Signature-Certificate` field.\ - Steps: - -1. Verify the certificate's trust chain up to a trusted certification authority. -2. Ensure the certificate is valid (not expired or revoked). -3. Confirm the certificate is issued for the appropriate usage (e.g., digital signatures for Open Banking), based on the information from the National Bank registry (e.g., certificate SN and CA found in the `Signature` field). - -* **Result**: If the certificate is valid, the TPP's identity is confirmed. - -**Step 2: Verifying the Signature in the `Signature` Field** - -* OBP extracts the fields included in the signing string based on the information in the `Signature` field. -* OBP recreates the signing string in the same format used by the TPP. -* OBP uses the public key from the certificate in the `TPP-Signature-Certificate` field to verify the signature in the `Signature` field. -* **Result**: If the signature is valid, the authenticity of the request is confirmed. - -**Step 3: Verifying the Hash in the `Digest` Field** - -* OBP computes its own SHA-256 hash of the received request body. -* The computed hash is compared with the value in the `Digest` header. -* **Result**: If the two hashes match, the integrity of the request body is confirmed. - -**Step 4: Authorizing the Request** - -* If all verifications (integrity, signature, and certificate) pass, OBP processes the request. -* Otherwise, the request is rejected with an error message (e.g., `401 Unauthorized` or `403 Forbidden`). - ---- - -#### Additional Details - -**How does OBP verify the signature in the `Signature` field?** - -1. **Extracts the public key from the `TPP-Signature-Certificate`**: - * OBP retrieves the certificate (`TPP-Signature-Certificate`) from the request header. - * From this certificate, OBP extracts the TPP's public key. -2. **Recreates the Signing String**: - * OBP analyzes the `Signature` header to identify the signed fields (e.g., `Digest`, `X-Request-ID`, `Date`, etc.). - * OBP recreates the signing string from the actual values of these fields in the specified order. -3. **Decodes the Signature**: - * OBP decodes the value in the `Signature.signature` field (the digital signature generated by TPP). - * Decoding is done using the public key extracted from the `TPP-Signature-Certificate` and the algorithm specified in `Signature.algorithm` (e.g., RSA-SHA256). -4. **Compares the Resulting Hash**: - * During decoding, OBP obtains a hash calculated by TPP at the time of signing. - * OBP compares this hash with the hash generated internally from the recreated signing string. -5. **Possible Outcomes**: - * If the hashes match, the signature is valid. - * If the hashes do not match, the signature is invalid, and the request is rejected. \ No newline at end of file diff --git a/obp-api/src/main/scala/code/api/util/Glossary.scala b/obp-api/src/main/scala/code/api/util/Glossary.scala index 5503931d3..8b1a84d39 100644 --- a/obp-api/src/main/scala/code/api/util/Glossary.scala +++ b/obp-api/src/main/scala/code/api/util/Glossary.scala @@ -3515,7 +3515,7 @@ object Glossary extends MdcLoggable { private def getListOfFiles(): List[File] = { val glossaryPath = new File(getClass.getResource("").toURI.toString.replaceFirst("target/.*", "").replace("file:", ""), - "src/main/docs/glossary") + "/src/main/resources/docs/glossary") logger.info(s"|---> Glossary path: $glossaryPath") if (glossaryPath.exists && glossaryPath.isDirectory) { @@ -3525,6 +3525,7 @@ object Glossary extends MdcLoggable { .filter(_.getName.endsWith(".md")) .toList } else { + logger.error(s"Do not have any files under glossary path ($glossaryPath), please double check the folder: obp-api/src/main/resources/docs/glossary") List.empty[File] } }