Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
40f4cbc
Add ngsiv2 client
ushios Apr 26, 2025
892f0cc
Add client
ushios Apr 26, 2025
55e6bf5
test passed
ushios Apr 26, 2025
c95efd0
Add set fiware service method
ushios Apr 26, 2025
ee2fcf0
using apiClient
ushios Apr 26, 2025
3c53a80
set base path and host
ushios Apr 26, 2025
c96dec4
multi tenant not now
ushios Apr 26, 2025
069dc92
test works
ushios Apr 26, 2025
1dc1f90
add new constructo
ushios Apr 27, 2025
b5f32d2
update readme
ushios Apr 27, 2025
360e8ea
add client
ushios Apr 27, 2025
5dcb5ac
add first test
ushios Apr 27, 2025
7509b3c
Add ci test
ushios Apr 27, 2025
3bb3c60
Add readme
ushios Apr 27, 2025
d974934
Revert "add first test"
ushios Apr 27, 2025
b030bed
Add test
ushios Apr 27, 2025
3ebf505
Add test
ushios Apr 27, 2025
85a0d98
Add set token adn more
ushios Apr 27, 2025
7f9e90e
using srp auth
ushios Apr 28, 2025
8366b9a
add srp auth progress
ushios Apr 28, 2025
0682a59
add test
ushios Apr 28, 2025
d976829
challenged
ushios Apr 28, 2025
c86619f
move file
ushios Apr 29, 2025
118d819
remove password
ushios Apr 29, 2025
df6ff9e
remove password
ushios Apr 29, 2025
ee10444
remove password
ushios Apr 29, 2025
2ff796b
Using useIdFroSRP
ushios Apr 29, 2025
a3871e3
add poolid to hash
ushios Apr 29, 2025
c3aae6c
update hash funcs
ushios Apr 29, 2025
cff5f43
almost hash and crypt calc was correct
ushios Apr 30, 2025
cb80009
worked!
ushios Apr 30, 2025
efe5a37
Add new classes
ushios May 1, 2025
7d57688
worked
ushios May 1, 2025
ab8107b
worked
ushios May 2, 2025
2dd5fd4
worked
ushios May 2, 2025
b998dc4
Merge pull request #2 from makeOurCity/feature/ngsv2-client-srp
ushios May 2, 2025
bbe3fed
Update src/main/java/city/makeour/moc/auth/srp/SmallG.java
ushios May 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ root = true

[*]
indent_style = space
indent_size = 4
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

[*.xml]
indent_size = 2
[*.java]
indent_size = 4
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Java CI with Maven

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: "17"
distribution: "temurin"
cache: maven

- name: Run tests with Maven
run: mvn -B test --file pom.xml
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# MoC Java
MoC client for Java

