diff --git a/src/main/kotlin/snc/openchargingnetwork/node/config/NodeProperties.kt b/src/main/kotlin/snc/openchargingnetwork/node/config/NodeProperties.kt index c8a22fe..5e2cd78 100644 --- a/src/main/kotlin/snc/openchargingnetwork/node/config/NodeProperties.kt +++ b/src/main/kotlin/snc/openchargingnetwork/node/config/NodeProperties.kt @@ -18,12 +18,15 @@ package snc.openchargingnetwork.node.config import org.springframework.boot.context.properties.ConfigurationProperties import snc.openchargingnetwork.node.tools.generateUUIDv4Token +import javax.annotation.PostConstruct @ConfigurationProperties("ocn.node") class NodeProperties { var apikey: String = generateUUIDv4Token() + var base64apiKey: String = ""; + var dev: Boolean = false var privateKey: String? = null @@ -55,4 +58,9 @@ class NodeProperties { var plannedPartySearchEnabled: Boolean = true var serviceInterfaceEnabled: Boolean = true + + @PostConstruct + fun init() { + base64apiKey = java.util.Base64.getEncoder().encodeToString(apikey.toByteArray()); + } } \ No newline at end of file diff --git a/src/main/kotlin/snc/openchargingnetwork/node/controllers/AdminController.kt b/src/main/kotlin/snc/openchargingnetwork/node/controllers/AdminController.kt index e25ad29..7c08a0c 100644 --- a/src/main/kotlin/snc/openchargingnetwork/node/controllers/AdminController.kt +++ b/src/main/kotlin/snc/openchargingnetwork/node/controllers/AdminController.kt @@ -41,7 +41,7 @@ class AdminController(private val platformRepo: PlatformRepository, private val properties: NodeProperties) { fun isAuthorized(authorization: String): Boolean { - return authorization == "Token ${properties.apikey}" + return authorization == "Token ${properties.apikey}" || authorization == "Bearer ${properties.base64apiKey}" } @GetMapping("/connection-status/{countryCode}/{partyID}") diff --git a/src/main/kotlin/snc/openchargingnetwork/node/models/ocpi/Commands.kt b/src/main/kotlin/snc/openchargingnetwork/node/models/ocpi/Commands.kt index 5b78e1c..263e9fc 100644 --- a/src/main/kotlin/snc/openchargingnetwork/node/models/ocpi/Commands.kt +++ b/src/main/kotlin/snc/openchargingnetwork/node/models/ocpi/Commands.kt @@ -45,6 +45,7 @@ data class StartSession(@JsonProperty("response_url") var responseURL: String, @JsonProperty("token") val token: Token, @JsonProperty("location_id") val locationID: String, @JsonProperty("evse_uid") val evseUID: String? = null, + @JsonProperty("connector_id") val connectorID: String? = null, @JsonProperty("authorization_reference") val authorizationReference: String? = null) data class StopSession(@JsonProperty("response_url") var responseURL: String, diff --git a/src/main/kotlin/snc/openchargingnetwork/node/services/HttpService.kt b/src/main/kotlin/snc/openchargingnetwork/node/services/HttpService.kt index 035e663..6e9c8bf 100644 --- a/src/main/kotlin/snc/openchargingnetwork/node/services/HttpService.kt +++ b/src/main/kotlin/snc/openchargingnetwork/node/services/HttpService.kt @@ -25,6 +25,7 @@ import snc.openchargingnetwork.node.models.* import snc.openchargingnetwork.node.models.exceptions.OcpiServerGenericException import snc.openchargingnetwork.node.models.exceptions.OcpiServerUnusableApiException import snc.openchargingnetwork.node.models.ocpi.* +import snc.openchargingnetwork.node.tools.generateUUIDv4Token import snc.openchargingnetwork.node.tools.urlJoin @@ -96,7 +97,11 @@ class HttpService { */ fun getVersions(url: String, authorization: String): List { try { - val response = khttp.get(url = url, headers = mapOf("Authorization" to "Token $authorization")) + val response = khttp.get(url = url, headers = mapOf( + "Authorization" to "Token $authorization", + "X-Correlation-ID" to generateUUIDv4Token(), + "X-Request-ID" to generateUUIDv4Token() + )) val body: OcpiResponse> = mapper.readValue(response.text) return if (response.statusCode == 200 && body.statusCode == 1000) { @@ -117,7 +122,11 @@ class HttpService { */ fun getVersionDetail(url: String, authorization: String): VersionDetail { try { - val response = khttp.get(url = url, headers = mapOf("Authorization" to "Token $authorization")) + val response = khttp.get(url = url, headers = mapOf( + "Authorization" to "Token $authorization", + "X-Correlation-ID" to generateUUIDv4Token(), + "X-Request-ID" to generateUUIDv4Token() + )) val body: OcpiResponse = mapper.readValue(response.text) return if (response.statusCode == 200 && body.statusCode == 1000) { diff --git a/src/test/kotlin/snc/openchargingnetwork/node/controllers/ocpi/v2_2/CredentialsControllerTest.kt b/src/test/kotlin/snc/openchargingnetwork/node/controllers/ocpi/v2_2/CredentialsControllerTest.kt index be27f15..b6b0c5c 100644 --- a/src/test/kotlin/snc/openchargingnetwork/node/controllers/ocpi/v2_2/CredentialsControllerTest.kt +++ b/src/test/kotlin/snc/openchargingnetwork/node/controllers/ocpi/v2_2/CredentialsControllerTest.kt @@ -185,7 +185,7 @@ class CredentialsControllerTest(@Autowired val mockMvc: MockMvc) { .header("Authorization", "Token ${platform.auth.tokenC}") .contentType(MediaType.APPLICATION_JSON) .content(jacksonObjectMapper().writeValueAsString(Credentials( - token = tokenB!!, + token = tokenB, url = versionsUrl, roles = listOf(role1, role2))))) .andExpect(status().isOk) diff --git a/src/test/kotlin/snc/openchargingnetwork/node/integration/AppInterfaceTest.kt b/src/test/kotlin/snc/openchargingnetwork/node/integration/AppInterfaceTest.kt deleted file mode 100644 index d9ca29b..0000000 --- a/src/test/kotlin/snc/openchargingnetwork/node/integration/AppInterfaceTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -package snc.openchargingnetwork.node.integration - -import org.awaitility.kotlin.await -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.springframework.http.HttpMethod -import snc.openchargingnetwork.node.integration.utils.* -import snc.openchargingnetwork.node.models.OcnServicePermission -import snc.openchargingnetwork.node.models.ocpi.InterfaceRole -import snc.openchargingnetwork.node.models.ocpi.ModuleID -import java.util.concurrent.TimeUnit - -class ServiceInterfaceTest { - - // TODO: integration test setup could be in an inheritable class - private lateinit var networkComponents: NetworkComponents - private lateinit var cpo1: TestCpo - private lateinit var cpo2: TestCpo - private lateinit var msp: TestMsp - - - @BeforeEach - fun bootStrap() { - networkComponents = setupNetwork(HubClientInfoParams()) - cpo1 = networkComponents.cpos[0] - cpo2 = networkComponents.cpos[1] - msp = networkComponents.msps.first() - } - - @AfterEach - fun stopTestParties() { - stopPartyServers(networkComponents) - } - - private fun seenByBothCpos(): Boolean { - val message = ReceivedMessage( - module = ModuleID.LOCATIONS, - interfaceRole = InterfaceRole.SENDER, - method = HttpMethod.GET, - sender = msp.party) - val cpo1Seen = cpo1.server.messageStore.contains(message) - val cpo2Seen = cpo2.server.messageStore.contains(message) - return cpo1Seen && cpo2Seen - } - - private fun testForwarding(recipient: TestCpo, service: TestCpo) { - service.server.setServicePermissions(listOf(OcnServicePermission.FORWARD_ALL)) - msp.server.agreeToServicePermissions(service.address) - msp.server.getLocation(recipient.party) - await.atMost(2L, TimeUnit.SECONDS).until { seenByBothCpos() } - } - - @Test - fun fowardsRequestToService_Local() { - testForwarding(recipient = cpo2, service = cpo1) - - } - - @Test - fun fowardsRequestToService_Remote() { - testForwarding(recipient = cpo1, service = cpo2) - } - -} \ No newline at end of file