Skip to content

Commit

Permalink
SDK-2262: Add Digital Identity Session Receipt retrieval service
Browse files Browse the repository at this point in the history
  • Loading branch information
irotech committed Jul 25, 2023
1 parent 6e7d16a commit 1618e00
Show file tree
Hide file tree
Showing 26 changed files with 904 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.yoti.api.client;

import static com.yoti.validation.Validation.notNull;
import static com.yoti.validation.Validation.notNullOrEmpty;

import java.io.IOException;
import java.security.KeyPair;
import java.security.Security;
Expand All @@ -13,6 +10,8 @@
import com.yoti.api.client.spi.remote.KeyStreamVisitor;
import com.yoti.api.client.spi.remote.call.identity.DigitalIdentityException;
import com.yoti.api.client.spi.remote.call.identity.DigitalIdentityService;
import com.yoti.api.client.spi.remote.call.identity.Receipt;
import com.yoti.validation.Validation;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

Expand All @@ -27,8 +26,8 @@ public class DigitalIdentityClient {
private final DigitalIdentityService identityService;

DigitalIdentityClient(String sdkId, KeyPairSource keyPair, DigitalIdentityService identityService) {
notNullOrEmpty(sdkId, "SDK ID");
notNull(keyPair, "Application Key Pair");
Validation.notNullOrEmpty(sdkId, "SDK ID");
Validation.notNull(keyPair, "Application Key Pair");

this.sdkId = sdkId;
this.keyPair = loadKeyPair(keyPair);
Expand Down Expand Up @@ -79,8 +78,17 @@ public ShareSessionQrCode fetchShareQrCode(String qrCodeId) throws DigitalIdenti
return identityService.fetchShareQrCode(sdkId, keyPair, qrCodeId);
}

public Object fetchShareReceipt(String receiptId) {
return identityService.fetchShareReceipt(receiptId);
/**
* Retrieve the decrypted share receipt.
*
* <p>A receipt will contain the shared user attributes.</p>
*
* @param receiptId ID of the receipt
* @return Shared user attributes
* @throws DigitalIdentityException Thrown if the receipt retrieval is unsuccessful
*/
public Receipt fetchShareReceipt(String receiptId) throws DigitalIdentityException {
return identityService.fetchShareReceipt(sdkId, keyPair, receiptId);
}

private KeyPair loadKeyPair(KeyPairSource keyPairSource) throws InitialisationException {
Expand All @@ -103,14 +111,14 @@ public static class Builder {
private Builder() { }

public Builder withClientSdkId(String sdkId) {
notNullOrEmpty(sdkId, "SDK ID");
Validation.notNullOrEmpty(sdkId, "SDK ID");

this.sdkId = sdkId;
return this;
}

public Builder withKeyPairSource(KeyPairSource keyPairSource) {
notNull(keyPairSource, "Key Pair Source");
Validation.notNull(keyPairSource, "Key Pair Source");

this.keyPairSource = keyPairSource;
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.yoti.api.client.identity;

import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import com.yoti.validation.Validation;

import com.fasterxml.jackson.annotation.JsonProperty;

public final class ShareSessionNotification {
Expand Down Expand Up @@ -85,7 +85,7 @@ public Builder withHeader(String key, String value) {
}

public ShareSessionNotification build() {
notNullOrEmpty(url, Property.URL);
Validation.notNullOrEmpty(url, Property.URL);

return new ShareSessionNotification(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.yoti.api.client.identity;

import static com.yoti.api.client.spi.remote.util.Validation.notNull;
import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -11,6 +8,7 @@

import com.yoti.api.client.identity.extension.Extension;
import com.yoti.api.client.identity.policy.Policy;
import com.yoti.validation.Validation;

import com.fasterxml.jackson.annotation.JsonProperty;

Expand All @@ -23,7 +21,7 @@ public class ShareSessionRequest {
private final Policy policy;

@JsonProperty(Property.EXTENSIONS)
private final List<Extension> extensions;
private final List<Extension<?>> extensions;

@JsonProperty(Property.REDIRECT_URI)
private final String redirectUri;
Expand All @@ -47,7 +45,7 @@ public Policy getPolicy() {
return policy;
}

public List<Extension> getExtensions() {
public List<Extension<?>> getExtensions() {
return extensions;
}

Expand All @@ -67,7 +65,7 @@ public static final class Builder {

private Map<String, Object> subject;
private Policy policy;
private List<Extension> extensions;
private List<Extension<?>> extensions;
private String redirectUri;
private ShareSessionNotification notification;

Expand All @@ -85,12 +83,12 @@ public Builder withPolicy(Policy policy) {
return this;
}

public Builder withExtensions(List<Extension> extensions) {
public Builder withExtensions(List<Extension<?>> extensions) {
this.extensions = Collections.unmodifiableList(extensions);
return this;
}

public Builder withExtension(Extension extension) {
public Builder withExtension(Extension<?> extension) {
extensions.add(extension);
return this;
}
Expand All @@ -106,8 +104,8 @@ public Builder withNotification(ShareSessionNotification notification) {
}

public ShareSessionRequest build() {
notNull(policy, Property.POLICY);
notNullOrEmpty(redirectUri, Property.REDIRECT_URI);
Validation.notNull(policy, Property.POLICY);
Validation.notNullOrEmpty(redirectUri, Property.REDIRECT_URI);

return new ShareSessionRequest(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.yoti.api.client.identity.extension;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Extension<T> {
Expand All @@ -10,7 +11,8 @@ public class Extension<T> {
@JsonProperty(Property.CONTENT)
private final T content;

Extension(String type, T content) {
@JsonCreator
Extension(@JsonProperty(Property.TYPE) String type, @JsonProperty(Property.CONTENT) T content) {
this.type = type;
this.content = content;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.yoti.api.client.identity.extension;

import com.yoti.api.client.spi.remote.util.Validation;
import com.yoti.validation.Validation;

public class LocationConstraintExtensionBuilder implements ExtensionBuilder<LocationConstraintContent> {

public static final String TYPE = "LOCATION_CONSTRAINT";

private double latitude;
private double longitude;
private double radius = 150d;
Expand Down Expand Up @@ -42,7 +40,7 @@ public LocationConstraintExtensionBuilder withMaxUncertainty(double maxUncertain
@Override
public Extension<LocationConstraintContent> build() {
LocationConstraintContent content = new LocationConstraintContent(latitude, longitude, radius, maxUncertainty);
return new Extension<>(TYPE, content);
return new Extension<>("LOCATION_CONSTRAINT", content);
}

private static final class Property {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
package com.yoti.api.client.identity.extension;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.TimeZone;

import com.yoti.api.client.AttributeDefinition;
import com.yoti.api.client.spi.remote.call.YotiConstants;

import com.fasterxml.jackson.annotation.JsonProperty;

public class ThirdPartyAttributeContent {

private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(YotiConstants.RFC3339_PATTERN_MILLIS);

private final Date expiryDate;
private final OffsetDateTime expiry;

@JsonProperty(Property.DEFINITIONS)
private final List<AttributeDefinition> definitions;

ThirdPartyAttributeContent(Date expiryDate, List<AttributeDefinition> definitions) {
this.expiryDate = expiryDate;
ThirdPartyAttributeContent(OffsetDateTime expiry, List<AttributeDefinition> definitions) {
this.expiry = expiry;
this.definitions = definitions;
}

@JsonProperty(Property.EXPIRY_DATE)
public String getExpiryDate() {
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
return DATE_FORMAT.format(expiryDate.getTime());
public OffsetDateTime getExpiryDate() {
return expiry;
}

public List<AttributeDefinition> getDefinitions() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
package com.yoti.api.client.identity.extension;

import static com.yoti.api.client.spi.remote.util.Validation.notNull;
import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty;

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.yoti.api.client.AttributeDefinition;
import com.yoti.validation.Validation;

public class ThirdPartyAttributeExtensionBuilder implements ExtensionBuilder<ThirdPartyAttributeContent> {

public static final String TYPE = "THIRD_PARTY_ATTRIBUTE";

private Date expiryDate;
private OffsetDateTime expiryDate;
private List<AttributeDefinition> definitions;

public ThirdPartyAttributeExtensionBuilder() {
this.definitions = new ArrayList<>();
}

public ThirdPartyAttributeExtensionBuilder withExpiryDate(Date expiryDate) {
notNull(expiryDate, Property.EXPIRY_DATE);
public ThirdPartyAttributeExtensionBuilder withExpiryDate(OffsetDateTime expiryDate) {
Validation.notNull(expiryDate, Property.EXPIRY_DATE);

this.expiryDate = new Date(expiryDate.getTime());
this.expiryDate = expiryDate;
return this;
}

public ThirdPartyAttributeExtensionBuilder withDefinition(String definition) {
notNullOrEmpty(definition, Property.DEFINITION);
Validation.notNullOrEmpty(definition, Property.DEFINITION);

this.definitions.add(new AttributeDefinition(definition));
return this;
Expand All @@ -45,7 +41,7 @@ public ThirdPartyAttributeExtensionBuilder withDefinitions(List<String> definiti

public Extension<ThirdPartyAttributeContent> build() {
ThirdPartyAttributeContent thirdPartyAttributeContent = new ThirdPartyAttributeContent(expiryDate, definitions);
return new Extension<>(TYPE, thirdPartyAttributeContent);
return new Extension<>("THIRD_PARTY_ATTRIBUTE", thirdPartyAttributeContent);
}

private static final class Property {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.yoti.api.client.identity.extension;

import com.yoti.api.client.spi.remote.util.Validation;
import com.yoti.validation.Validation;

public class TransactionalFlowExtensionBuilder implements ExtensionBuilder<Object> {

public static final String TYPE = "TRANSACTIONAL_FLOW";

private Object content;

public TransactionalFlowExtensionBuilder withContent(Object content) {
Expand All @@ -17,7 +15,7 @@ public TransactionalFlowExtensionBuilder withContent(Object content) {

@Override
public Extension<Object> build() {
return new Extension<>(TYPE, content);
return new Extension<>("TRANSACTIONAL_FLOW", content);
}

private static final class Property {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.yoti.api.client.identity.policy;

import static com.yoti.api.client.spi.remote.util.Validation.notNull;
import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty;
import com.yoti.validation.Validation;

import com.fasterxml.jackson.annotation.JsonProperty;

Expand Down Expand Up @@ -46,8 +45,8 @@ public Builder withSubType(String subType) {
}

public WantedAnchor build() {
notNullOrEmpty(value, Property.NAME);
notNull(subType, Property.SUB_TYPE);
Validation.notNullOrEmpty(value, Property.NAME);
Validation.notNull(subType, Property.SUB_TYPE);

return new WantedAnchor(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.yoti.api.client.identity.policy;

import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.yoti.api.client.identity.constraint.Constraint;
import com.yoti.validation.Validation;

import com.fasterxml.jackson.annotation.JsonProperty;

Expand Down Expand Up @@ -102,7 +101,7 @@ public Builder withConstraint(Constraint constraint) {
}

public WantedAttribute build() {
notNullOrEmpty(name, Property.NAME);
Validation.notNullOrEmpty(name, Property.NAME);

return new WantedAttribute(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@
import com.yoti.api.client.Attribute;
import com.yoti.api.client.ProfileException;

class AttributeListReader {
public class AttributeListReader {

private final EncryptedDataReader encryptedDataReader;
private final AttributeListConverter attributeListConverter;

private AttributeListReader(EncryptedDataReader encryptedDataReader,
AttributeListConverter attributeListConverter) {
private AttributeListReader(
EncryptedDataReader encryptedDataReader,
AttributeListConverter attributeListConverter) {
this.encryptedDataReader = encryptedDataReader;
this.attributeListConverter = attributeListConverter;
}

static AttributeListReader newInstance() {
public static AttributeListReader newInstance() {
return new AttributeListReader(
EncryptedDataReader.newInstance(),
AttributeListConverter.newInstance()
);
}

List<Attribute<?>> read(byte[] encryptedProfileBytes, Key secretKey) throws ProfileException {
public List<Attribute<?>> read(byte[] encryptedProfileBytes, Key secretKey) throws ProfileException {
List<Attribute<?>> attributeList = new ArrayList<>();
if (encryptedProfileBytes != null && encryptedProfileBytes.length > 0) {
byte[] profileData = encryptedDataReader.decryptBytes(encryptedProfileBytes, secretKey);
Expand Down
Loading

0 comments on commit 1618e00

Please sign in to comment.