Skip to content

Commit

Permalink
Implement and add basic authentication API in the jpro-auth-core
Browse files Browse the repository at this point in the history
…module
  • Loading branch information
besidev committed Jan 2, 2024
1 parent 993890e commit 80b4aad
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 24 deletions.
1 change: 1 addition & 0 deletions jpro-auth/core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
exports one.jpro.platform.auth.core;
exports one.jpro.platform.auth.core.api;
exports one.jpro.platform.auth.core.authentication;
exports one.jpro.platform.auth.core.basic;
exports one.jpro.platform.auth.core.jwt;
exports one.jpro.platform.auth.core.oauth2;
exports one.jpro.platform.auth.core.oauth2.provider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
*/
public interface AuthAPI {

/**
* Configure and create a basic (username and password) authentication provider.
*
* @return fluent style api.
*/
static FluentBasicAuth basicAuth() {
return new FluentBasicAuthAPI();
}

/**
* Configure and create a Google authentication provider.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package one.jpro.platform.auth.core.api;

import one.jpro.platform.auth.core.basic.BasicAuthenticationProvider;

import java.util.Map;
import java.util.Set;

/**
* Fluent Basic (username and password) Authentication interface.
*
* @author Besmir Beqiri
*/
public interface FluentBasicAuth {

/**
* Set the roles.
*
* @param roles the roles
* @return self
*/
FluentBasicAuth roles(Set<String> roles);

/**
* Set the attributes.
*
* @param attributes the attributes
* @return self
*/
FluentBasicAuth attributes(Map<String, Object> attributes);

/**
* Set the authorization path.
*
* @param authorizationPath the authorization path
* @return self
*/
FluentBasicAuth authorizationPath(String authorizationPath);

/**
* Create a simple authentication provider.
*
* @return a {@link BasicAuthenticationProvider} instance.
*/
BasicAuthenticationProvider create();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package one.jpro.platform.auth.core.api;

import one.jpro.platform.auth.core.basic.BasicAuthenticationProvider;

import java.util.Map;
import java.util.Set;

/**
* Fluent Basic (username and password) Authentication API.
*
* @author Besmir Beqiri
*/
public class FluentBasicAuthAPI implements FluentBasicAuth {

private Set<String> roles;
private Map<String, Object> attributes;
private String authorizationPath = BasicAuthenticationProvider.DEFAULT_AUTHORIZATION_PATH;

@Override
public FluentBasicAuth roles(Set<String> roles) {
this.roles = roles;
return this;
}

@Override
public FluentBasicAuth attributes(Map<String, Object> attributes) {
this.attributes = attributes;
return this;
}

@Override
public FluentBasicAuth authorizationPath(String authorizationPath) {
this.authorizationPath = authorizationPath;
return this;
}

@Override
public BasicAuthenticationProvider create() {
final var basicAuthProvider = new BasicAuthenticationProvider(roles, attributes);
basicAuthProvider.setAuthorizationPath(authorizationPath);
return basicAuthProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,37 @@ default JSONObject toJSON() {
return json;
}

/**
* Build an {@link Authentication} instance for the user.
*
* @param username User's name
* @return an {@link Authentication} object
*/
@NotNull
static Authentication create(@NotNull String username) {
return Authentication.create(username, null, null);
return new User(username, null, null);
}

static Authentication create(@NotNull String username,
@NotNull Set<String> roles) {
/**
* Build an {@link Authentication} instance for the user.
*
* @param username User's name
* @param roles User's roles
* @return an {@link Authentication} object
*/
@NotNull
static Authentication create(@NotNull String username,
@NotNull Set<String> roles) {
Objects.requireNonNull(roles, "User's roles are null.");
return new User(username, roles, null);
}

/**
* Build an {@link Authentication} instance foe the user.
* Build an {@link Authentication} instance for the user.
*
* @param username User's name
* @param username User's name
* @param attributes User's attributes
* @return An {@link Authentication} for the user
* @return an {@link Authentication} object
*/
@NotNull
static Authentication create(@NotNull String username,
Expand All @@ -79,10 +93,10 @@ static Authentication create(@NotNull String username,
/**
* Builds an {@link Authentication} instance for the user.
*
* @param username User's name
* @param roles User's roles
* @param username User's name
* @param roles User's roles
* @param attributes User's attributes
* @return An {@link Authentication} for the user
* @return an {@link Authentication} object
*/
@NotNull
static Authentication create(@NotNull String username,
Expand All @@ -92,10 +106,10 @@ static Authentication create(@NotNull String username,
}

/**
* Builds an {@link Authentication} instance for the user from a {@link JSONObject}.
* Builds an {@link User} instance for the user from a {@link JSONObject}.
*
* @param json a {@link JSONObject} containing user's data.
* @return An {@link Authentication} for the user
* @return an {@link User} object
*/
@NotNull
static User create(@NotNull JSONObject json) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package one.jpro.platform.auth.core.basic;

import one.jpro.platform.auth.core.authentication.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
* The {@code BasicAuthenticationProvider} class implements the {@code AuthenticationProvider} interface
* to provide basic authentication using username and password credentials.
*
* @author Besmir Beqiri
*/
public class BasicAuthenticationProvider implements AuthenticationProvider<UsernamePasswordCredentials> {

private static final Logger logger = LoggerFactory.getLogger(BasicAuthenticationProvider.class);

public static final String DEFAULT_AUTHORIZATION_PATH = "/auth/basic";

@NotNull
private String authorizationPath = DEFAULT_AUTHORIZATION_PATH;
@Nullable
private Set<String> roles;
@Nullable
private Map<String, Object> attributes;

/**
* Constructs a new {@code BasicAuthenticationProvider} with specified roles and attributes.
*
* @param roles the set of roles to be associated with the authenticated user, may be {@code null}.
* @param attributes the map of attributes to be associated with the authenticated user, may be {@code null}.
*/
public BasicAuthenticationProvider(@Nullable final Set<String> roles,
@Nullable final Map<String, Object> attributes) {
this.roles = roles;
this.attributes = attributes;
}

/**
* Authenticates the user based on the provided {@code UsernamePasswordCredentials}.
*
* @param credentials the credentials containing the username and password
* @return a {@code CompletableFuture} that, when completed, provides the authenticated {@code User}.
* @throws CredentialValidationException if the credentials are not valid
*/
@NotNull
@Override
public CompletableFuture<User> authenticate(@NotNull final UsernamePasswordCredentials credentials)
throws CredentialValidationException {
try {
credentials.validate(null);
} catch (CredentialValidationException ex) {
logger.error("Username and password credentials not valid", ex);
return CompletableFuture.failedFuture(ex);
}

JSONObject userJSON = new JSONObject();
userJSON.put(User.KEY_NAME, credentials.getUsername());
userJSON.put(User.KEY_ROLES, new JSONArray(roles));

JSONObject authJSON = new JSONObject();
authJSON.put("password", credentials.getPassword());
userJSON.put(User.KEY_ATTRIBUTES, new JSONObject(attributes).put("auth", authJSON));

final User user = Authentication.create(userJSON);
return CompletableFuture.completedFuture(user);
}

/**
* Gets the authorization path URI for basic authentication.
* This is the URI path that the users will be redirected to if they need to be authenticated.
*
* @return the authorization path string
*/
@NotNull
public String getAuthorizationPath() {
return authorizationPath;
}

/**
* Sets the authorization path for basic authentication.
* This is the URI path that the users will be redirected to if they need to be authenticated.
*
* @param authorizationPath the authorization path string
*/
public void setAuthorizationPath(@NotNull String authorizationPath) {
this.authorizationPath = authorizationPath;
}

/**
* Gets the set of roles associated with this authentication provider.
*
* @return The set of roles, may be {@code null}.
*/
@Nullable
public Set<String> getRoles() {
return roles;
}

/**
* Sets the roles to be associated with this authentication provider.
*
* @param roles The set of roles, may be {@code null}.
*/
public void setRoles(@Nullable Set<String> roles) {
this.roles = roles;
}

/**
* Gets the attributes associated with this authentication provider.
*
* @return The attributes, may be {@code null}.
*/
@Nullable
public Map<String, Object> getAttributes() {
return attributes;
}

/**
* Sets the attributes to be associated with this authentication provider.
*
* @param attributes The map of attributes, may be {@code null}.
*/
public void setAttributes(@Nullable Map<String, Object> attributes) {
this.attributes = attributes;
}
}
Loading

0 comments on commit 80b4aad

Please sign in to comment.