How to extend user schema using WSO2 charon scim library - wso2

I am creating a SCIM server using Charon library. How to extend user schema using WSO2 charon scim library?

You have two options to extend the schema using charon library.
Option 1:
Define the attribute definitions in a file and build the schema using the file.
When writing that file, the final config in the configuration file should be the definition of the extension.
Method to use in charon: https://github.com/wso2/charon/blob/27562f69ce5b23b4e85015daf5aa11c651a91a8c/modules/charon-core/src/main/java/org/wso2/charon3/core/config/SCIMUserSchemaExtensionBuilder.java#L63
sample java code to build schema using this method:
String schemaFilePath = "<absolute path to the schema defined file>";
SCIMUserSchemaExtensionBuilder.getInstance().buildUserSchemaExtension(schemaFilePath);
AttributeSchema extensionSchema = SCIMUserSchemaExtensionBuilder.getInstance().getExtensionSchema();
// print the attribute URIs in the built schema
extensionSchema.getSubAttributeSchemas().stream().forEach(e->System.out.print(e.getURI() + "\n"));
refer: https://github.com/AnuradhaSK/schema-extension/blob/cea1fa636bea2bb1e599ac9c71c6c45eaa339199/src/main/java/ScimSchemas.java#L29-L35
Format of the file: https://github.com/AnuradhaSK/schema-extension/blob/main/src/main/resources/custom-schema
Option 2:
Use SCIMCustomSchemaExtensionBuilder in charon.
You have to define the extended schema URI first.
Then create
SCIMCustomAttribute objects for each attribute you need to add to the extended schema. You have to define the default set of attribute properties mentioned in the scim schema for an attribute
Finally create another SCIMCustomAttribute to represent the extended schema
Put all objects to a List and call buildUserCustomSchemaExtension method in SCIMCustomSchemaExtensionBuilder
Method to use in charon:
https://github.com/wso2/charon/blob/27562f69ce5b23b4e85015daf5aa11c651a91a8c/modules/charon-core/src/main/java/org/wso2/charon3/core/config/SCIMCustomSchemaExtensionBuilder.java#L71
sample java code:
SCIMCustomSchemaExtensionBuilder.getInstance().setURI("urn:scim:custom:extended:schemas");
LOG.info("====Attributes of extended schema using custom attributes===");
// Sub attribute of the schema.
Map<String, String> subAttributeProperties = new HashMap<>();
subAttributeProperties.put("attributeURI","urn:scim:custom:extended:schemas:vehicleNo");
subAttributeProperties.put("attributeName","vehicleNo");
subAttributeProperties.put("dataType","string");
subAttributeProperties.put("multiValued","false");
subAttributeProperties.put("description","User's vehicle number");
subAttributeProperties.put("required","false");
subAttributeProperties.put("caseExact","false");
subAttributeProperties.put("mutability","readWrite");
subAttributeProperties.put("returned","default");
subAttributeProperties.put("uniqueness","none");
subAttributeProperties.put("canonicalValues","[]");
SCIMCustomAttribute scimCustomAttribute = new SCIMCustomAttribute();
scimCustomAttribute.setProperties(subAttributeProperties);
// Schema object.
Map<String, String> schemaObjectProperties = new HashMap<>();
schemaObjectProperties.put("attributeURI","urn:scim:custom:extended:schemas");
schemaObjectProperties.put("attributeName","urn:scim:custom:extended:schemas");
schemaObjectProperties.put("dataType","complex");
schemaObjectProperties.put("multiValued","false");
schemaObjectProperties.put("description","Extended custom schema");
schemaObjectProperties.put("required","false");
schemaObjectProperties.put("caseExact","false");
schemaObjectProperties.put("mutability","readWrite");
schemaObjectProperties.put("returned","default");
schemaObjectProperties.put("uniqueness","none");
schemaObjectProperties.put("subAttributes","vehicleNo");
schemaObjectProperties.put("canonicalValues","[]");
SCIMCustomAttribute schemaAttribute = new SCIMCustomAttribute();
schemaAttribute.setProperties(schemaObjectProperties);
List<SCIMCustomAttribute> attributeList = new ArrayList<>();
attributeList.add(scimCustomAttribute);
attributeList.add(schemaAttribute);
AttributeSchema customExtendedSchema = SCIMCustomSchemaExtensionBuilder.getInstance().buildUserCustomSchemaExtension(attributeList);
customExtendedSchema.getSubAttributeSchemas().stream().forEach(e->System.out.print(e.getURI() + "\n"));
refer: https://github.com/AnuradhaSK/schema-extension/blob/cea1fa636bea2bb1e599ac9c71c6c45eaa339199/src/main/java/ScimSchemas.java#L39-L78

