use of io.jans.scim.model.scim2.annotations.Attribute in project jans by JanssenProject.
the class IntrospectUtil method traverseClassForNames.
private static void traverseClassForNames(Class clazz, String prefix, List<Field> extraFields, boolean prune) throws Exception {
List<Field> fields = new ArrayList<>();
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
fields.addAll(extraFields);
for (Field f : fields) {
Attribute attrAnnot = f.getAnnotation(Attribute.class);
if (attrAnnot != null) {
String name = f.getName();
if (prefix.length() > 0)
name = prefix + "." + name;
switch(attrAnnot.returned()) {
case ALWAYS:
alwaysAttrsNames.add(name);
break;
case DEFAULT:
defaultAttrsNames.add(name);
break;
case NEVER:
neverAttrsNames.add(name);
break;
case REQUEST:
requestAttrsNames.add(name);
break;
}
if (attrAnnot.isRequired())
requiredAttrsNames.add(name);
if (attrAnnot.canonicalValues().length > 0)
canonicalizedAttrsNames.add(name);
Validator vAnnot = f.getAnnotation(Validator.class);
if (vAnnot != null)
validableAttrsNames.add(name);
if (!prune && attrAnnot.type().equals(AttributeDefinition.Type.COMPLEX)) {
// Use <T> parameter of Collection if present
Class cls = attrAnnot.multiValueClass();
if (cls.equals(NullType.class)) {
cls = f.getType();
}
if (clazz.equals(cls)) {
// Prevent infinite loop
prune = true;
}
traverseClassForNames(cls, name, new ArrayList<>(), prune);
}
}
}
}
use of io.jans.scim.model.scim2.annotations.Attribute in project jans by JanssenProject.
the class ScimResourceUtil method traverse.
void traverse(String prefix, Map<String, Object> source, Map<String, Object> destination, boolean replacing) {
for (String key : source.keySet()) {
Object value = source.get(key);
Object destValue = destination.get(key);
if (value != null && error == null) {
// Atributes related to extensions evaluate null here
Attribute attrAnnot = IntrospectUtil.getFieldAnnotation(getNewPrefix(prefix, key), base, Attribute.class);
if (attrAnnot != null && !attrAnnot.mutability().equals(READ_ONLY)) {
if (value instanceof Map) {
value = smallerMap(getNewPrefix(prefix, key), IntrospectUtil.strObjMap(value), destValue, replacing);
} else if (attrAnnot.mutability().equals(IMMUTABLE) && destValue != null && !value.equals(destValue)) {
// provokes no more traversals
error = "Invalid value passed for immutable attribute " + key;
value = null;
}
if (value != null) {
if (IntrospectUtil.isCollection(value.getClass())) {
Collection col = (Collection) value;
int size = col.size();
if (!replacing) {
// we need to add to the existing collection
if (destValue != null) {
if (IntrospectUtil.isCollection(destValue.getClass()))
col.addAll((Collection) destValue);
else
log.warn("Value {} was expected to be a collection", destValue);
}
}
// Do the arrangement so that only one primary="true" can stay in data
value = col.isEmpty() ? null : adjustPrimarySubAttributes(col, size);
}
destination.put(key, value);
}
}
}
}
}
use of io.jans.scim.model.scim2.annotations.Attribute in project jans by JanssenProject.
the class ComplexSearchUserTest method searchSortByDate.
// This test is disabled to avoid problems in attribute excludeMetaLastMod being inconsistent with updatedAt in testing server
// @Test
public void searchSortByDate() {
SearchRequest sr = new SearchRequest();
sr.setFilter("userName pr");
sr.setSortBy("meta.lastModified");
sr.setAttributes(Collections.singletonList(sr.getSortBy()));
Response response = client.searchUsersPost(sr);
assertEquals(response.getStatus(), OK.getStatusCode());
ListResponse listResponse = response.readEntity(ListResponse.class);
UserResource[] users = listResponse.getResources().stream().map(usrClass::cast).collect(Collectors.toList()).toArray(new UserResource[0]);
for (int i = 1; i < users.length; i++) {
String lastMod1 = users[i - 1].getMeta() == null ? null : users[i - 1].getMeta().getLastModified();
String lastMod2 = users[i].getMeta() == null ? null : users[i].getMeta().getLastModified();
if (// Both being non null is OK
lastMod1 != null)
assertNotNull(lastMod2);
if (// If second is null, first must be
lastMod2 == null)
assertNull(lastMod1);
if (lastMod1 != null && lastMod2 != null) {
ZonedDateTime dt1 = ZonedDateTime.parse(lastMod1);
ZonedDateTime dt2 = ZonedDateTime.parse(lastMod2);
assertTrue(dt1.isEqual(dt2) || dt1.isBefore(dt2));
}
}
}
use of io.jans.scim.model.scim2.annotations.Attribute in project jans by JanssenProject.
the class Fido2DeviceTest method updateWithObject.
@Test(dependsOnMethods = "updateWithJson")
public void updateWithObject() throws Exception {
logger.debug("Updating device to original attributes");
Response response = client.updateF2Device(device, device.getId(), null, null);
assertEquals(response.getStatus(), OK.getStatusCode());
Fido2DeviceResource updated = response.readEntity(fido2Class);
// Naively compare (property-to-property) the original and new object. It's feasible since all of them are strings
for (String path : IntrospectUtil.allAttrs.get(fido2Class)) {
String val = BeanUtils.getProperty(device, path);
// Exclude metas since they diverge and skip if original attribute was null (when passing null for an update, server ignores)
if (!path.startsWith("meta") && val != null) {
assertEquals(BeanUtils.getProperty(updated, path), val);
}
}
// Update an immutable attribute
updated.setCounter(Integer.MIN_VALUE);
response = client.updateF2Device(updated, updated.getId(), null, null);
assertEquals(response.getStatus(), BAD_REQUEST.getStatusCode());
}
use of io.jans.scim.model.scim2.annotations.Attribute in project jans by JanssenProject.
the class FilterListener method enterAttrexp.
@Override
public void enterAttrexp(ScimFilterParser.AttrexpContext ctx) {
if (StringUtils.isEmpty(error)) {
log.trace("enterAttrexp.");
String path = ctx.attrpath().getText();
ScimFilterParser.CompvalueContext compValueCtx = ctx.compvalue();
boolean isPrRule = compValueCtx == null && ctx.getChild(1).getText().equals("pr");
Type attrType = null;
Attribute attrAnnot = IntrospectUtil.getFieldAnnotation(path, resourceClass, Attribute.class);
String ldapAttribute = null;
boolean isNested = false;
Boolean multiValued = false;
if (attrAnnot == null) {
ExtensionField field = extService.getFieldOfExtendedAttribute(resourceClass, path);
if (field == null) {
error = String.format("Attribute path '%s' is not recognized in %s", path, resourceClass.getSimpleName());
} else {
attrType = field.getAttributeDefinitionType();
multiValued = field.isMultiValued();
ldapAttribute = path.substring(path.lastIndexOf(":") + 1);
}
} else {
attrType = attrAnnot.type();
Pair<String, Boolean> pair = FilterUtil.getLdapAttributeOfResourceAttribute(path, resourceClass);
ldapAttribute = pair.getFirst();
isNested = pair.getSecond();
multiValued = computeMultivaluedForCoreAttribute(path, attrAnnot, ldapAttribute);
}
if (error != null) {
// Intentionally left empty
} else if (attrType == null) {
error = String.format("Could not determine type of attribute path '%s' in %s", path, resourceClass.getSimpleName());
} else if (ldapAttribute == null) {
error = String.format("Could not determine LDAP attribute for path '%s' in %s", path, resourceClass.getSimpleName());
} else {
String subattr = isNested ? path.substring(path.lastIndexOf(".") + 1) : null;
CompValueType type;
ScimOperator operator;
if (isPrRule) {
type = CompValueType.NULL;
operator = ScimOperator.NOT_EQUAL;
} else {
type = FilterUtil.getCompValueType(compValueCtx);
operator = ScimOperator.getByValue(ctx.compareop().getText());
}
error = FilterUtil.checkFilterConsistency(path, attrType, type, operator);
if (error == null) {
Pair<Filter, String> subf = subFilterGenerator.build(subattr, ldapAttribute, isPrRule ? null : compValueCtx.getText(), attrType, type, operator, multiValued);
Filter subFilth = subf.getFirst();
error = subf.getSecond();
if (subFilth == null) {
if (error == null) {
error = String.format("Operator '%s' is not supported for attribute %s", operator.getValue(), path);
}
} else {
filter.push(subFilth);
}
}
}
}
}
Aggregations