[![Java CI with Maven](https://github.com/makeOurCity/moc-java/actions/workflows/test.yml/badge.svg)](https://github.com/makeOurCity/moc-java/actions/workflows/test.yml)
57 changes: 49 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>


<groupId>city.makeour</groupId>
<artifactId>moc</artifactId>
Expand All @@ -14,22 +15,57 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-sdk-java</artifactId>
<artifactId>cognitoidentityprovider</artifactId>
<version>2.31.20</version>
</dependency>
<dependency>
<groupId>com.github.makeOurCity</groupId>
<artifactId>ngsiv2-java</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
</dependencies>

<build>
Expand All @@ -51,7 +87,12 @@
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<version>3.5.3</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
Expand All @@ -77,4 +118,4 @@
</plugins>
</pluginManagement>
</build>
</project>
</project>
71 changes: 0 additions & 71 deletions src/main/java/city/makeour/FetchCognitoToken.java

This file was deleted.

96 changes: 96 additions & 0 deletions src/main/java/city/makeour/moc/FetchCognitoToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package city.makeour.moc;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import city.makeour.moc.auth.srp.SrpAuthenticationHelper;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient;
import software.amazon.awssdk.services.cognitoidentityprovider.model.AuthFlowType;
import software.amazon.awssdk.services.cognitoidentityprovider.model.AuthenticationResultType;
import software.amazon.awssdk.services.cognitoidentityprovider.model.ChallengeNameType;
import software.amazon.awssdk.services.cognitoidentityprovider.model.InitiateAuthRequest;
import software.amazon.awssdk.services.cognitoidentityprovider.model.InitiateAuthResponse;
import software.amazon.awssdk.services.cognitoidentityprovider.model.RespondToAuthChallengeRequest;
import software.amazon.awssdk.services.cognitoidentityprovider.model.RespondToAuthChallengeResponse;

public class FetchCognitoToken implements TokenFetcherInterface {

private String cognitoUserPoolId;
private String cognitoClientId;
private String username;
private String password;
private Region region = Region.AP_NORTHEAST_1;

private SrpAuthenticationHelper helper;
private CognitoIdentityProviderClient cognitoClient;

public FetchCognitoToken(String cognitoUserPoolId, String cognitoClientId) {
this(Region.AP_NORTHEAST_1, cognitoUserPoolId, cognitoClientId);
}

public FetchCognitoToken(Region region, String cognitoUserPoolId, String cognitoClientId) {
this.cognitoUserPoolId = cognitoUserPoolId;
this.cognitoClientId = cognitoClientId;
this.region = region;

this.helper = new SrpAuthenticationHelper(this.cognitoUserPoolId);

this.cognitoClient = CognitoIdentityProviderClient.builder()
.region(this.region)
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
}

public void setAuthParameters(String username, String password) {
this.username = username;
this.password = password;
}

public Token fetchTokenWithSrpAuth() throws InvalidKeyException, NoSuchAlgorithmException {
InitiateAuthRequest initiateAuthRequest = InitiateAuthRequest.builder()
.authFlow(AuthFlowType.USER_SRP_AUTH)
.clientId(this.cognitoClientId)
.authParameters(Map.of(
"USERNAME", this.username,
"SRP_A", helper.getA()))
.build();
InitiateAuthResponse initiateAuthResponse = cognitoClient.initiateAuth(initiateAuthRequest);
Map<String, String> challengeParameters = initiateAuthResponse.challengeParameters();

String userIdForSrp = challengeParameters.get("USER_ID_FOR_SRP");
String salt = challengeParameters.get("SALT");
String srpB = challengeParameters.get("SRP_B");
String secretBlock = challengeParameters.get("SECRET_BLOCK");

byte[] signatureKey = helper.getPasswordAuthenticationKey(userIdForSrp, password,
srpB, salt,
secretBlock);
String timestamp = helper.getCurrentFormattedTimestamp();
String signature = helper.calculateSignature(userIdForSrp, secretBlock, timestamp, signatureKey);

Map<String, String> challengeResponses = new HashMap<>();
challengeResponses.put("USERNAME", userIdForSrp);
challengeResponses.put("PASSWORD_CLAIM_SECRET_BLOCK", secretBlock);
challengeResponses.put("PASSWORD_CLAIM_SIGNATURE", signature);
challengeResponses.put("TIMESTAMP", timestamp);

RespondToAuthChallengeRequest respondRequest = RespondToAuthChallengeRequest.builder()
.challengeName(ChallengeNameType.PASSWORD_VERIFIER)
.clientId(this.cognitoClientId)
.challengeResponses(challengeResponses)
.build();

RespondToAuthChallengeResponse authChallengeResponse = cognitoClient.respondToAuthChallenge(respondRequest);
AuthenticationResultType authResult = authChallengeResponse.authenticationResult();

return new Token(authResult.idToken(), authResult.refreshToken());
}

public Token fetchToken() throws InvalidKeyException, NoSuchAlgorithmException {
return this.fetchTokenWithSrpAuth();
}
}
52 changes: 52 additions & 0 deletions src/main/java/city/makeour/moc/MocClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package city.makeour.moc;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import city.makeour.ngsi.v2.api.EntitiesApi;
import city.makeour.ngsi.v2.invoker.ApiClient;

public class MocClient {
protected ApiClient apiClient;

protected EntitiesApi entitiesApi;

protected TokenFetcherInterface tokenFetcher;

protected RefreshTokenStorageInterface refreshTokenStorage;

public MocClient() {
this("https://orion.sandbox.makeour.city");
}

public MocClient(String basePath) {
this.apiClient = new ApiClient();
this.apiClient.setBasePath(basePath);

this.entitiesApi = new EntitiesApi(this.apiClient);
this.refreshTokenStorage = new RefreshTokenStorage();
}

public EntitiesApi entities() {
return this.entitiesApi;
}

public void setMocAuthInfo(String cognitoUserPoolId, String cognitoClientId) {
this.tokenFetcher = new FetchCognitoToken(cognitoUserPoolId, cognitoClientId);
}

public void login(String username, String password) throws InvalidKeyException, NoSuchAlgorithmException {
if (this.tokenFetcher == null) {
throw new IllegalStateException("MocClient is not initialized with Cognito auth info.");
}

this.tokenFetcher.setAuthParameters(username, password);
Token token = this.tokenFetcher.fetchToken();
this.setToken(token.getIdToken());
this.refreshTokenStorage.setRefreshToken(token.getRefreshToken());
}

public void setToken(String token) {
this.apiClient.addDefaultHeader("Authorization", token);
}
}
22 changes: 22 additions & 0 deletions src/main/java/city/makeour/moc/RefreshTokenStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package city.makeour.moc;

public class RefreshTokenStorage implements RefreshTokenStorageInterface {

private String refreshToken;

public RefreshTokenStorage() {
this.refreshToken = null;
}

public String getRefreshToken() {
return refreshToken;
}

public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

public boolean hasRefreshToken() {
return this.refreshToken != null;
}
}
10 changes: 10 additions & 0 deletions src/main/java/city/makeour/moc/RefreshTokenStorageInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package city.makeour.moc;

public interface RefreshTokenStorageInterface {

public String getRefreshToken();

public void setRefreshToken(String refreshToken);

public boolean hasRefreshToken();
}
Loading