Skip to content

Commit

Permalink
add tests, functionality, and docs for updating mfa provider
Browse files Browse the repository at this point in the history
[#151224508] https://www.pivotaltracker.com/story/show/151224508

Signed-off-by: Henry Zhao <henryzh16@gmail.com>
  • Loading branch information
Aakash Shah authored and 6palace committed Oct 11, 2017
1 parent 8013e9e commit 19a000d
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 12 deletions.
Expand Up @@ -13,6 +13,7 @@
import java.util.Date; import java.util.Date;


import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;


public class MfaProviderTest { public class MfaProviderTest {
Expand Down Expand Up @@ -63,7 +64,30 @@ public void testDeserialize() {
assertEquals(32, config.getDuration()); assertEquals(32, config.getDuration());
assertEquals("issuer", config.getIssuer()); assertEquals("issuer", config.getIssuer());
assertEquals("ddd", config.getProviderDescription()); assertEquals("ddd", config.getProviderDescription());
}



@Test
public void testDeserializeInvalidType() {
String json = "{\n" +
" \"type\" : \"invalid-type\",\n" +
" \"config\" : {\n" +
" \"providerDescription\" : \"ddd\",\n" +
" \"issuer\": \"issuer\",\n" +
" \"algorithm\": \"SHA256\",\n" +
" \"digits\": 8, \n" +
" \"duration\": 32 \n" +
" },\n" +
" \"name\" : \"UAA Provider\", \n" +
" \"active\" : true\n" +
"}";

MfaProvider<GoogleMfaProviderConfig> provider = JsonUtils.readValue(json, MfaProvider.class);

assertEquals(null, provider.getType());
assertEquals("UAA Provider", provider.getName());
assertEquals(true, provider.isActive());
assertNull(provider.getConfig());
} }


@Test @Test
Expand Down
Expand Up @@ -23,7 +23,13 @@ public class JdbcMfaProviderProvisioning implements MfaProviderProvisioning, Sys
private static Log logger = LogFactory.getLog(JdbcMfaProviderProvisioning.class); private static Log logger = LogFactory.getLog(JdbcMfaProviderProvisioning.class);
public static final String TABLE_NAME = "mfa_providers"; public static final String TABLE_NAME = "mfa_providers";
public static final String MFA_PROVIDER_FIELDS = "id,name,type,config,active,identity_zone_id,created,lastmodified"; public static final String MFA_PROVIDER_FIELDS = "id,name,type,config,active,identity_zone_id,created,lastmodified";
public static final String CREATE_PROVIDER_SQL = "insert into mfa_providers(" + MFA_PROVIDER_FIELDS + ") values (?,?,?,?,?,?,?,?)"; public static final String CREATE_PROVIDER_SQL = "insert into " + TABLE_NAME + "(" + MFA_PROVIDER_FIELDS + ") values (?,?,?,?,?,?,?,?)";

public static final String MFA_PROVIDER_UPDATE_FIELDS = "name,type,config,active,identity_zone_id,lastmodified".replace(",","=?,")+"=?";

public static final String UPDATE_PROVIDER_SQL = "update " + TABLE_NAME + " set " + MFA_PROVIDER_UPDATE_FIELDS + " where id=? and identity_zone_id=?";


public static final String MFA_PROVIDER_BY_ID_QUERY = "select " + MFA_PROVIDER_FIELDS + " from " + TABLE_NAME + " where id=? and identity_zone_id=?"; public static final String MFA_PROVIDER_BY_ID_QUERY = "select " + MFA_PROVIDER_FIELDS + " from " + TABLE_NAME + " where id=? and identity_zone_id=?";
public static final String MFA_PROVIDERS_QUERY = "select " + MFA_PROVIDER_FIELDS + " from " + TABLE_NAME + " where identity_zone_id=?"; public static final String MFA_PROVIDERS_QUERY = "select " + MFA_PROVIDER_FIELDS + " from " + TABLE_NAME + " where identity_zone_id=?";


Expand Down Expand Up @@ -61,6 +67,28 @@ public void setValues(PreparedStatement ps) throws SQLException {
return retrieve(id, zoneId); return retrieve(id, zoneId);
} }


@Override
public MfaProvider update(MfaProvider provider, String zoneId) {
jdbcTemplate.update(UPDATE_PROVIDER_SQL, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps) throws SQLException {
int pos = 1;
ps.setString(pos++, provider.getName());
ps.setString(pos++, provider.getType().toValue());
ps.setString(pos++, JsonUtils.writeValueAsString(provider.getConfig()));
ps.setBoolean(pos++, provider.isActive());
ps.setString(pos++, zoneId);
ps.setTimestamp(pos++, new Timestamp(System.currentTimeMillis()));

ps.setString(pos++, provider.getId().trim());
ps.setString(pos++, zoneId);

}
});

