Skip to content

Commit

Permalink
oidc
Browse files Browse the repository at this point in the history
  • Loading branch information
София Корватовская committed Feb 2, 2025
1 parent cc42749 commit 35ddf7e
Show file tree
Hide file tree
Showing 17 changed files with 456 additions and 18 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ru.kontur.diadoc</groupId>
<artifactId>diadocsdk</artifactId>
<version>3.26.1</version>
<version>3.27.0</version>

<packaging>jar</packaging>

Expand Down
31 changes: 26 additions & 5 deletions src/main/java/Diadoc/Api/DiadocApi.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package Diadoc.Api;

import Diadoc.Api.auth.AuthManager;
import Diadoc.Api.auth.AuthenticateClient;
import Diadoc.Api.auth.*;
import Diadoc.Api.auth.oidc.OidcAuthManager;
import Diadoc.Api.auth.oidc.TokenProvider;
import Diadoc.Api.counteragent.CounteragentClient;
import Diadoc.Api.counteragentGroup.CounteragentGroupClient;
import Diadoc.Api.department.DepartmentClient;
Expand Down Expand Up @@ -29,6 +30,8 @@

public class DiadocApi {

private final AuthenticationType authenticationType;

private final AuthManager authManager;
private final AuthenticateClient authClient;
private final OrganizationClient organizationClient;
Expand Down Expand Up @@ -56,12 +59,21 @@ public class DiadocApi {
private final DiadocHttpClient diadocHttpClient;

public DiadocApi(String apiClientId, String url, @Nullable HttpHost proxyHost, @Nullable ConnectionSettings connectionSettings) {
this(new AuthManager(apiClientId), url, proxyHost, connectionSettings);
}

public DiadocApi(TokenProvider tokenProvider, String url, @Nullable HttpHost proxyHost, @Nullable ConnectionSettings connectionSettings) {
this(new OidcAuthManager(tokenProvider), url, proxyHost, connectionSettings);
}

private DiadocApi(IAuthManager authManager, String url, @Nullable HttpHost proxyHost, @Nullable ConnectionSettings connectionSettings) {
if (url == null) {
throw new IllegalArgumentException("url");
}
authManager = new AuthManager(apiClientId);
this.authManager = authManager.getAuthenticationType().equals(AuthenticationType.DIADOC) ? (AuthManager) authManager : new FallbackAuthManager();
diadocHttpClient = new DiadocHttpClient(authManager.getCredentialsProvider(), url, proxyHost, connectionSettings);
authClient = new AuthenticateClient(authManager, diadocHttpClient);
authenticationType = authManager.getAuthenticationType();
authClient = authManager.createAuthenticateClient(diadocHttpClient);
organizationClient = new OrganizationClient(diadocHttpClient);
departmentClient = new DepartmentClient(diadocHttpClient);
employeeClient = new EmployeeClient(diadocHttpClient);
Expand All @@ -83,7 +95,6 @@ public DiadocApi(String apiClientId, String url, @Nullable HttpHost proxyHost, @
employeePowerOfAttorneyClient = new EmployeePowerOfAttorneyClient(diadocHttpClient);
documentWorkflowClient = new DocumentWorkflowClient(diadocHttpClient);
operatorClient = new OperatorClient(diadocHttpClient);
authManager.setCredentials(null);
}

public DiadocApi(String apiClientId, String url) {
Expand Down Expand Up @@ -183,10 +194,20 @@ public DocumentWorkflowClient getDocumentWorkflowClient() {
return documentWorkflowClient;
}

/**
* @deprecated
* This method is deprecated due to the expansion of authentication types and is retained for backward compatibility.
* Use {@link #getAuthenticationType()} to see the authentication type and constructors {@link #DiadocApi(String, String, HttpHost, ConnectionSettings)}, {@link #DiadocApi(TokenProvider, String, HttpHost, ConnectionSettings)} to update Authorization header.
*/
@Deprecated
public AuthManager getAuthManager() {
return authManager;
}

public AuthenticationType getAuthenticationType() {
return authenticationType;
}

public TemplateClient getTemplateClient() {
return templateClient;
}
Expand Down
29 changes: 23 additions & 6 deletions src/main/java/Diadoc/Api/auth/AuthManager.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
package Diadoc.Api.auth;

import Diadoc.Api.helpers.Tools;
import Diadoc.Api.httpClient.DiadocHttpClient;
import org.apache.http.auth.AuthScope;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;

public class AuthManager {
private boolean isAuthenticated = false;
private String apiClientId;
private CredentialsProvider credentialsProvider;
public class AuthManager implements IAuthManager {
private volatile boolean isAuthenticated;
private final String apiClientId;
private final CredentialsProvider credentialsProvider;

public AuthManager(String apiClientId) {
if (Tools.isNullOrEmpty(apiClientId)) {
throw new IllegalArgumentException("ApiClientId cannot be empty or null");
}
this.apiClientId = apiClientId;
isAuthenticated = false;
credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new DiadocCredentials(apiClientId, null));
}

@Override
public AuthenticateClient createAuthenticateClient(DiadocHttpClient httpClient) {
return new AuthenticateClient(this, httpClient);
}

@Override
public CredentialsProvider getCredentialsProvider() {
return credentialsProvider;
}

@Override
public AuthenticationType getAuthenticationType() {
return AuthenticationType.DIADOC;
}

public boolean isAuthenticated() {
return isAuthenticated;
}

public void setCredentials(String authToken) {
isAuthenticated = (authToken != null);
isAuthenticated = authToken != null;
credentialsProvider.setCredentials(AuthScope.ANY, new DiadocCredentials(apiClientId, authToken));
}

public void clearCredentials(){
public void clearCredentials() {
isAuthenticated = false;
credentialsProvider.setCredentials(AuthScope.ANY, new DiadocCredentials(apiClientId, null));
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/Diadoc/Api/auth/AuthenticateClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

public class AuthenticateClient {
private static final String V_3_AUTHENTICATE = "/V3/Authenticate";
private AuthManager authManager;
private DiadocHttpClient diadocHttpClient;
private final AuthManager authManager;
private final DiadocHttpClient diadocHttpClient;

public AuthenticateClient(AuthManager authManager, DiadocHttpClient diadocHttpClient) {
this.authManager = authManager;
Expand Down Expand Up @@ -142,4 +142,4 @@ public ExternalServiceAuthInfo getExternalServiceAuthInfo(String key) throws Dia
throw new DiadocSdkException(ex);
}
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/Diadoc/Api/auth/AuthenticationType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package Diadoc.Api.auth;

public enum AuthenticationType {
OIDC,
DIADOC
}
25 changes: 25 additions & 0 deletions src/main/java/Diadoc/Api/auth/CredentialsSchemeFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package Diadoc.Api.auth;

import Diadoc.Api.auth.oidc.DiadocOidcCredentials;
import Diadoc.Api.auth.oidc.OidcAuthScheme;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.Credentials;

import java.util.Map;
import java.util.function.Supplier;

public class CredentialsSchemeFactory {

private static final Map<Class<? extends Credentials>, Supplier<AuthScheme>> SCHEME_SUPPLIERS = Map.of(
DiadocOidcCredentials.class, OidcAuthScheme::new,
DiadocCredentials.class, DiadocAuthScheme::new
);

public AuthScheme createScheme(Credentials credentials) {
Supplier<AuthScheme> schemeSupplier = SCHEME_SUPPLIERS.get(credentials.getClass());
if (schemeSupplier == null) {
throw new IllegalArgumentException("Unsupported credentials type: " + credentials.getClass().getName());
}
return schemeSupplier.get();
}
}
4 changes: 2 additions & 2 deletions src/main/java/Diadoc/Api/auth/DiadocAuthScheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@Contract()
public class DiadocAuthScheme extends RFC2617Scheme {

private boolean complete;
private volatile boolean complete;

/**
* Default constructor for the Diadoc authentication scheme.
Expand Down Expand Up @@ -121,4 +121,4 @@ public static Header authenticate(final DiadocCredentials credentials) {
return new BufferedHeader(buffer);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
Expand All @@ -13,6 +14,12 @@

public class DiadocPreemptiveAuthRequestInterceptor implements HttpRequestInterceptor {

private final CredentialsSchemeFactory credentialsSchemeMapper;

public DiadocPreemptiveAuthRequestInterceptor() {
this.credentialsSchemeMapper = new CredentialsSchemeFactory();
}

public void process(final HttpRequest request, final HttpContext context) {
AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
// If no auth scheme has been initialized yet
Expand All @@ -24,8 +31,14 @@ public void process(final HttpRequest request, final HttpContext context) {
Credentials credentials = credentialsProvider.getCredentials(authScope);
// If found, generate BasicScheme preemptively
if (credentials != null) {
authState.update(new DiadocAuthScheme(), credentials);
updateAuthState(authState, credentials);
}
}
}

private void updateAuthState(AuthState authState, Credentials credentials) {
AuthScheme scheme = credentialsSchemeMapper.createScheme(credentials);
authState.update(scheme, credentials);
}

}
41 changes: 41 additions & 0 deletions src/main/java/Diadoc/Api/auth/FallbackAuthManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package Diadoc.Api.auth;

import Diadoc.Api.httpClient.DiadocHttpClient;
import org.apache.http.client.CredentialsProvider;

public class FallbackAuthManager extends AuthManager {
public FallbackAuthManager() {
super("EMPTY");
}

@Override
public AuthenticateClient createAuthenticateClient(DiadocHttpClient httpClient) {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}

@Override
public CredentialsProvider getCredentialsProvider() {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}

@Override
public AuthenticationType getAuthenticationType() {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}

@Override
public boolean isAuthenticated() {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}

@Override
public void setCredentials(String authToken) {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}

@Override
public void clearCredentials() {
throw new UnsupportedOperationException("Cannot determine Diadoc authentication manager operations for OIDC authentication.");
}
}

13 changes: 13 additions & 0 deletions src/main/java/Diadoc/Api/auth/IAuthManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package Diadoc.Api.auth;

import Diadoc.Api.httpClient.DiadocHttpClient;
import org.apache.http.client.CredentialsProvider;

public interface IAuthManager {

AuthenticateClient createAuthenticateClient(DiadocHttpClient httpClient);

CredentialsProvider getCredentialsProvider();

AuthenticationType getAuthenticationType();
}
34 changes: 34 additions & 0 deletions src/main/java/Diadoc/Api/auth/oidc/ContainerTokenProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package Diadoc.Api.auth.oidc;

import java.util.Objects;

/**
* Default implementation
*/
public class ContainerTokenProvider implements TokenProvider {

private volatile String token;

@Override
public String getToken() {
return token;
}

public void setToken(String token) {
this.token = token;
}

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

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

}
35 changes: 35 additions & 0 deletions src/main/java/Diadoc/Api/auth/oidc/DiadocOidcCredentials.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package Diadoc.Api.auth.oidc;

import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.auth.BasicUserPrincipal;
import org.apache.http.auth.Credentials;

import java.security.Principal;

@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class DiadocOidcCredentials implements Credentials {

private final TokenProvider tokenProvider;
private final Principal userPrincipal;

public DiadocOidcCredentials(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
this.userPrincipal = new BasicUserPrincipal("DefaultUser");
}


public TokenProvider getTokenProvider() {
return tokenProvider;
}

@Override
public Principal getUserPrincipal() {
return userPrincipal;
}

@Override
public String getPassword() {
return "";
}
}
Loading

0 comments on commit 35ddf7e

Please sign in to comment.