Skip to content
This repository has been archived by the owner on Dec 12, 2018. It is now read-only.

Commit

Permalink
Initial work for saving Account custom data
Browse files Browse the repository at this point in the history
  • Loading branch information
bdemers committed Apr 28, 2017
1 parent 7566aa9 commit b0cebbb
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
data.remove("color");
}

data.save();
account.save();
}

req.setAttribute("birthday", birthday);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.stormpath.sdk.impl.resource.Property;
import com.stormpath.sdk.lang.Assert;
import com.stormpath.sdk.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.AbstractMap;
import java.util.ArrayList;
Expand All @@ -38,6 +40,7 @@
*/
public class DefaultCustomData extends AbstractInstanceResource implements CustomData {

private static final Logger log = LoggerFactory.getLogger(DefaultCustomData.class);
static final DateProperty CREATED_AT = new DateProperty("createdAt");
static final DateProperty MODIFIED_AT = new DateProperty("modifiedAt");

Expand Down Expand Up @@ -225,6 +228,13 @@ public void save() {
if (isDirty()) {
this.writeLock.lock();
try{

// return if href ends with '/okta-custom-data'
if (getHref().endsWith("/okta-custom-data")) {
log.warn("Custom Data cannot be updated directly when using Okta's API, use Account.save() instead.");
return;
}

if (hasRemovedProperties()) {
deleteRemovedProperties();
}
Expand All @@ -241,6 +251,11 @@ public void deleteRemovedProperties() {
this.writeLock.lock();
try {

// cannot save custom data for accounts directly
if (getHref().endsWith("/okta-custom-data")) {
return;
}

Set<String> deletedPropertyNames = this.getDeletedPropertyNames();
for (String deletedPropertyName : deletedPropertyNames) {
getDataStore().deleteResourceProperty(this, deletedPropertyName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,13 @@ public ResourceDataResult filter(final ResourceDataRequest req) {
QueryString qs = uri.getQuery();

HttpHeaders httpHeaders = req.getHttpHeaders();
Request request = new DefaultRequest(HttpMethod.POST, href, qs, httpHeaders, body, length);

// if this is an Okta user, we must use a PUT and not a POST
HttpMethod method = HttpMethod.POST;
if (href.matches(".*\\/api\\/v1\\/users\\/\\w*$") && !create) {
method = HttpMethod.PUT;
}
Request request = new DefaultRequest(method, href, qs, httpHeaders, body, length);

Response response = execute(request);
Map<String, Object> responseBody = getBody(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.stormpath.sdk.saml.AttributeStatementMappingRules;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -51,17 +52,23 @@ public DefaultResourceConverter(ReferenceFactory referenceFactory) {
@Override
public Map<String, Object> convert(AbstractResource resource) {
Assert.notNull(resource, "resource cannot be null.");
return toMap(resource, true);

boolean updateBoth = false;
if (resource.getHref() != null && resource.getHref().matches(".*\\/api\\/v1\\/users\\/\\w*$")) {
updateBoth = true;
}
return toMap(resource, true, updateBoth);
}

private LinkedHashMap<String, Object> toMap(final AbstractResource resource, boolean partialUpdate) {
private LinkedHashMap<String, Object> toMap(final AbstractResource resource, boolean partialUpdate, boolean updateBoth) {

Set<String> propNames;
Set<String> propNames = new HashSet<>();

if (partialUpdate) {
propNames = resource.getUpdatedPropertyNames();
} else {
propNames = resource.getPropertyNames();
if (partialUpdate || updateBoth) {
propNames.addAll(resource.getUpdatedPropertyNames());
}
if (!partialUpdate || updateBoth) {
propNames.addAll(resource.getPropertyNames());
}

LinkedHashMap<String, Object> props = new LinkedHashMap<>(propNames.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ public static Map<String, Object> toAccount(Map<String, Object> userMap, String
// build full name
nullSafePut(accountMap, STORMPATH_FULL_NAME, buildFullName(profileMap.get(OKTA_FIRST_NAME), profileMap.get(OKTA_LAST_NAME)));
// everything not in this lis is considered customData
nullSafePut(accountMap, STORMPATH_CUSTOM_DATA, trimMap(profileMap, OKTA_LOGIN, OKTA_EMAIL, OKTA_FIRST_NAME, OKTA_MIDDLE_NAME, OKTA_LAST_NAME, OKTA_EMAIL_VERIFICATION_STATUS, STORMPATH_EMAIL_VERIFICATION_TOKEN));
Map<String, Object> customData = trimMap(profileMap, OKTA_LOGIN, OKTA_EMAIL, OKTA_FIRST_NAME, OKTA_MIDDLE_NAME, OKTA_LAST_NAME, OKTA_EMAIL_VERIFICATION_STATUS, STORMPATH_EMAIL_VERIFICATION_TOKEN);
customData.put(STORMPATH_HREF, baseUrl + OktaApiPaths.USERS + userMap.get(OKTA_ID) +"/okta-custom-data");
nullSafePut(accountMap, STORMPATH_CUSTOM_DATA, customData);

}

nullSafePut(accountMap, STORMPATH_CREATED_AT, userMap.get(OKTA_CREATED));
Expand Down Expand Up @@ -207,7 +210,9 @@ public static Map<String, Object> toUser(Map<String, Object> accountMap) {

// custom data, just drop it in profile map
if (accountMap.containsKey(STORMPATH_CUSTOM_DATA)) {
profileMap.putAll(getPropertyMap(accountMap, STORMPATH_CUSTOM_DATA));

Map<String, Object> customData = trimMap(getPropertyMap(accountMap, STORMPATH_CUSTOM_DATA), STORMPATH_HREF);
profileMap.putAll(customData);

String recoveryAnswer = (String) profileMap.get(RECOVERY_WORK_AROUND_KEY);

Expand Down

0 comments on commit b0cebbb

Please sign in to comment.