return retrieve(provider.getId(), zoneId);
}

@Override @Override
public MfaProvider retrieve(String id, String zoneId) { public MfaProvider retrieve(String id, String zoneId) {
MfaProvider provider = jdbcTemplate.queryForObject(MFA_PROVIDER_BY_ID_QUERY, mapper, id, zoneId); MfaProvider provider = jdbcTemplate.queryForObject(MFA_PROVIDER_BY_ID_QUERY, mapper, id, zoneId);
Expand Down
Expand Up @@ -15,9 +15,9 @@


import java.util.List; import java.util.List;


import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.GET; import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST; import static org.springframework.web.bind.annotation.RequestMethod.POST;
import static org.springframework.web.bind.annotation.RequestMethod.PUT;


@RequestMapping("/mfa-providers") @RequestMapping("/mfa-providers")
@RestController @RestController
Expand All @@ -33,16 +33,27 @@ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEv
} }


@RequestMapping(method = POST) @RequestMapping(method = POST)
public ResponseEntity<MfaProvider> createMfaProvider(@RequestBody MfaProvider provider) { public ResponseEntity<MfaProvider> createMfaProvider(@RequestBody MfaProvider body) {
String zoneId = IdentityZoneHolder.get().getId(); String zoneId = IdentityZoneHolder.get().getId();
provider.setIdentityZoneId(zoneId); body.setIdentityZoneId(zoneId);
mfaProviderValidator.validate(provider); mfaProviderValidator.validate(body);
if(!StringUtils.hasText(provider.getConfig().getIssuer())){ if(!StringUtils.hasText(body.getConfig().getIssuer())){
provider.getConfig().setIssuer(IdentityZoneHolder.get().getName()); body.getConfig().setIssuer(IdentityZoneHolder.get().getName());
} }
MfaProvider created = mfaProviderProvisioning.create(provider,zoneId); MfaProvider created = mfaProviderProvisioning.create(body,zoneId);
return new ResponseEntity<>(created, HttpStatus.CREATED); return new ResponseEntity<>(created, HttpStatus.CREATED);
} }
@RequestMapping(value = "{id}", method = PUT)
public ResponseEntity<MfaProvider> updateMfaProvider(@PathVariable String id, @RequestBody MfaProvider body) {
String zoneId = IdentityZoneHolder.get().getId();
mfaProviderProvisioning.retrieve(id, zoneId);
body.setId(id);
body.setIdentityZoneId(zoneId);
mfaProviderValidator.validate(body);

MfaProvider updated = mfaProviderProvisioning.update(body, zoneId);
return new ResponseEntity<>(updated, HttpStatus.OK);
}