Related

Google Cloud Data flow : CloudBigtableScanConfiguration.withScan(), how to pass dynamic filter values?

SourceLocation is prefix for my Bigtable, which is fetched from application.properties. Is there a way to fetch it dynamically while running the data flow template?
My Pipeline:
pipeline.apply("ReadTable", Read.from(CloudBigtableIO.read(configSetUp(options))))
CloudBigtableScanConfiguration
private static CloudBigtableScanConfiguration configSetUp(LocationSetupOptions options) {
ValueProvider<Integer> pageFilter = options.getPageFilter();
Scan scan = new Scan(Bytes.toBytes(options.getSourceLocation().get()));
FilterList filterList = new FilterList();
PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes(options.getSourceLocation().get()));
filterList.addFilter(new PageFilter(Long.valueOf(pageFilter.get())));
filterList.addFilter(prefixFilter);
scan.setFilter(filterList);
return new CloudBigtableScanConfiguration.Builder()
.withProjectId(options.getProjectId())
.withInstanceId(options.getInstanceId())
.withTableId(options.getTableId())
.withScan(scan)
.build();}
There are two clients for Bigtable CloudBigtableIO and BigtableIO. The CloudBigtableIO parameters are not updated to be modified by templates via a ValueProvider but BigtableIO is compatible with ValueProviders.
In your particular case if you are looking for ValueProvider to be used along with template then I would recommend that you move to using BigtableIO. A sample can be found here AvroToBigtable.
UPDATE
The #Default.InstanceFactory can be used to specify a user-provided factory method to generate default values for a parameter. With this, you could read the default value from a resource file inside of your DefaultValueFactory implementation.
As an example, you can check how WindowedWordCount defines DefaultToCurrentSystemTime to annotate the minTimestampMillis parameter:

DynamoDb scan not working properly

