com.synedge.oss.client.authentication.AuthenticatedClient.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of synedge-java-client Show documentation
Show all versions of synedge-java-client Show documentation
This client allows you to easily connect to the Synedge API with any language running on the JDK
The newest version!
package com.synedge.oss.client.authentication
import com.synedge.oss.client.ClientVersion
import com.synedge.oss.client.exceptions.SynedgeClientAuthenticationException
import com.synedge.oss.client.exceptions.SynedgeClientException
import groovy.json.JsonSlurper
import groovy.transform.CompileStatic
import groovy.transform.TypeCheckingMode
import groovy.util.logging.Slf4j
import org.glassfish.jersey.client.JerseyClient
import org.glassfish.jersey.client.JerseyClientBuilder
import javax.ws.rs.WebApplicationException
import javax.ws.rs.client.ClientRequestContext
import javax.ws.rs.client.ClientRequestFilter
import javax.ws.rs.client.Entity
import javax.ws.rs.client.Invocation.Builder
import javax.ws.rs.core.MultivaluedHashMap
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import java.security.MessageDigest
import java.util.concurrent.ConcurrentHashMap
@Slf4j
@CompileStatic
class AuthenticatedClient {
private static final String CLIENT_ID = "synedge-java-client-${ClientVersion.version}"
private static final String USER_AGENT = "Synedge Java Client (${ClientVersion.version})"
private static final Map AUTHENTICATION_MAP = new ConcurrentHashMap<>()
private final Random random = new Random()
private final String authenticationKey
protected final JsonSlurper jsonSlurper = new JsonSlurper()
protected final JerseyClient client
protected final String endpoint
protected AuthenticatedClient(String username, String password, String endpoint) {
this.client = JerseyClientBuilder.createClient().register(UserAgent)
this.endpoint = endpoint
this.authenticationKey = MessageDigest.getInstance("MD5").digest((username + '-' + password + '-' + endpoint).bytes).encodeHex().toString()
if (AUTHENTICATION_MAP.containsKey(authenticationKey)) {
return;
}
String clientSecret = generateRandomString(12)
AuthInfo authInfo = login(username, password, clientSecret)
AUTHENTICATION_MAP.put(authenticationKey, authInfo)
}
private final AuthInfo login(String username, String password, String clientSecret) {
MultivaluedMap formData = new MultivaluedHashMap<>();
formData.add('username', username)
formData.add('password', password)
formData.add('client_id', CLIENT_ID)
formData.add('client_secret', clientSecret)
formData.add('grant_type', 'password')
try {
return handleAuthResult(client.target(endpoint).path('auth').path('token').request().post(Entity.form(formData), String.class), clientSecret)
}
catch (WebApplicationException e) {
String response = e.response.readEntity(String)
// Check auth errors
log.error('Error logging in: ' + response, e)
throw new SynedgeClientAuthenticationException(response)
}
}
@CompileStatic(TypeCheckingMode.SKIP)
private final AuthInfo handleAuthResult(String result, String clientSecret) {
def authResult = jsonSlurper.parseText(result)
new AuthInfo(System.currentTimeMillis() + (authResult.expires_in as int) - 60, authResult.access_token as String, authResult.refresh_token as String, clientSecret)
}
private final void refresh() {
AuthInfo authInfo = AUTHENTICATION_MAP.get(authenticationKey)
MultivaluedMap formData = new MultivaluedHashMap<>();
formData.add('client_id', CLIENT_ID)
formData.add('client_secret', authInfo.clientSecret)
formData.add('grant_type', 'refresh_token')
formData.add('refresh_token', authInfo.refreshToken)
try {
AUTHENTICATION_MAP.put(authenticationKey, handleAuthResult(client.target(endpoint).path('auth').path('token').request().post(Entity.form(formData), String.class), authInfo.clientSecret))
}
catch (WebApplicationException e) {
String response = e.response.readEntity(String)
// Check auth errors
log.error('Error logging in: ' + response, e)
throw new SynedgeClientAuthenticationException(response)
}
}
protected Builder sign(Builder webTarget) {
AuthInfo authInfo = AUTHENTICATION_MAP.get(authenticationKey)
if (authInfo.tokenExpires < System.currentTimeMillis()) {
refresh()
}
webTarget.header("Authorization", "Bearer " + authInfo.accessToken)
}
private final String generateRandomString(int length) {
new BigInteger(length * 8, random).toString(16).substring(0, length)
}
protected final Object signAndGet(Builder webTarget) {
throwErrorOrReturnJson(sign(webTarget).get())
}
protected final Object signAndPost(Builder webTarget, Entity entity) {
throwErrorOrReturnJson(sign(webTarget).post(entity));
}
@CompileStatic(TypeCheckingMode.SKIP)
protected final Object throwErrorOrReturnJson(Response response) {
String responseStr = response.readEntity(String)
if (responseStr == null) {
throw new SynedgeClientAuthenticationException(response.getHeaderString('WWW-Authenticate'))
}
def result = jsonSlurper.parseText(responseStr)
if (result.error) {
throw new SynedgeClientException(result.message)
}
result.response
}
private static class UserAgent implements ClientRequestFilter {
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
requestContext.getHeaders().remove('User-Agent')
requestContext.getHeaders().add('User-Agent', USER_AGENT)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy