Skip to content
This repository was archived by the owner on Dec 12, 2018. It is now read-only.
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
23 changes: 13 additions & 10 deletions impl/src/main/java/com/stormpath/sdk/impl/ds/DefaultDataStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

import com.stormpath.sdk.api.ApiKey;
import com.stormpath.sdk.cache.CacheManager;
import com.stormpath.sdk.impl.api.ApiKeyResolver;
import com.stormpath.sdk.impl.authc.credentials.ClientCredentials;
import com.stormpath.sdk.http.HttpMethod;
import com.stormpath.sdk.impl.api.ApiKeyResolver;
import com.stormpath.sdk.impl.authc.credentials.ApiKeyCredentials;
import com.stormpath.sdk.impl.authc.credentials.ClientCredentials;
import com.stormpath.sdk.impl.cache.DisabledCacheManager;
import com.stormpath.sdk.impl.ds.api.ApiKeyQueryFilter;
import com.stormpath.sdk.impl.ds.api.DecryptApiKeySecretFilter;
Expand All @@ -42,6 +42,7 @@
import com.stormpath.sdk.impl.http.support.DefaultRequest;
import com.stormpath.sdk.impl.http.support.UserAgent;
import com.stormpath.sdk.impl.oauth.OAuthTokenRevoked;
import com.stormpath.sdk.impl.provider.IdentityProviderType;
import com.stormpath.sdk.impl.query.DefaultCriteria;
import com.stormpath.sdk.impl.query.DefaultOptions;
import com.stormpath.sdk.impl.resource.AbstractResource;
Expand Down Expand Up @@ -274,21 +275,23 @@ public <T extends Resource, R extends T> R getResource(String href, Class<T> par
Assert.notEmpty(idClassMap, "idClassMap cannot be null or empty.");

ResourceDataResult result = getResourceData(href, parent, null);
Map<String,?> data = result.getData();
Map<String, ?> data = result.getData();

if (Collections.isEmpty(data)) {
if (Collections.isEmpty(data) || !data.containsKey(childIdProperty)) {
throw new IllegalStateException(childIdProperty + " could not be found in: " + data + ".");
}

String childClassName = null;
Object val = data.get(childIdProperty);
if (val != null) {
childClassName = String.valueOf(val);
Object propertyValue = data.get(childIdProperty);
if (propertyValue == null) {
throw new IllegalStateException("No Class mapping could be found for " + childIdProperty + ".");
}
Class<? extends R> childClass = idClassMap.get(childClassName);

Class<? extends R> childClass = idClassMap.get(propertyValue.toString());

if (childClass == null) {
throw new IllegalStateException("No Class mapping could be found for " + childIdProperty + ".");
childClass = idClassMap.get(IdentityProviderType.DEFAULT.getNameKey());
Assert.state(childClass != null, "No Class mapping could be found to instantiate resource.");
log.warn("Could not find class for '{}' with value '{}'. Using '{}' as fallback.", childIdProperty, propertyValue, childClass);
}

return instantiate(childClass, data, result.getUri().getQuery());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import java.util.Map;

/**
* This DefaultProvider represents Stormpath as a Provider. For example, the provider of a Stormpath-owned directory is
* "stormpath".
* This DefaultProvider represents a {@link IdentityProviderType#DEFAULT} provider. For example, the provider of is
* "a-new-social-provider".
*
* @since 1.0.beta
*/
Expand All @@ -46,7 +46,7 @@ public Map<String, Property> getPropertyDescriptors() {

@Override
protected String getConcreteProviderId() {
return IdentityProviderType.STORMPATH.getNameKey();
return getString(PROVIDER_ID);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.stormpath.sdk.provider.*;
import com.stormpath.sdk.provider.saml.SamlProvider;
import com.stormpath.sdk.provider.saml.SamlProviderData;
import com.stormpath.sdk.provider.saml.StormpathProvider;

import java.util.Collections;
import java.util.HashMap;
Expand All @@ -31,7 +32,7 @@
*/
public enum IdentityProviderType {

STORMPATH("stormpath", Provider.class, ProviderData.class),
STORMPATH("stormpath", StormpathProvider.class, ProviderData.class),

FACEBOOK("facebook", FacebookProvider.class, FacebookProviderData.class),

Expand All @@ -50,7 +51,12 @@ public enum IdentityProviderType {
/**
* @since 1.0.RC8
*/
SAML("saml", SamlProvider.class, SamlProviderData.class);
SAML("saml", SamlProvider.class, SamlProviderData.class),

/**
* @since 1.2.0
*/
DEFAULT("default", Provider.class, ProviderData.class);

private static final Map<String, IdentityProviderType> IDENTITY_PROVIDER_MAP;
public static final Map<String, Class<? extends Provider>> IDENTITY_PROVIDER_CLASS_MAP;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2016 Stormpath, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stormpath.sdk.impl.provider.saml;

import com.stormpath.sdk.impl.ds.InternalDataStore;
import com.stormpath.sdk.impl.provider.AbstractProvider;
import com.stormpath.sdk.impl.provider.IdentityProviderType;
import com.stormpath.sdk.impl.resource.Property;
import com.stormpath.sdk.provider.saml.StormpathProvider;

import java.util.Map;

/**
* This DefaultProvider represents Stormpath as a Provider. For example, the provider of a Stormpath-owned directory is
* "stormpath".
*
* @since 1.2.2
*/
public class DefaultStormpathProvider extends AbstractProvider implements StormpathProvider {

private static final Map<String, Property> PROPERTY_DESCRIPTORS = createPropertyDescriptorMap(PROVIDER_ID, CREATED_AT, MODIFIED_AT);

public DefaultStormpathProvider(InternalDataStore dataStore) {
super(dataStore);
}

public DefaultStormpathProvider(InternalDataStore dataStore, Map<String, Object> properties) {
super(dataStore, properties);
}

@Override
public Map<String, Property> getPropertyDescriptors() {
return PROPERTY_DESCRIPTORS;
}

@Override
protected String getConcreteProviderId() {
return IdentityProviderType.STORMPATH.getNameKey();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import com.stormpath.sdk.impl.ds.InternalDataStore
import com.stormpath.sdk.impl.group.DefaultGroupList
import com.stormpath.sdk.impl.organization.DefaultOrganizationAccountStoreMappingList
import com.stormpath.sdk.impl.organization.DefaultOrganizationList
import com.stormpath.sdk.impl.provider.DefaultProvider
import com.stormpath.sdk.impl.provider.saml.DefaultStormpathProvider
import com.stormpath.sdk.impl.provider.IdentityProviderType
import com.stormpath.sdk.impl.resource.CollectionReference
import com.stormpath.sdk.impl.resource.ResourceReference
Expand Down Expand Up @@ -165,7 +165,7 @@ class DefaultDirectoryTest {
andReturn(new DefaultTenant(internalDataStore, properties.tenant))

expect(internalDataStore.getResource(properties.provider.href, Provider.class, "providerId", IdentityProviderType.IDENTITY_PROVIDER_CLASS_MAP))
.andReturn(new DefaultProvider(internalDataStore, properties.provider))
.andReturn(new DefaultStormpathProvider(internalDataStore, properties.provider))

expect(internalDataStore.instantiate(PasswordPolicy, properties.passwordPolicy)).
andReturn(new DefaultPasswordPolicy(internalDataStore, properties.passwordPolicy))
Expand Down Expand Up @@ -258,9 +258,9 @@ class DefaultDirectoryTest {
assertTrue(resource instanceof DefaultTenant && resource.getHref().equals(properties.tenant.href))

resource = defaultDirectory.getProvider()
assertTrue(resource instanceof DefaultProvider && resource.getHref().equals(properties.provider.href))
assertTrue(resource instanceof DefaultStormpathProvider && resource.getHref().equals(properties.provider.href))
resource = defaultDirectory.getProvider() //Second invocation must not internally call internalDataStore.getResource(...) as it is already fully available in the internal properties
assertTrue(resource instanceof DefaultProvider && resource.getHref().equals(properties.provider.href))
assertTrue(resource instanceof DefaultStormpathProvider && resource.getHref().equals(properties.provider.href))

resource = defaultDirectory.getPasswordPolicy()
assertTrue(resource instanceof DefaultPasswordPolicy && resource.getHref().equals(properties.passwordPolicy.href))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ import com.stormpath.sdk.api.ApiKey
import com.stormpath.sdk.cache.Caches
import com.stormpath.sdk.impl.api.ApiKeyResolver
import com.stormpath.sdk.impl.api.DefaultApiKeyResolver
import com.stormpath.sdk.impl.authc.credentials.ApiKeyCredentials
import com.stormpath.sdk.impl.application.DefaultApplication
import com.stormpath.sdk.impl.authc.credentials.ApiKeyCredentials
import com.stormpath.sdk.impl.http.RequestExecutor
import com.stormpath.sdk.impl.http.Response
import com.stormpath.sdk.impl.http.support.DefaultRequest
import com.stormpath.sdk.impl.provider.DefaultGoogleProviderData
import com.stormpath.sdk.impl.provider.IdentityProviderType
import com.stormpath.sdk.impl.query.DefaultOptions
import com.stormpath.sdk.impl.util.BaseUrlResolver
import com.stormpath.sdk.provider.*
import com.stormpath.sdk.provider.FacebookProvider
import com.stormpath.sdk.provider.GithubProvider
import com.stormpath.sdk.provider.GoogleProviderData
import com.stormpath.sdk.provider.Provider
import com.stormpath.sdk.provider.ProviderData
import com.stormpath.sdk.provider.Providers
import com.stormpath.sdk.query.Options
import com.stormpath.sdk.resource.Resource
import org.testng.annotations.Test
Expand Down Expand Up @@ -213,6 +218,45 @@ class DefaultDataStoreTest {
verify(requestExecutor, response, facebookProvider)
}


@Test
void getSpecificResourceUnknownProviderId() {
def requestExecutor = createStrictMock(RequestExecutor)
def response = createStrictMock(Response)
def facebookProvider = createStrictMock(FacebookProvider)
def apiKeyCredentials = createStrictMock(ApiKeyCredentials)
def apiKeyResolver = createStrictMock(ApiKeyResolver)

def responseMap = [href: "https://api.stormpath.com/v1/directories/5fgF3o89Ph5nbJzY6EVSct/provider",
createdAt: "2014-04-01T22:05:25.661Z",
modifiedAt: "2014-04-01T22:05:53.177Z",
clientId: "237396459765014",
clientSecret: "a93fae44d2a4f21d4de6201aae9b849a",
providerId: "unknown"
]
def mapMarshaller = new JacksonMapMarshaller();
// convert String into InputStream
InputStream is = new ByteArrayInputStream(mapMarshaller.marshal(responseMap).getBytes());

def childIdProperty = "providerId"
def map = IdentityProviderType.IDENTITY_PROVIDER_CLASS_MAP

expect(requestExecutor.executeRequest(anyObject(DefaultRequest))).andReturn(response)
expect(response.isError()).andReturn(false)
expect(response.hasBody()).andReturn(true)
expect(response.getBody()).andReturn(is)

replay(requestExecutor, response, facebookProvider)

def defaultDataStore = new DefaultDataStore(requestExecutor, "https://api.stormpath.com/v1", apiKeyCredentials, apiKeyResolver)

def provider = defaultDataStore.getResource("https://api.stormpath.com/v1/directories/5fgF3o89Ph5nbJzY6EVSct/provider", Provider, childIdProperty, map)

assertEquals "unknown", provider.getProviderId()

verify(requestExecutor, response, facebookProvider)
}

@Test
void getSpecificResourceNonexistentPropertyException() {
def requestExecutor = createStrictMock(RequestExecutor)
Expand Down Expand Up @@ -247,7 +291,47 @@ class DefaultDataStoreTest {
defaultDataStore.getResource("https://api.stormpath.com/v1/directories/5fgF3o89Ph5nbJzY6EVSct/provider", Provider, childIdProperty, map)
fail("should have thrown")
} catch (IllegalStateException e) {
assertEquals(e.getMessage(), "No Class mapping could be found for nonexistentProperty.")
assertTrue e.getMessage().contains("nonexistentProperty could not be found in:"), "Message '${e.getMessage()}' doesn't contain expected: 'nonexistentProperty could not be found in:' "
}

verify(requestExecutor, response, facebookProvider)
}

@Test
void getSpecificResourceNullProviderIdExceptionIsThrown() {
def requestExecutor = createStrictMock(RequestExecutor)
def response = createStrictMock(Response)
def facebookProvider = createStrictMock(FacebookProvider)
def apiKeyCredentials = createStrictMock(ApiKeyCredentials)
def apiKeyResolver = createStrictMock(ApiKeyResolver)

def responseMap = [href: "https://api.stormpath.com/v1/directories/5fgF3o89Ph5nbJzY6EVSct/provider",
createdAt: "2014-04-01T22:05:25.661Z",
modifiedAt: "2014-04-01T22:05:53.177Z",
clientId: "237396459765014",
clientSecret: "a93fae44d2a4f21d4de6201aae9b849a",
providerId: null
]
def mapMarshaller = new JacksonMapMarshaller();
// convert String into InputStream
InputStream is = new ByteArrayInputStream(mapMarshaller.marshal(responseMap).getBytes())

def childIdProperty = "providerId"
def map = IdentityProviderType.IDENTITY_PROVIDER_CLASS_MAP

expect(requestExecutor.executeRequest(anyObject(DefaultRequest))).andReturn(response)
expect(response.isError()).andReturn(false)
expect(response.hasBody()).andReturn(true)
expect(response.getBody()).andReturn(is)

replay(requestExecutor, response, facebookProvider)

def defaultDataStore = new DefaultDataStore(requestExecutor, "https://api.stormpath.com/v1", apiKeyCredentials, apiKeyResolver)
try {
defaultDataStore.getResource("https://api.stormpath.com/v1/directories/5fgF3o89Ph5nbJzY6EVSct/provider", Provider, childIdProperty, map)
fail("should have thrown")
} catch (IllegalStateException e) {
assertEquals e.getMessage(), "No Class mapping could be found for providerId."
}

verify(requestExecutor, response, facebookProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ class DefaultProviderTest {

def properties = [href: "https://api.stormpath.com/v1/directories/iouertnw48ufsjnsDFSf/provider",
createdAt: "2013-10-01T23:38:55.000Z",
modifiedAt: "2013-10-02T23:38:55.000Z"
modifiedAt: "2013-10-02T23:38:55.000Z",
providerId: "my-social-thing"
]

def internalDataStore = createStrictMock(InternalDataStore)
def provider = new DefaultProvider(internalDataStore, properties)

assertEquals(provider.getHref(), "https://api.stormpath.com/v1/directories/iouertnw48ufsjnsDFSf/provider")
assertEquals(provider.getProviderId(), "stormpath")
assertEquals(provider.getProviderId(), "my-social-thing")
assertEquals(provider.getCreatedAt().format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT")), "2013-10-01T23:38:55.000Z")
assertEquals(provider.getModifiedAt().format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT")) , "2013-10-02T23:38:55.000Z")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2016 Stormpath, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.stormpath.sdk.impl.provider

import com.stormpath.sdk.impl.ds.InternalDataStore
import com.stormpath.sdk.impl.provider.saml.DefaultStormpathProvider
import com.stormpath.sdk.impl.resource.DateProperty
import com.stormpath.sdk.impl.resource.StringProperty
import com.stormpath.sdk.provider.Provider
import org.testng.annotations.Test

import static org.easymock.EasyMock.createStrictMock
import static org.testng.Assert.assertEquals
import static org.testng.Assert.assertTrue

/**
* @since 1.2.2
*/
class DefaultStormpathProviderTest {

@Test
void testGetPropertyDescriptors() {

def provider = new DefaultStormpathProvider(createStrictMock(InternalDataStore))

def propertyDescriptors = provider.getPropertyDescriptors()

assertEquals(propertyDescriptors.size(), 3)

assertTrue(propertyDescriptors.get("providerId") instanceof StringProperty)
assertTrue(propertyDescriptors.get("createdAt") instanceof DateProperty)
assertTrue(propertyDescriptors.get("modifiedAt") instanceof DateProperty)
assertTrue(Provider.isInstance(provider))
}

@Test
void testMethods() {

def properties = [href: "https://api.stormpath.com/v1/directories/iouertnw48ufsjnsDFSf/provider",
createdAt: "2013-10-01T23:38:55.000Z",
modifiedAt: "2013-10-02T23:38:55.000Z",
]

def internalDataStore = createStrictMock(InternalDataStore)
def provider = new DefaultStormpathProvider(internalDataStore, properties)

assertEquals(provider.getHref(), "https://api.stormpath.com/v1/directories/iouertnw48ufsjnsDFSf/provider")
assertEquals(provider.getProviderId(), "stormpath")
assertEquals(provider.getCreatedAt().format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT")), "2013-10-01T23:38:55.000Z")
assertEquals(provider.getModifiedAt().format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("GMT")) , "2013-10-02T23:38:55.000Z")
}

}
Loading