Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions acs-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@
</execution>
<execution>
<id>delete</id>
<configuration>
<appname>${acs.appname}</appname>
</configuration>
<phase>post-integration-test</phase>
<goals>
<goal>delete</goal>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ge.predix.integration.test;

import static com.ge.predix.acs.commons.web.AcsApiUriTemplates.RESOURCE_CONNECTOR_URL;
import static com.ge.predix.acs.commons.web.AcsApiUriTemplates.SUBJECT_CONNECTOR_URL;
import static com.ge.predix.acs.commons.web.AcsApiUriTemplates.V1;
import static com.ge.predix.test.utils.PolicyHelper.PREDIX_ZONE_ID;

Expand All @@ -23,6 +24,7 @@
import org.springframework.web.client.RestTemplate;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.ge.predix.acs.rest.AttributeAdapterConnection;
Expand Down Expand Up @@ -110,45 +112,48 @@ private void setupPublicACS() throws Exception {
this.zoneHelper.createTestZone(this.acsAdmin, this.acsZone1Name, false);
}

public void testPutGetDeleteConnector() throws Exception {
@Test(dataProvider = "requestUrlProvider")
public void testPutGetDeleteConnector(final String endpointUrl) throws Exception {
AttributeConnector expectedConnector = new AttributeConnector();
expectedConnector.setMaxCachedIntervalMinutes(100);
expectedConnector.setAdapters(Collections.singleton(new AttributeAdapterConnection("http://my-endpoint.com",
"http://my-uaa.com", "my-client", "my-secret")));
try {
this.zone1ConnectorAdmin.put(this.acsUrl + V1 + RESOURCE_CONNECTOR_URL,
this.zone1ConnectorAdmin.put(this.acsUrl + V1 + endpointUrl,
new HttpEntity<>(expectedConnector, this.zone1Headers));
} catch (Exception e) {
Assert.fail("Unable to create attribute connector. " + e.getMessage());
}

try {
ResponseEntity<AttributeConnector> response = this.zone1ConnectorReadClient.exchange(
this.acsUrl + V1 + RESOURCE_CONNECTOR_URL, HttpMethod.GET, new HttpEntity<>(this.zone1Headers),
this.acsUrl + V1 + endpointUrl, HttpMethod.GET, new HttpEntity<>(this.zone1Headers),
AttributeConnector.class);
Assert.assertEquals(response.getBody(), expectedConnector);
} catch (Exception e) {
Assert.fail("Unable to retrieve attribute connector." + e.getMessage());
} finally {
this.zone1ConnectorAdmin.exchange(this.acsUrl + V1 + RESOURCE_CONNECTOR_URL, HttpMethod.DELETE,
this.zone1ConnectorAdmin.exchange(this.acsUrl + V1 + endpointUrl, HttpMethod.DELETE,
new HttpEntity<>(this.zone1Headers), String.class);
}
}

public void testCreateConnectorDeniedWithoutOauthToken() throws Exception {
@Test(dataProvider = "requestUrlProvider")
public void testCreateConnectorDeniedWithoutOauthToken(final String endpointUrl) throws Exception {
RestTemplate acs = new RestTemplate();
try {
acs.put(this.acsUrl + V1 + RESOURCE_CONNECTOR_URL,
acs.put(this.acsUrl + V1 + endpointUrl,
new HttpEntity<>(new AttributeConnector(), this.zone1Headers));
Assert.fail("No exception thrown when configuring connector without a token.");
} catch (HttpClientErrorException e) {
Assert.assertEquals(e.getStatusCode(), HttpStatus.UNAUTHORIZED);
}
}

public void testCreateConnectorDeniedWithoutSufficientScope() throws Exception {
@Test(dataProvider = "requestUrlProvider")
public void testCreateConnectorDeniedWithoutSufficientScope(final String endpointUrl) throws Exception {
try {
this.zone1ConnectorReadClient.put(this.acsUrl + V1 + RESOURCE_CONNECTOR_URL,
this.zone1ConnectorReadClient.put(this.acsUrl + V1 + endpointUrl,
new HttpEntity<>(new AttributeConnector(), this.zone1Headers));
Assert.fail("No exception thrown when creating connector without sufficient scope.");
} catch (HttpClientErrorException e) {
Expand All @@ -159,10 +164,10 @@ public void testCreateConnectorDeniedWithoutSufficientScope() throws Exception {
// Due to the issue in spring security, 403 Forbidden response from the server, is received as a 400 Bad Request
// error code because error is not correctly translated by the JSON deserializer
//https://github.com/spring-projects/spring-security-oauth/issues/191
public void testGetConnectorDeniedWithoutSufficientScope() throws Exception {
@Test(dataProvider = "requestUrlProvider")
public void testGetConnectorDeniedWithoutSufficientScope(final String endpointUrl) throws Exception {
try {
this.zone1Admin.exchange(
this.acsUrl + V1 + RESOURCE_CONNECTOR_URL, HttpMethod.GET,
this.zone1Admin.exchange(this.acsUrl + V1 + endpointUrl, HttpMethod.GET,
new HttpEntity<>(this.zone1Headers), AttributeConnector.class);
Assert.fail("No exception thrown when retrieving connector without sufficient scope.");
} catch (HttpClientErrorException e) {
Expand All @@ -174,14 +179,19 @@ public void testGetConnectorDeniedWithoutSufficientScope() throws Exception {
}
}

public void testDeleteConnectorDeniedWithoutSufficientScope() throws Exception {
@Test(dataProvider = "requestUrlProvider")
public void testDeleteConnectorDeniedWithoutSufficientScope(final String endpointUrl) throws Exception {
try {
this.zone1ConnectorReadClient.exchange(
this.acsUrl + V1 + RESOURCE_CONNECTOR_URL, HttpMethod.DELETE,
this.zone1ConnectorReadClient.exchange(this.acsUrl + V1 + endpointUrl, HttpMethod.DELETE,
new HttpEntity<>(this.zone1Headers), String.class);
Assert.fail("No exception thrown when deleting connector without sufficient scope.");
} catch (HttpClientErrorException e) {
Assert.assertEquals(e.getStatusCode(), HttpStatus.FORBIDDEN);
}
}

@DataProvider(name = "requestUrlProvider")
private Object[][] requestUrlProvider() {
return new String[][] { { RESOURCE_CONNECTOR_URL }, { SUBJECT_CONNECTOR_URL } };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ private AcsApiUriTemplates() {
public static final String ZONE_URL = "/zone/{zoneName}";

public static final String ZONECLIENT_URL = "/client";

public static final String RESOURCE_CONNECTOR_URL = "/connector/resource";

public static final String CONNECTOR_URL = "/connector";

public static final String RESOURCE_CONNECTOR_URL = CONNECTOR_URL + "/resource";

public static final String SUBJECT_CONNECTOR_URL = CONNECTOR_URL + "/subject";
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,52 @@ public ResponseEntity<?> deleteResourceConnector() {
throw new RestApiException(HttpStatus.UNPROCESSABLE_ENTITY, e.getMessage(), e);
}
}

@RequestMapping(
method = PUT,
value = V1 + AcsApiUriTemplates.SUBJECT_CONNECTOR_URL,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AttributeConnector> putSubjectConnector(@RequestBody final AttributeConnector connector) {
try {
boolean connectorCreated = this.service.upsertSubjectConnector(connector);

if (connectorCreated) {
// return 201 with empty response body
return created(V1 + AcsApiUriTemplates.SUBJECT_CONNECTOR_URL, false);
}
// return 200 with empty response body
return ok();
} catch (AttributeConnectorException e) {
throw new RestApiException(HttpStatus.UNPROCESSABLE_ENTITY, e.getMessage(), e);
}
}

@RequestMapping(
method = GET,
value = V1 + AcsApiUriTemplates.SUBJECT_CONNECTOR_URL,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AttributeConnector> getSubjectConnector() {
try {
AttributeConnector connector = this.service.retrieveSubjectConnector();
if (connector != null) {
return ok(connector);
}
return notFound();
} catch (AttributeConnectorException e) {
throw new RestApiException(HttpStatus.UNPROCESSABLE_ENTITY, e);
}
}

@RequestMapping(method = DELETE, value = V1 + AcsApiUriTemplates.SUBJECT_CONNECTOR_URL)
public ResponseEntity<?> deleteSubjectConnector() {
try {
Boolean deleted = this.service.deleteSubjectConnector();
if (deleted) {
return noContent();
}
return notFound();
} catch (AttributeConnectorException e) {
throw new RestApiException(HttpStatus.UNPROCESSABLE_ENTITY, e.getMessage(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.ge.predix.acs.rest.AttributeConnector;

public interface AttributeConnectorService {

boolean upsertResourceConnector(AttributeConnector connector);

AttributeConnector retrieveResourceConnector();
Expand All @@ -11,9 +12,15 @@ public interface AttributeConnectorService {

AttributeConnector getResourceAttributeConnector();

AttributeConnector getSubjectAttributeConnector();

boolean isResourceAttributeConnectorConfigured();

boolean upsertSubjectConnector(AttributeConnector connector);

AttributeConnector retrieveSubjectConnector();

boolean deleteSubjectConnector();

AttributeConnector getSubjectAttributeConnector();

boolean isSubjectAttributeConnectorConfigured();
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,68 @@ public boolean deleteResourceConnector() {
return true;
}

@Override
public boolean upsertSubjectConnector(final AttributeConnector connector) {
ZoneEntity zoneEntity = this.zoneResolver.getZoneEntityOrFail();
validateConnectorConfigOrFail(connector);

boolean isCreated = false;
try {
AttributeConnector existingConnector = zoneEntity.getSubjectAttributeConnector();
isCreated = (null == existingConnector);
connector.setAdapters(encryptAdapterClientSecrets(connector.getAdapters()));
zoneEntity.setSubjectAttributeConnector(connector);
this.zoneRepository.save(zoneEntity);
if (!isCreated) {
this.attributeReaderFactory.removeSubjectReader(zoneEntity.getName());
}
} catch (Exception e) {
String message = String.format(
"Unable to persist connector configuration for subject attributes for zone '%s'",
zoneEntity.getName());
throw new AttributeConnectorException(message, e);
}
return isCreated;
}

@Override
public AttributeConnector retrieveSubjectConnector() {
ZoneEntity zoneEntity = this.zoneResolver.getZoneEntityOrFail();
try {
AttributeConnector connector = zoneEntity.getSubjectAttributeConnector();
if (null != connector) {
// Deep copy the connector to prevent double-decryption of secrets
connector = AttributeConnector.newInstance(connector);
connector.setAdapters(decryptAdapterClientSecrets(connector.getAdapters()));
}
return connector;
} catch (Exception e) {
String message = String.format(
"Unable to retrieve connector configuration for subject attributes for zone '%s'",
zoneEntity.getName());
throw new AttributeConnectorException(message, e);
}
}

@Override
public boolean deleteSubjectConnector() {
ZoneEntity zoneEntity = this.zoneResolver.getZoneEntityOrFail();
try {
if (null == zoneEntity.getSubjectAttributeConnector()) {
return false;
}
zoneEntity.setSubjectAttributeConnector(null);
this.zoneRepository.save(zoneEntity);
this.attributeReaderFactory.removeSubjectReader(zoneEntity.getName());
} catch (Exception e) {
String message = String.format(
"Unable to delete connector configuration for subject attributes for zone '%s'",
zoneEntity.getName());
throw new AttributeConnectorException(message, e);
}
return true;
}

private void validateAdapterEntityOrFail(final AttributeAdapterConnection adapter) {
if (adapter == null) {
throw new AttributeConnectorException("Attribute connector configuration requires at least one adapter");
Expand Down Expand Up @@ -165,19 +227,7 @@ public AttributeConnector getResourceAttributeConnector() {

@Override
public AttributeConnector getSubjectAttributeConnector() {
ZoneEntity zoneEntity = this.zoneResolver.getZoneEntityOrFail();
try {
AttributeConnector connector = zoneEntity.getSubjectAttributeConnector();
if (null != connector) {
connector.setAdapters(decryptAdapterClientSecrets(connector.getAdapters()));
}
return connector;
} catch (Exception e) {
String message = String.format(
"Unable to retrieve connector configuration for subject attributes for zone '%s'",
zoneEntity.getName());
throw new AttributeConnectorException(message, e);
}
return retrieveSubjectConnector();
}

@Override
Expand Down
Loading