Skip to content

Commit

Permalink
Merge pull request kruize#1311 from khansaad/auth-updates
Browse files Browse the repository at this point in the history
Database updates for authentication
  • Loading branch information
dinogun authored Nov 21, 2024
2 parents 93cb9a6 + 48dbe43 commit 227769f
Show file tree
Hide file tree
Showing 18 changed files with 431 additions and 153 deletions.
3 changes: 2 additions & 1 deletion migrations/kruize_local_ddl.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), authentication jsonb, primary key (name));
create table IF NOT EXISTS kruize_authentication (id serial, authentication_type varchar(255), credentials jsonb, service_type varchar(255), primary key (id));
create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), authentication_id serial, FOREIGN KEY (authentication_id) REFERENCES kruize_authentication(id), primary key (name));
create table IF NOT EXISTS kruize_dsmetadata (id serial, version varchar(255), datasource_name varchar(255), cluster_name varchar(255), namespace varchar(255), workload_type varchar(255), workload_name varchar(255), container_name varchar(255), container_image_name varchar(255), primary key (id));
alter table kruize_experiments add column experiment_type varchar(255), add column metadata_id bigint references kruize_dsmetadata(id), alter column datasource type varchar(255);
create table IF NOT EXISTS kruize_metric_profiles (api_version varchar(255), kind varchar(255), metadata jsonb, name varchar(255) not null, k8s_type varchar(255), profile_version float(53) not null, slo jsonb, primary key (name));
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/autotune/common/auth/AuthType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.autotune.common.auth;

public enum AuthType {
BASIC, BEARER, API_KEY, OAUTH2, NONE
}
67 changes: 41 additions & 26 deletions src/main/java/com/autotune/common/auth/AuthenticationConfig.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
package com.autotune.common.auth;

import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.utils.KruizeConstants;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

public class AuthenticationConfig {
private String type; // "basic", "bearer", "apiKey", "oauth2"
private AuthType type;
private Credentials credentials;
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationConfig.class);

