Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions api/src/main/java/io/bosonnetwork/service/BosonService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
import io.bosonnetwork.PeerInfo;

/**
* Interface BosonService is the basic abstraction for the extensible service on top of
* the Boson super node. This interface describes the basic information about the service
* itself and the life-cycle management methods. All super node services should implement
* this interface.
* Interface BosonService is the basic abstraction for extensible services on top of
* the Boson super node. This interface defines the core service attributes and
* lifecycle management methods. All services intended to run on a Boson super node
* MUST implement this interface.
*/
public interface BosonService {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import io.bosonnetwork.BosonException;

/**
* An exception that is thrown when an error occurs in the Boson services.
* Base exception thrown when an error occurs within the Boson service layer.
* This includes errors during service lifecycle (init, start, stop) or
* during service-specific operations.
*/
public class BosonServiceException extends BosonException {
private static final long serialVersionUID = 3891117673443389144L;
Expand Down
67 changes: 3 additions & 64 deletions api/src/main/java/io/bosonnetwork/service/ClientAuthenticator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@

package io.bosonnetwork.service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import io.bosonnetwork.Id;

/**
* Interface for authenticating clients (users and devices).
* Interface for authenticating clients (users and devices) within the Boson network.
* <p>
* Implementations of this interface provide mechanisms to verify the identity of users and devices
* using cryptographic signatures and other credentials.
* Implementations provide mechanisms to verify the identity of users and devices
* typically using cryptographic challenges and signatures (e.g., Ed25519).
*/
public interface ClientAuthenticator {

Expand Down Expand Up @@ -84,63 +82,4 @@ default CompletableFuture<Boolean> authenticateUser(Id userId) {
default CompletableFuture<Boolean> authenticateDevice(Id userId, Id deviceId, String address) {
return authenticateDevice(userId, deviceId, null, null, address);
}

/**
* Returns a `ClientAuthenticator` instance that allows all authentication attempts.
* The returned authenticator verifies the provided signature against the corresponding
* signature key derived from the user or device ID, enabling universal authentication
* acceptance when the signature is valid.
*
* @return a `ClientAuthenticator` instance that performs signature validation for user
* and device authentication and always allows access if the signature is valid
*/
static ClientAuthenticator allowAll() {
return new ClientAuthenticator() {
@Override
public CompletableFuture<Boolean> authenticateUser(Id userId, byte[] nonce, byte[] signature) {
boolean isValid = nonce == null || signature == null || userId.toSignatureKey().verify(nonce, signature);
return CompletableFuture.completedFuture(isValid);
}

@Override
public CompletableFuture<Boolean> authenticateDevice(Id userId, Id deviceId, byte[] nonce, byte[] signature, String address) {
boolean isValid = nonce == null || signature == null || deviceId.toSignatureKey().verify(nonce, signature);
return CompletableFuture.completedFuture(isValid);
}
};
}

/**
* Creates a `ClientAuthenticator` instance that validates authentication
* attempts based on a provided mapping of users and their associated devices.
* The returned authenticator verifies the provided signature and ensures
* that the user ID and device ID exist in the given map, granting access
* if all checks are satisfied.
*
* @param userDeviceMap a mapping where the keys represent user IDs and the values
* are lists of device IDs associated with each user
* @return a `ClientAuthenticator` instance that performs authentication based
* on the provided user-device mapping and cryptographic signature verification
*/
static ClientAuthenticator allow(Map<Id, List<Id>> userDeviceMap) {
return new ClientAuthenticator() {
@Override
public CompletableFuture<Boolean> authenticateUser(Id userId, byte[] nonce, byte[] signature) {
if (!userDeviceMap.containsKey(userId))
return CompletableFuture.completedFuture(false);

boolean isValid = nonce == null || signature == null || userId.toSignatureKey().verify(nonce, signature);
return CompletableFuture.completedFuture(isValid);
}

@Override
public CompletableFuture<Boolean> authenticateDevice(Id userId, Id deviceId, byte[] nonce, byte[] signature, String address) {
if (!userDeviceMap.containsKey(userId) || !userDeviceMap.get(userId).contains(deviceId))
return CompletableFuture.completedFuture(false);

boolean isValid = nonce == null || signature == null || deviceId.toSignatureKey().verify(nonce, signature);
return CompletableFuture.completedFuture(isValid);
}
};
}
}
13 changes: 0 additions & 13 deletions api/src/main/java/io/bosonnetwork/service/ClientAuthorizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,4 @@ public interface ClientAuthorizer {
* (e.g., tokens, permissions) if successful, or completes exceptionally if authorization fails
*/
CompletableFuture<Map<String, Object>> authorize(Id userId, Id deviceId, String serviceId);

/**
* Returns a no-operation implementation of {@link ClientAuthorizer}.
*
* This implementation provides an authorization mechanism that always completes
* successfully without performing any checks or validations. It returns an
* empty map to indicate no authorization details are provided.
*
* @return a no-op {@link ClientAuthorizer} instance
*/
static ClientAuthorizer noop() {
return (userId, deviceId, serviceId) -> CompletableFuture.completedFuture(Map.of());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
import java.util.concurrent.CompletableFuture;

import io.bosonnetwork.Id;
import io.bosonnetwork.Identity;
import io.bosonnetwork.service.impl.AllowAllClientContext;
import io.bosonnetwork.service.impl.StaticClientContext;
import io.bosonnetwork.web.CompactWebTokenAuth;

/**
* Client manager interface (Read-only) for the Boson Super Node services.
Expand All @@ -34,7 +38,7 @@
* registered within the network. It allows retrieving user details, checking for user existence,
* and listing or verifying devices associated with users.
*/
public interface Clients {
public interface ClientContext {
/**
* Retrieves the user information for a given user ID.
*
Expand All @@ -59,6 +63,7 @@ public interface Clients {
* @param userId the unique identifier of the user whose devices are to be retrieved
* @return a {@link CompletableFuture} that completes with a list of {@link ClientDevice} objects belonging to the user
*/
@Deprecated
CompletableFuture<List<ClientDevice>> getDevices(Id userId);

/**
Expand All @@ -68,6 +73,7 @@ public interface Clients {
* @return a {@link CompletableFuture} that completes with the {@link ClientDevice} object if found,
* or completes with {@code null} if the device does not exist
*/
@Deprecated
CompletableFuture<ClientDevice> getDevice(Id deviceId);

/**
Expand All @@ -77,6 +83,7 @@ public interface Clients {
* @return a {@link CompletableFuture} that completes with {@code true} if the device exists,
* or {@code false} otherwise
*/
@Deprecated
CompletableFuture<Boolean> existsDevice(Id deviceId);

/**
Expand All @@ -88,4 +95,82 @@ public interface Clients {
* or {@code false} otherwise
*/
CompletableFuture<Boolean> existsDevice(Id userId, Id deviceId);

/**
* Gets the client authenticator instance.
*
* @return the {@link ClientAuthenticator} used for authenticating clients.
*/
ClientAuthenticator getAuthenticator();

/**
* Gets the client authorizer instance.
*
* @return the {@link ClientAuthorizer} used for authorizing client requests.
*/
ClientAuthorizer getAuthorizer();

/**
* Get the instance of {@link CompactWebTokenAuth} used for handling
* web token authentication within the client context.
*
* @return the {@link CompactWebTokenAuth} instance responsible for managing
* web token authentication.
*/
CompactWebTokenAuth getWebTokenAuthenticator();

/**
* Returns a new client context configured to allow all clients without Web Token Auth support.
* <p>
* Useful for scenarios where the Web Token authenticator is not required or should be nullified,
* typically used in simplified or test configurations.
* </p>
*
* @return a {@link ClientContext} instance allowing all access without token auth support.
*/
static ClientContext allowAll() {
return new AllowAllClientContext(null);
}

/**
* Returns a new client context configured to allow all clients with the specified node identity.
* <p>
* This configuration allows any request but associates them with a specific node identity,
* depending on the implementation of {@link AllowAllClientContext}.
* </p>
*
* @param nodeIdentity the identity of the node allowing access; if null, generic allows-all behavior applies
* @return a {@link ClientContext} instance configured with permissive access rules.
*/
static ClientContext allowAll(Identity nodeIdentity) {
return new AllowAllClientContext(nodeIdentity);
}

/**
* Returns a new in-memory client context suitable for testing without Web Token Auth support.
* <p>
* This implementation uses an internal map for storage and is typically used for simulation
* or unit testing where network connectivity is not required. Unlike production contexts,
* this version does not support CompactWebTokenAuth. It does not require a node identity.
* </p>
*
* @return a {@link ClientContext} instance using an in-memory map store for simulation purposes.
*/
static ClientContext staticContext() {
return new StaticClientContext(null);
}

/**
* Returns a new in-memory client context suitable for testing with Node Identity.
* <p>
* Provides an in-memory simulation environment configured with a specific node identity
* but without Web Token Auth support.
* </p>
*
* @param nodeIdentity the identity of the node to associate with this static context; if null, generic behavior applies
* @return a {@link ClientContext} instance using an in-memory map store for simulation purposes.
*/
static ClientContext staticContext(Identity nodeIdentity) {
return new StaticClientContext(nodeIdentity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,28 @@
public class DefaultServiceContext implements ServiceContext {
private final Vertx vertx;
private final Node node;
private final ClientAuthenticator clientAuthenticator;
private final ClientAuthorizer clientAuthorizer;
private final FederationAuthenticator federationAuthenticator;
private final Clients clients;
private final Federation federation;
private final ClientContext clientContext;
private final FederationContext federationContext;
private final Map<String, Object> configuration;
private final Path dataDir;
private Map<Object, Object> properties;

/**
* Creates a new {@link ServiceContext} instance.
*
* @param vertx the Vert.x instance to be used
* @param node the host Boson node
* @param clientAuthenticator the authenticator for client connections
* @param clientAuthorizer the authorizer for client requests
* @param federationAuthenticator the authenticator for federation communications
* @param clients the clients management component
* @param federation the federation instance
* @param configuration the configuration data for the service
* @param dataDir the path to the persistence data directory, or {@code null} if not available
* @param vertx the Vert.x instance to be used
* @param node the host Boson node
* @param clientContext the clients context instance
* @param federationContext the federation context instance
* @param configuration the configuration data for the service
* @param dataDir the path to the persistence data directory, or {@code null} if not available
*/
public DefaultServiceContext(Vertx vertx, Node node, ClientAuthenticator clientAuthenticator, ClientAuthorizer clientAuthorizer,
FederationAuthenticator federationAuthenticator, Clients clients, Federation federation,
Map<String, Object> configuration, Path dataDir) {
public DefaultServiceContext(Vertx vertx, Node node, ClientContext clientContext,
FederationContext federationContext, Map<String, Object> configuration, Path dataDir) {
this.vertx = vertx;
this.node = node;
this.clientAuthenticator = clientAuthenticator;
this.clientAuthorizer = clientAuthorizer;
this.federationAuthenticator = federationAuthenticator;
this.clients = clients;
this.federation = federation;
this.clientContext = clientContext;
this.federationContext = federationContext;
this.configuration = configuration;
this.dataDir = dataDir;
}
Expand Down Expand Up @@ -114,40 +104,16 @@ public Path getDataDir() {
* {@inheritDoc}
*/
@Override
public ClientAuthenticator getClientAuthenticator() {
return clientAuthenticator;
public ClientContext getClientContext() {
return clientContext;
}

/**
* {@inheritDoc}
*/
@Override
public ClientAuthorizer getClientAuthorizer() {
return clientAuthorizer;
}

/**
* {@inheritDoc}
*/
@Override
public FederationAuthenticator getFederationAuthenticator() {
return federationAuthenticator;
}

/**
* {@inheritDoc}
*/
@Override
public Clients getClients() {
return clients;
}

/**
* {@inheritDoc}
*/
@Override
public Federation getFederation() {
return federation;
public FederationContext getFederationContext() {
return federationContext;
}

/**
Expand Down
Loading
Loading