Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GOOGLEAPPS-22] added support to proxy #65

Merged
merged 4 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target
.idea
*.iml
.java-version
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,29 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.directory.Directory;
import com.google.api.services.directory.DirectoryScopes;
import com.google.api.services.licensing.Licensing;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.UserCredentials;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Arrays;
import java.util.List;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.common.security.GuardedString;
Expand All @@ -55,11 +66,6 @@ public class GoogleAppsConfiguration extends AbstractConfiguration implements St

private static final Log LOG = Log.getLog(GoogleAppsConfiguration.class);

/**
* Global instance of the HTTP transport.
*/
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

/**
* Global instance of the JSON factory.
*/
Expand Down Expand Up @@ -97,6 +103,17 @@ public class GoogleAppsConfiguration extends AbstractConfiguration implements St

private boolean removeLicenseOnDisable = false;

// proxy configuration section
private String proxyServerType = Proxy.Type.HTTP.name();

private String proxyServerHost;

private Integer proxyServerPort;

private String proxyServerUser;

private String proxyServerPassword;

@ConfigurationProperty(order = 1, displayMessageKey = "domain.display",
groupMessageKey = "basic.group", helpMessageKey = "domain.help", required = true,
confidential = false)
Expand Down Expand Up @@ -192,6 +209,61 @@ public void setRemoveLicenseOnDisable(final boolean removeLicenseOnDisable) {
this.removeLicenseOnDisable = removeLicenseOnDisable;
}

@ConfigurationProperty(displayMessageKey = "proxyServerType.display",
andrea-patricelli marked this conversation as resolved.
Show resolved Hide resolved
helpMessageKey = "proxyServerType.help",
order = 10)
public String getProxyServerType() {
return proxyServerType;
}

public void setProxyServerType(final String proxyServerType) {
this.proxyServerType = proxyServerType;
}

@ConfigurationProperty(displayMessageKey = "proxyServerHost.display",
helpMessageKey = "proxyServerHost.help",
order = 11)
public String getProxyServerHost() {
return proxyServerHost;
}

public void setProxyServerHost(final String proxyServerHost) {
this.proxyServerHost = proxyServerHost;
}

@ConfigurationProperty(displayMessageKey = "proxyServerPort.display",
helpMessageKey = "proxyServerPort.help",
order = 12)
public Integer getProxyServerPort() {
return proxyServerPort;
}

public void setProxyServerPort(final Integer proxyServerPort) {
this.proxyServerPort = proxyServerPort;
}

@ConfigurationProperty(displayMessageKey = "proxyServerUser.display",
helpMessageKey = "proxyServerUser.help",
order = 13)
public String getProxyServerUser() {
return proxyServerUser;
}

public void setProxyServerUser(final String proxyServerUser) {
this.proxyServerUser = proxyServerUser;
}

@ConfigurationProperty(displayMessageKey = "proxyServerPassword.display",
helpMessageKey = "proxyServerPassword.help",
order = 14, confidential = true)
public String getProxyServerPassword() {
return proxyServerPassword;
}

public void setProxyServerPassword(final String proxyServerPassword) {
this.proxyServerPassword = proxyServerPassword;
}

@Override
public void validate() {
if (StringUtil.isBlank(domain)) {
Expand Down Expand Up @@ -221,14 +293,45 @@ public void validate() {
throw new ConfigurationException("'customSchemaJSON' parameter must be a valid JSON.");
}
}
if (StringUtil.isNotBlank(proxyServerHost) && proxyServerPort == null
|| StringUtil.isBlank(proxyServerHost) && proxyServerPort != null) {
throw new ConfigurationException("Proxy host and port cannot be empty.");
}

if (StringUtil.isNotBlank(proxyServerUser) && StringUtil.isBlank(proxyServerPassword)) {
throw new ConfigurationException("Proxy server password cannot be null or empty if user is specified.");
}
if (StringUtil.isNotBlank(proxyServerPassword) && StringUtil.isBlank(proxyServerUser)) {
throw new ConfigurationException("Proxy server user cannot be null or empty if password is specified.");
}
}

private void initGoogleCredentials() {
synchronized (this) {
if (null == googleCredentials) {
UserCredentials.Builder credentialsBuilder = UserCredentials.newBuilder()
.setClientId(getClientId())
.setClientSecret(SecurityUtil.decrypt(getClientSecret()));
UserCredentials.Builder credentialsBuilder = UserCredentials.newBuilder();

boolean proxyEnabled = StringUtil.isNotBlank(proxyServerHost) && proxyServerPort != null;
if (proxyEnabled) {
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
ilgrosso marked this conversation as resolved.
Show resolved Hide resolved
clientBuilder.setProxy(new HttpHost(proxyServerHost, proxyServerPort));
if (StringUtil.isNotBlank(proxyServerUser) && StringUtil.isNotBlank(proxyServerPassword)) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(proxyServerUser, proxyServerPassword));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
}

credentialsBuilder.setHttpTransportFactory(new HttpTransportFactory() {
@Override
public HttpTransport create() {
return new ApacheHttpTransport(clientBuilder.build());
}
});
}
credentialsBuilder.setClientId(getClientId()).setClientSecret(SecurityUtil.decrypt(getClientSecret()));

getRefreshToken().access(chars -> credentialsBuilder.setRefreshToken(new String(chars)));

Expand All @@ -243,11 +346,17 @@ private void initGoogleCredentials() {
DirectoryScopes.ADMIN_DIRECTORY_GROUP,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER));

HttpTransport httpTransport = proxyEnabled
? new NetHttpTransport.Builder().setProxy(
new Proxy(Proxy.Type.valueOf(proxyServerType.toUpperCase()),
new InetSocketAddress(proxyServerHost, proxyServerPort))).build()
: new NetHttpTransport();

HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(googleCredentials);
directory = new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).
directory = new Directory.Builder(httpTransport, JSON_FACTORY, requestInitializer).
setApplicationName(APPLICATION_NAME).
build();
licensing = new Licensing.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).
licensing = new Licensing.Builder(httpTransport, JSON_FACTORY, requestInitializer).
setApplicationName(APPLICATION_NAME).
build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ productId.help=Google Product ID
removeLicenseOnDisable.display=Remove license while disabling an user
removeLicenseOnDisable.help=Also performs license removal when an user is disabled (suspend = true); Needs skuIds and productId to be defined.
basic.group=Basic Configuration Properties
proxyServerType.display=Proxy Server Type
proxyServerType.help=Specifies the type of the proxy server to use (if any) to access to the SCIM server, allowed values are HTTP and SOCKS
proxyServerHost.display=Proxy Server Host
proxyServerHost.help=Specifies proxy host to connect to reach SCIM server
proxyServerPort.display=Proxy Server Port
proxyServerPort.help=Specifies proxy port to connect to reach SCIM server
proxyServerUser.display=Proxy Server Username
proxyServerUser.help=Specifies username to authenticate on proxy (optional, only Basic auth is supported)
proxyServerPassword.display=Proxy Server Password
proxyServerPassword.help=Specifies password to authenticate on proxy

MESSAGE_OBJECT_CLASS___ACCOUNT__=Account
MESSAGE_OBJECT_CLASS___GROUP__=Group

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public static void setUp() throws IOException {
+ "}]"
+ "}]");

CONN_CONF.setProxyServerHost("localhost");
CONN_CONF.setProxyServerPort(3128);

CONNECTOR = newFacade();
}

Expand Down