@RequestMapping(method = GET) @RequestMapping(method = GET)
public ResponseEntity<List<MfaProvider>> retrieveMfaProviders() { public ResponseEntity<List<MfaProvider>> retrieveMfaProviders() {
Expand Down Expand Up @@ -79,4 +90,5 @@ public void setMfaProviderProvisioning(MfaProviderProvisioning mfaProviderProvis
public void setMfaProviderValidator(MfaProviderValidator mfaProviderValidator) { public void setMfaProviderValidator(MfaProviderValidator mfaProviderValidator) {
this.mfaProviderValidator = mfaProviderValidator; this.mfaProviderValidator = mfaProviderValidator;
} }

} }
Expand Up @@ -5,6 +5,8 @@
public interface MfaProviderProvisioning { public interface MfaProviderProvisioning {
MfaProvider create(MfaProvider provider, String zoneId); MfaProvider create(MfaProvider provider, String zoneId);


MfaProvider update(MfaProvider provider, String zoneId);

MfaProvider retrieve(String id, String zoneId); MfaProvider retrieve(String id, String zoneId);


List<MfaProvider> retrieveAll(String zoneId); List<MfaProvider> retrieveAll(String zoneId);
Expand Down
Expand Up @@ -7,6 +7,7 @@
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;


import java.util.List; import java.util.List;

import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
Expand Down Expand Up @@ -38,6 +39,28 @@ public void testCreateAndRetrieve() {
assertEquals(mfaProvider.getConfig(), retrieved.getConfig()); assertEquals(mfaProvider.getConfig(), retrieved.getConfig());
} }


@Test
public void testCreateAndUpdate() {
MfaProvider mfaProvider = constructGoogleProvider();
String zoneId = IdentityZoneHolder.get().getId();
assertEquals(0, (int) jdbcTemplate.queryForObject("select count(*) from mfa_providers where identity_zone_id=? and name=?", new Object[]{zoneId, mfaProvider.getName()}, Integer.class));

MfaProvider created = mfaProviderProvisioning.create(mfaProvider, zoneId);
assertNotNull(created);
assertEquals(1, (int) jdbcTemplate.queryForObject("select count(*) from mfa_providers where identity_zone_id=? and id=?", new Object[]{zoneId, created.getId()}, Integer.class));

mfaProvider = created;
mfaProvider.setName("UpdatedName");
mfaProvider.getConfig().setIssuer("new issuer");

MfaProvider updated = mfaProviderProvisioning.update(created, zoneId);
assertNotNull(updated);

MfaProvider retrieved = mfaProviderProvisioning.retrieve(created.getId(), zoneId);
assertEquals(mfaProvider.getName(), retrieved.getName());
assertEquals(mfaProvider.getConfig().getIssuer(), retrieved.getConfig().getIssuer());
}

@Test @Test
public void testRetrieveAll() { public void testRetrieveAll() {
String zoneId = IdentityZoneHolder.get().getId(); String zoneId = IdentityZoneHolder.get().getId();
Expand Down
Expand Up @@ -38,7 +38,7 @@ public void setup() {
} }


@Test @Test
public void testDefaultIssuer() { public void testCreateDefaultIssuer() {
MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider(); MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider();
Mockito.when(provisioning.create(Mockito.any(), Mockito.anyString())).thenReturn(mfaProvider); Mockito.when(provisioning.create(Mockito.any(), Mockito.anyString())).thenReturn(mfaProvider);


Expand All @@ -47,6 +47,22 @@ public void testDefaultIssuer() {
assertEquals(IdentityZoneHolder.get().getName(), mfaProviderResponseEntity.getBody().getConfig().getIssuer()); assertEquals(IdentityZoneHolder.get().getName(), mfaProviderResponseEntity.getBody().getConfig().getIssuer());
} }


@Test
public void testUpdateProvider() {
MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider();
Mockito.when(provisioning.create(Mockito.any(), Mockito.anyString())).thenReturn(mfaProvider);
Mockito.when(provisioning.update(Mockito.any(), Mockito.anyString())).thenReturn(mfaProvider);

mfaProvider = endpoint.createMfaProvider(mfaProvider).getBody();
mfaProvider.setId("providerId");
mfaProvider.setName("UpdatedName");

MfaProvider<GoogleMfaProviderConfig> updatedMfaProvider = endpoint.updateMfaProvider(mfaProvider.getId(), mfaProvider).getBody();

assertEquals("UpdatedName", updatedMfaProvider.getName());
assertEquals(mfaProvider.getId(), updatedMfaProvider.getId());
}

@Test @Test
public void testGetMfaProviders() { public void testGetMfaProviders() {
MfaProvider<GoogleMfaProviderConfig> mockProviderResponse = constructGoogleProvider(); MfaProvider<GoogleMfaProviderConfig> mockProviderResponse = constructGoogleProvider();
Expand Down
3 changes: 3 additions & 0 deletions uaa/src/main/webapp/WEB-INF/spring/multitenant-endpoints.xml
Expand Up @@ -110,6 +110,9 @@
<intercept-url pattern="/mfa-providers" <intercept-url pattern="/mfa-providers"
access="#oauth2.hasScopeInAuthZone('zones.{zone.id}.admin')" access="#oauth2.hasScopeInAuthZone('zones.{zone.id}.admin')"
method="GET"/> method="GET"/>
<intercept-url pattern="/mfa-providers/*"
access="#oauth2.hasScopeInAuthZone('zones.{zone.id}.admin')"
method="PUT"/>
<intercept-url pattern="/mfa-providers/*" <intercept-url pattern="/mfa-providers/*"
access="#oauth2.hasScopeInAuthZone('zones.{zone.id}.admin')" access="#oauth2.hasScopeInAuthZone('zones.{zone.id}.admin')"
method="GET"/> method="GET"/>
Expand Down
Expand Up @@ -15,8 +15,6 @@
import org.springframework.restdocs.headers.HeaderDescriptor; import org.springframework.restdocs.headers.HeaderDescriptor;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.FieldDescriptor; import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.request.ParameterDescriptor;
import org.springframework.restdocs.request.RequestDocumentation;
import org.springframework.restdocs.snippet.Snippet; import org.springframework.restdocs.snippet.Snippet;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
Expand All @@ -39,7 +37,6 @@
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


Expand Down Expand Up @@ -104,6 +101,33 @@ public void testCreateGoogleMfaProvider() throws Exception {
); );
} }



@Test
public void testUpdateGoogleMfaProvider() throws Exception {
MfaProvider<GoogleMfaProviderConfig> mfaProvider = createMfaProviderHelper(getGoogleMfaProvider());

FieldDescriptor[] idempotentFields = getGoogleMfaProviderFields();
Snippet requestFields = requestFields(idempotentFields);

Snippet responseFields = responseFields(getMfaProviderResponseFields(idempotentFields));
getMockMvc().perform(RestDocumentationRequestBuilders.put("/mfa-providers/{id}", mfaProvider.getId())
.accept(APPLICATION_JSON)
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(serializeExcludingProperties(mfaProvider, "id", "created", "last_modified", "identityZoneId")))
.andExpect(status().isOk())
.andDo(document("{ClassName}/{methodName}",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestHeaders(
MFA_AUTHORIZATION_HEADER,
IDENTITY_ZONE_ID_HEADER
),
requestFields,
responseFields)
);
}

private FieldDescriptor[] getGoogleMfaProviderFields() { private FieldDescriptor[] getGoogleMfaProviderFields() {
return (FieldDescriptor[]) ArrayUtils.addAll(commonProviderFields, new FieldDescriptor[]{ return (FieldDescriptor[]) ArrayUtils.addAll(commonProviderFields, new FieldDescriptor[]{
fieldWithPath("config.algorithm").optional("SHA256").type(STRING).description("Algorithm"), fieldWithPath("config.algorithm").optional("SHA256").type(STRING).description("Algorithm"),
Expand Down
Expand Up @@ -27,6 +27,7 @@
import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;


public class MfaProviderEndpointsMockMvcTests extends InjectedMockContextTest { public class MfaProviderEndpointsMockMvcTests extends InjectedMockContextTest {


Expand Down Expand Up @@ -68,6 +69,57 @@ public void testCreateGoogleMfaProviderInvalidType() throws Exception {
Assert.assertEquals(HttpStatus.UNPROCESSABLE_ENTITY.value(), authorization.andReturn().getResponse().getStatus()); Assert.assertEquals(HttpStatus.UNPROCESSABLE_ENTITY.value(), authorization.andReturn().getResponse().getStatus());
} }


@Test
public void testUpdateGoogleMfaProviderInvalidType() throws Exception {
MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider();
mfaProvider.setConfig(null);
MvcResult mfaResponse = getMockMvc().perform(
post("/mfa-providers")
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaProvider))).andReturn();

mfaProvider = JsonUtils.readValue(mfaResponse.getResponse().getContentAsString(), MfaProvider.class);

ObjectNode mfaAsJSON = (ObjectNode) JsonUtils.readTree(JsonUtils.writeValueAsString(mfaProvider));
mfaAsJSON.put("type", "not-google-authenticator");
ResultActions authorization = getMockMvc().perform(
put("/mfa-providers/" + mfaProvider.getId())
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaAsJSON)));
Assert.assertEquals(HttpStatus.UNPROCESSABLE_ENTITY.value(), authorization.andReturn().getResponse().getStatus());
}


@Test
public void testCreateAndUpdateMfaProvider() throws Exception {
MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider();
mfaProvider.setConfig(null);
MvcResult mfaResponse = getMockMvc().perform(
post("/mfa-providers")
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaProvider))).andReturn();

mfaProvider = JsonUtils.readValue(mfaResponse.getResponse().getContentAsString(), MfaProvider.class);

mfaProvider.setName("UpdatedName");
mfaProvider.getConfig().setDigits(13);

MvcResult updateResponse = getMockMvc().perform(
put("/mfa-providers/" + mfaProvider.getId())
.header("Authorization", "Bearer " + adminToken)
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaProvider))).andReturn();

MfaProvider<GoogleMfaProviderConfig> updatedProvider = JsonUtils.readValue(updateResponse.getResponse().getContentAsString(), MfaProvider.class);

Assert.assertEquals(HttpStatus.OK.value(), updateResponse.getResponse().getStatus());
Assert.assertEquals(13, updatedProvider.getConfig().getDigits());
Assert.assertEquals("UpdatedName", updatedProvider.getName());

}


@Test @Test
public void testRetrieveMfaProviders() throws Exception { public void testRetrieveMfaProviders() throws Exception {
Expand Down Expand Up @@ -108,6 +160,39 @@ public void testCreateMfaForOtherZone() throws Exception{
Assert.assertEquals(HttpStatus.CREATED.value(), mfaResponse.getResponse().getStatus()); Assert.assertEquals(HttpStatus.CREATED.value(), mfaResponse.getResponse().getStatus());
} }


@Test
public void testUpdateMfaForOtherZone() throws Exception{
IdentityZone identityZone = MockMvcUtils.utils().createZoneUsingWebRequest(getMockMvc(), adminToken);

MfaProvider<GoogleMfaProviderConfig> mfaProvider = constructGoogleProvider();
MvcResult mfaResponse = getMockMvc().perform(
post("/mfa-providers")
.header("Authorization", "Bearer " + adminToken)
.header(IdentityZoneSwitchingFilter.HEADER, identityZone.getId())
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaProvider))).andReturn();
Assert.assertEquals(HttpStatus.CREATED.value(), mfaResponse.getResponse().getStatus());

mfaProvider = JsonUtils.readValue(mfaResponse.getResponse().getContentAsString(), MfaProvider.class);

mfaProvider.setName("UpdatedName");
mfaProvider.getConfig().setDigits(13);

MvcResult updateResponse = getMockMvc().perform(
put("/mfa-providers/" + mfaProvider.getId())
.header("Authorization", "Bearer " + adminToken)
.header(IdentityZoneSwitchingFilter.HEADER, identityZone.getId())
.contentType(APPLICATION_JSON)
.content(JsonUtils.writeValueAsString(mfaProvider))).andReturn();
Assert.assertEquals(HttpStatus.OK.value(), updateResponse.getResponse().getStatus());

MfaProvider<GoogleMfaProviderConfig> updatedProvider = JsonUtils.readValue(updateResponse.getResponse().getContentAsString(), MfaProvider.class);
Assert.assertEquals(13, updatedProvider.getConfig().getDigits());
Assert.assertEquals("UpdatedName", updatedProvider.getName());

}


@Test @Test
public void testGetMfaInOtherZone() throws Exception{ public void testGetMfaInOtherZone() throws Exception{
IdentityZone identityZone = MockMvcUtils.utils().createZoneUsingWebRequest(getMockMvc(), adminToken); IdentityZone identityZone = MockMvcUtils.utils().createZoneUsingWebRequest(getMockMvc(), adminToken);
Expand Down

0 comments on commit 19a000d

Please sign in to comment.