I am trying to fetch items from the dynamoDb. However when I fetch single item using partiton key everything works fine but when I try to fetch all the items in dynamo db using scan I encouter an error. Following is the code what I am trying to do:
public List<PageCmsDomain> getAllPages() {
DynamoDBUtil dynamoDBUtil = new DynamoDBUtil();
AmazonDynamoDB dynamoDBClient = dynamoDBUtil.getDynamoDBClient();
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
List<PageCmsDomain> scanResult = mapper.scan(PageCmsDomain.class, new
DynamoDBScanExpression());
return scanResult;
Following error comes when I execute this code:
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: PageCmsDomain[restrictions]; could not unconvert attribute
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:271)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.privateMarshallIntoObject(DynamoDBMapper.java:456)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.marshallIntoObjects(DynamoDBMapper.java:484)
at com.amazonaws.services.dynamodbv2.datamodeling.PaginatedScanList.<init>(PaginatedScanList.java:64)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.scan(DynamoDBMapper.java:1458)
at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.scan(AbstractDynamoDBMapper.java:216)
at com.astro.ott.dynamodb.cmsapi.impl.PageCmsDaoImpl.getAllPages(PageCmsDaoImpl.java:74)
at com.astro.ott.cmsapi.impl.PageCmsGetServiceImpl.getPages(PageCmsGetServiceImpl.java:41)
at com.astro.ott.cms_api.cms_api.PageCmsTestCase.get(PageCmsTestCase.java:81)
Caused by: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted
at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$Rules$NotSupported.get(StandardModelFactories.java:660)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$Rules$NotSupported.get(StandardModelFactories.java:650)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$AbstractRule.unconvert(StandardModelFactories.java:714)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$AbstractRule.unconvert(StandardModelFactories.java:691)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.unconvert(DynamoDBTypeConverter.java:109)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToMap.unconvert(StandardTypeConverters.java:433)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToMap$1.unconvert(StandardTypeConverters.java:417)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToMap$1.unconvert(StandardTypeConverters.java:410)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.unconvert(DynamoDBTypeConverter.java:109)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.unconvert(DynamoDBTypeConverter.java:128)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.unconvert(DynamoDBTypeConverter.java:88)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvert(DynamoDBMapperFieldModel.java:146)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvertAndSet(DynamoDBMapperFieldModel.java:164)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:267)
... 32
And I am using same PageCmsDomain while fetching single item also.
Specified code will work only if restrictions field is null or empty map. Otherwise it will throw exception as DynamoDB does not allow to save or fetch objects that have field with Object type (even as a generic type, in this case - map's value type Object), instead it should have specific type (e.g. String, Integer, Map<String, Integer>).
If restrictions map's value type can't be changed to specific one,
you can fix that by adding DynamoDBTypeConvertedJson annotation to store serialized value of restrictions field:
#DynamoDBAttribute(attributeName = "restrictions")
#DynamoDBTypeConvertedJson
private Map<String, Object> restrictions;
Another option is to specify your own custom converter class and annotate restrictions field with
#DynamoDBTypeConverted(converter = CustomConverter.class)

How to query based on one-to-many relationships in Spring Data Neo4j

I have defined simple one-to-many relationship as:
#Relationship(type = "BELONG")
private Set<Category> categories;
I want to query all the objects based on the exact set of Category. i.e. implement something like:
Page<SomeObject> findAllByCategories(Set<Category> categories, PageRequest page);
What is the best way to do it in Spring Data Neo4j?
You have a couple of options on how you can do this.
Your calling code can simply call the following on your SomeObjectRepository:
Iterable<Long> ids = categories.stream().map(SomeObject::getId).collect(Collectors.toSet());
Iterable<SomeObject> someObjects = someObjectRepository.findAll(ids, 1);
Note this method does not support paging though.
Another way is to inject a Session into your calling code and either write a custom Cypher query to retrieve the objects you want or use the load all by instance method:
#Autowired
private Session session;
...
// Option 1: write some cypher
Map<String, Object> params = new HashMap<>():
params.put("ids", ids) // use a stream like above to collect the ids.
Iterable<SomeObject> someObjects = session.query(SomeObject.class, "MATCH (n:SomeObject) ...", params);
//Option 2: use the load by instances method which also allows pagination:
Collection<SomeObject> someObjects = session.loadAll(categories, new Pagination(0, 25));
My recommendation would be option 2 as it pretty much does exactly what you want.

How to add a list property to an entity using gcloud Java client?

I can set a property to a new entity:
Entity.Builder builder = Entity.builder(actKey);
builder.set("name", someName);
I can see a method to add a list as a property:
List<Value<String>> aliases = new ArrayList<>();
builder.set("aliases", aliases);
I cannot find, however, how to create this Value<String>. There is a DatastoreHelper.makeValue() method in DatastoreV1, but it creates a different Value object.
Looking at the source code for gcloud, the answer is this:
Builder aliases = ListValue.builder();
while (someIterator.hasNext()) {
aliases.addValue(StringValue.builder("some string").build());
}
builder.set("aliases", aliases.build());

zf2 acl doctrine 2

Actually using Zend Framework 2, I am looking for a way to implement a performant ACL strategy based on a database.
The whole idea is to directly filter the DQL queries depending on the currently logged in user, and it's permissions.
I found an implementation of this mecanisme in Symfony 2 http://symfony.com/doc/current/cookbook/security/acl_advanced.html, in this case one table seems to store for each user if he has access to a single row, so we can easily dynamically load only allowed rows by joining this table.
To synthesize,I am looking for a way to define access rules to entities based on criterias, but want to be able to get results in a single query to be able to do some ordering, and pagination.
Are there any ZF2 modules to resolve this case ?
It looks like integrating the SF2 security component as standalone is not an option: Security component from Symfony 2.0 as standalone
You have to use doctrine filter for load things for current member
example of my codes adding the filter for member query :
$em = $sm->get('doctrine.entitymanager.orm_default');
$ormconfig = $sm->get('doctrine.configuration.orm_default');
$ormconfig->addFilter("member", "\PatrickCore\Script\ORM\Functional\MemberAccessFilter");
//
$currentUser = $membersService->getCurrentUser();
$uid = $currentUser->getId();
$filter = $em->getFilters()->enable("member");
$filter->setParameter('member', $uid);
and this file \PatrickCore\Script\ORM\Functional\MemberAccessFilter :
<?php
namespace PatrickCore\Script\ORM\Functional;
use Doctrine\ORM\Mapping\ClassMetaData,
Doctrine\ORM\Query\Filter\SQLFilter;
class MemberAccessFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
// Check if the entity implements the LocalAware interface
if (!$targetEntity->reflClass->implementsInterface('\PatrickCore\Entity\MemberAccessAware')) {
return "";
}
return $targetTableAlias.'.member_id = ' . $this->getParameter('member'); // getParameter applies quoting automatically
}
}