public AuthenticationConfig(String type, Credentials credentials) {
public AuthenticationConfig(AuthType type, Credentials credentials) {
this.type = type;
this.credentials = credentials;
}

public AuthenticationConfig() {
}

public String getType() {
public AuthType getType() {
return type;
}

Expand All @@ -30,27 +31,35 @@ public Credentials getCredentials() {
public static AuthenticationConfig createAuthenticationConfigObject(JSONObject authenticationObj) {
// Parse and map authentication methods if they exist
if (authenticationObj != null) {
String type = authenticationObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TYPE);
AuthType type = AuthType.valueOf(authenticationObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TYPE).toUpperCase());
JSONObject credentialsObj = authenticationObj.getJSONObject(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CREDENTIALS);

Credentials credentials = new Credentials();
switch (type.toLowerCase()) {
case KruizeConstants.AuthenticationConstants.BASIC:
credentials.setUsername(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_USERNAME));
credentials.setPassword(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_PASSWORD));
Credentials credentials = null; // Initialize credentials as null, and create specific subclass instances based on the type
switch (type) {
case BASIC:
BasicAuthCredentials basicCredentials = new BasicAuthCredentials();
basicCredentials.setUsername(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_USERNAME));
basicCredentials.setPassword(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_PASSWORD));
credentials = basicCredentials;
break;
case KruizeConstants.AuthenticationConstants.BEARER:
credentials.setTokenFilePath(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_FILE));
case BEARER:
BearerTokenCredentials bearerCredentials = new BearerTokenCredentials();
bearerCredentials.setTokenFilePath(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_FILE));
credentials = bearerCredentials;
break;
case KruizeConstants.AuthenticationConstants.API_KEY:
credentials.setApiKey(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_API_KEY));
credentials.setHeaderName(credentialsObj.optString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_HEADER_NAME, "X-API-Key"));
case API_KEY:
ApiKeyCredentials apiKeyCredentials = new ApiKeyCredentials();
apiKeyCredentials.setApiKey(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_API_KEY));
apiKeyCredentials.setHeaderName(credentialsObj.optString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_HEADER_NAME, "X-API-Key"));
credentials = apiKeyCredentials;
break;
case KruizeConstants.AuthenticationConstants.OAUTH2:
credentials.setTokenEndpoint(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_ENDPOINT));
credentials.setClientId(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_ID));
credentials.setClientSecret(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_SECRET));
credentials.setGrantType(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_GRANT_TYPE));
case OAUTH2:
OAuth2Credentials oauth2Credentials = new OAuth2Credentials();
oauth2Credentials.setTokenEndpoint(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_ENDPOINT));
oauth2Credentials.setClientId(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_ID));
oauth2Credentials.setClientSecret(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_SECRET));
oauth2Credentials.setGrantType(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_GRANT_TYPE));
credentials = oauth2Credentials;
break;
default:
LOGGER.error(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION + "{}", type);
Expand All @@ -63,14 +72,20 @@ public static AuthenticationConfig createAuthenticationConfigObject(JSONObject a

// Static method to return a no-auth config
public static AuthenticationConfig noAuth() {
return new AuthenticationConfig(AnalyzerConstants.NONE, null);
return new AuthenticationConfig(AuthType.NONE, null);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AuthenticationConfig that = (AuthenticationConfig) o;
return Objects.equals(type, that.type) &&
Objects.equals(credentials, that.credentials);
}

@Override
public String toString() {
return "AuthenticationConfig{" +
"type='" + type + '\'' +
", credentials=" + credentials +
'}';
public int hashCode() {
return Objects.hash(type, credentials);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
public class AuthenticationStrategyFactory {

public static AuthenticationStrategy createAuthenticationStrategy(AuthenticationConfig authConfig) {
String type = authConfig.getType();
AuthType type = authConfig.getType();
switch (type) {
case KruizeConstants.AuthenticationConstants.NONE:
case NONE:
return new NoAuthStrategy();
case KruizeConstants.AuthenticationConstants.BASIC:
String username = authConfig.getCredentials().getUsername();
String password = authConfig.getCredentials().getPassword();
case BASIC:
String username = ((BasicAuthCredentials) authConfig.getCredentials()).getUsername();
String password = ((BasicAuthCredentials) authConfig.getCredentials()).getPassword();
return new BasicAuthenticationStrategy(username, password);
case KruizeConstants.AuthenticationConstants.BEARER:
String tokenFilePath = authConfig.getCredentials().getTokenFilePath();
case BEARER:
String tokenFilePath = ((BearerTokenCredentials) authConfig.getCredentials()).getTokenFilePath();
return new BearerAuthenticationStrategy(tokenFilePath);
case KruizeConstants.AuthenticationConstants.API_KEY:
String apiKey = authConfig.getCredentials().getApiKey();
case API_KEY:
String apiKey = ((ApiKeyCredentials) authConfig.getCredentials()).getApiKey();
return new APIKeyAuthenticationStrategy(apiKey);
case KruizeConstants.AuthenticationConstants.OAUTH2:
String tokenEndpoint = authConfig.getCredentials().getTokenEndpoint();
String clientId = authConfig.getCredentials().getClientId();
String clientSecret = authConfig.getCredentials().getClientSecret();
case OAUTH2:
String tokenEndpoint = ((OAuth2Credentials) authConfig.getCredentials()).getTokenEndpoint();
String clientId = ((OAuth2Credentials) authConfig.getCredentials()).getClientId();
String clientSecret = ((OAuth2Credentials) authConfig.getCredentials()).getClientSecret();
return new OAuth2AuthenticationStrategy(tokenEndpoint, clientId, clientSecret);
default:
throw new IllegalArgumentException(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION+ type);
Expand Down
144 changes: 92 additions & 52 deletions src/main/java/com/autotune/common/auth/Credentials.java
Original file line number Diff line number Diff line change
@@ -1,108 +1,148 @@
package com.autotune.common.auth;

public class Credentials {
private String grantType; // OAuth2
private String clientId; // OAuth2
private String clientSecret; // OAuth2
private String username; // Basic auth
private String password; // Basic auth
private String tokenEndpoint; // OAuth2
private String tokenFilePath; // Bearer token
private String apiKey; // API key
private String headerName; // API key header name

public Credentials(String username, String password) {
this.username = username;
this.password = password;
}
import java.util.Objects;

public Credentials() {
}
public abstract class Credentials {
}

public String getUsername() {
return username;
}
class OAuth2Credentials extends Credentials {
private String grantType;
private String clientId;
private String clientSecret;
private String tokenEndpoint;

public String getGrantType() {
return grantType;
}

public String getClientSecret() {
return clientSecret;
public void setGrantType(String grantType) {
this.grantType = grantType;
}

public String getClientId() {
return clientId;
}

public String getTokenEndpoint() {
return tokenEndpoint;
public void setClientId(String clientId) {
this.clientId = clientId;
}

public String getHeaderName() {
return headerName;
public String getClientSecret() {
return clientSecret;
}

public String getApiKey() {
return apiKey;
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}

public String getTokenFilePath() {
return tokenFilePath;
public String getTokenEndpoint() {
return tokenEndpoint;
}

public String getPassword() {
return password;
public void setTokenEndpoint(String tokenEndpoint) {
this.tokenEndpoint = tokenEndpoint;
}

public void setGrantType(String grantType) {
this.grantType = grantType;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OAuth2Credentials that = (OAuth2Credentials) o;
return Objects.equals(grantType, that.grantType) &&
Objects.equals(clientId, that.clientId) &&
Objects.equals(clientSecret, that.clientSecret) &&
Objects.equals(tokenEndpoint, that.tokenEndpoint);
}

public void setClientId(String clientId) {
this.clientId = clientId;
@Override
public int hashCode() {
return Objects.hash(grantType, clientId, clientSecret, tokenEndpoint);
}
}

public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
class BasicAuthCredentials extends Credentials {
private String username;
private String password;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

public void setTokenEndpoint(String tokenEndpoint) {
this.tokenEndpoint = tokenEndpoint;
class BearerTokenCredentials extends Credentials {
private String tokenFilePath;

public String getTokenFilePath() {
return tokenFilePath;
}

public void setTokenFilePath(String tokenFilePath) {
this.tokenFilePath = tokenFilePath;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BearerTokenCredentials that = (BearerTokenCredentials) o;
return Objects.equals(tokenFilePath, that.tokenFilePath);
}

@Override
public int hashCode() {
return Objects.hash(tokenFilePath);
}
@Override
public String toString() {
return "BearerTokenCredentials{" +
"tokenFilePath='" + tokenFilePath + '\'' +
'}';
}
}

class ApiKeyCredentials extends Credentials {
private String apiKey;
private String headerName;

public String getApiKey() {
return apiKey;
}

public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}

public String getHeaderName() {
return headerName;
}

public void setHeaderName(String headerName) {
this.headerName = headerName;
}

@Override
public String toString() {
return "Credentials{" +
"grantType='" + grantType + '\'' +
", clientId='" + clientId + '\'' +
", clientSecret='" + clientSecret + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", tokenEndpoint='" + tokenEndpoint + '\'' +
", tokenFilePath='" + tokenFilePath + '\'' +
", apiKey='" + apiKey + '\'' +
", headerName='" + headerName + '\'' +
'}';
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApiKeyCredentials that = (ApiKeyCredentials) o;
return Objects.equals(apiKey, that.apiKey);
}

@Override
public int hashCode() {
return Objects.hash(apiKey);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ValidationOutputData {
private boolean success;
private String message;
private Integer errorCode;
private Long authEntryId;

public ValidationOutputData(boolean success, String message, Integer errorCode) {
this.success = success;
Expand Down Expand Up @@ -53,6 +54,14 @@ public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}

public Long getAuthEntryId() {
return authEntryId;
}

public void setAuthEntryId(Long authEntryId) {
this.authEntryId = authEntryId;
}

@Override
public String toString() {
return "ValidationOutputData{" +
Expand Down
Loading

0 comments on commit 227769f

Please sign in to comment.