public class PermissionsBinder implements TypeBinder {
private String fieldName = "permissions";
private String operationName = "read";
public PermissionsBinder fieldName(String fieldName) {
this.fieldName = fieldName;
return this;
}
public PermissionsBinder operationName(String operationName) {
this.operationName = operationName;
return this;
}
@Override
public void bind(TypeBindingContext context) {
context.getDependencies().useRootOnly();
IndexFieldReference<String> permissionsField = context.getIndexSchemaElement()
.field(this.fieldName, f -> f.asString().analyzer("permissions"))
.toReference();
context.getIndexSchemaElement().filter("is-permission", new Filter())
.param("operation", operationName)
.param("field", this.fieldName)
.toReference();
context.setBridge(new Bridge(
permissionsField
));
}
private static class Bridge implements TypeBridge {
private final IndexFieldReference<String> permissionsField;
protected IdentityStoreResolver getIdentityService() {
IdentityStoreResolver isr = ServiceLocator.getService(IdentityStoreResolver.class, IdentityStoreResolver.JNDI_NAME);
return isr;
}
private Bridge(IndexFieldReference<String> permissionsField) {
this.permissionsField = permissionsField;
}
@Override
public void write(DocumentElement target, Object bridgedElement, TypeBridgeWriteContext context) {
StringBuilder brules = new StringBuilder();
IdentityStoreResolver isr = getIdentityService();
PermissionManager pm = isr.getPermissionManager();
List<Permission> permissions = pm.listPermissions(bridgedElement);
for (Permission permission : permissions) {
IdentityType assignee = permission.getAssignee();
if (assignee instanceof Group) {
String[] roles = permission.getRoles();
if (roles == null || roles.length < 1) {
roles = new String[]{"*"};
}
for (String role : roles) {
brules.append(permission.getOperation()).append(":");
brules.append(permission.getContext()).append(":");
brules.append(permission.getPath()).append(":");
brules.append(role);
brules.append("\n");
}
} else {
brules.append(permission.getOperation()).append(":");
brules.append(permission.getContext()).append(":");
brules.append(permission.getPath());
brules.append("\n");
}
}
target.addValue(this.permissionsField, brules.toString());
}
}
private static class Filter implements FilterFactory {
@Override
public SearchPredicate create(FilterFactoryContext ctx) {
SearchPredicate filter;
SearchPredicateFactory predicate = ctx.predicate();
Account user = ctx.param("user");
String fieldPath = ctx.resolvePath(ctx.param("field"));
String operation = ctx.param("operation");
if (operation == null) {
operation = "read";
}
PermissionQuery query = new PermissionQuery(fieldPath, operation, user);
filter = predicate.extension(LuceneExtension.get())
.fromLuceneQuery(query)
.toPredicate();
return filter;
}
}
}