Master Data Services - Domain based attributes - master-data-services

We are using Master Data Services as an MDM solution for our SQL Server BI environment. I have an entity containing a first name and last name and then I have created a business rule that concatenates these two fields to form a full name which is then stored in the "name" system field of the entity.
I use this as a domain based entity in another entity. Then the user can then see the full name before linking it as a attribute in the second entity.
I want to be able to restrict the users from capturing data in the first entity against the name attribute because the business rule deals with the logic to populate this attribute. I have read that there are two ways to do this:
Set the display width to zero of the attribute. This does not seem to work, the explorer version still shows a narrow version of the field in the rows and the user can still edit the field in the detail pane.
Use the security to make the attribute read only. I have tried different combinations of this but it seems that you cannot use this functionality for a name field (system field).
This seems like pretty basic functionality that I require and it seems that there is no clear cut way to do this in MDS.
Any assistance will be appreciated.
Thanks

We do exactly the same thing.
I tested it, and whether you create a new member, or edit an existing member, the business rule just overwrites the manual input value in the name attribute.
Is there a specific 'business' reason why you need to restrict data input in the name field? If it is for Ux reasons, you can change the display name of the name attribute to something like 'Don't populate' or alternatively make it a '.', then the users won't know what to input.

Related

RESTful API, query params on PUT

I am struggling with developing an API that follows RESTful best practices for my use case.
My db model looks something like:
Company:
Id
Name
Location:
Id
Name
DefaultSetting
LocationSettings:
Id
LocationId
CompanyId
Setting
In the business model, not every company has set location values, so in many cases it will default to the value from Location. If the user decides to change the value, then we will store their custom settings instead of using the default.
I was thinking of an API along the lines of:
GET /location-settings?companyId=id
GET /location-settings?companyId=id&locationId=id
PUT /location-settings?companyId=id&locationId=id
The idea is that when a user decides to change any setting, we will invoke the PUT route - it will update the location settings if custom settings exist for this company, or create a new entry in LocationSettings if it does not exist.
However, this seems like it might be an anti-pattern as normally I do not see query parameters used in such a manner on PUT routes to specify which resource to update. In this case, I cannot easily provide an ID for the location-settings resource because it may or may not exist. I did not want to use 2 separate routes (one for PUT and one for POST) because in the application's use-case this would get confusing i.e. from an end-user's perspective the default settings logic is hidden, so they always have location settings for their company and are simply updating them.
Another option I was thinking of was (OPTION 2):
GET /location-settings?companyId=id
GET /location-settings/locations/{locationId}?companyId=id
PUT /location-settings/locations/{locationId}?companyId=id
However, this seems strange because locations is not a sub-resource of location-settings.
A 3rd option I was considering was (OPTION 3):
GET /locations/location-settings?companyId=id
GET /locations/{locationId}/location-settings?companyId=id
PUT /locations/{locationId}/location-settings?companyId=id
Personally I liked this option the best. However, I am not sure that referencing 2 collections like the first get route does without an ID is a good REST practice.
Any recommendations on this?
It sounds like every company only has 1 'location-settings'.
If that that's true, you don't really need to add the location settings id to the url.
I might be wrong, but it seems like the only 2 routes you need are:
GET /company/{id}/location/{locId} - Return custom location settings OR default
PUT /company/{id}/location/{locId} - Update custom location for location
I do not see query parameters used in such a manner on PUT routes to specify which resource to update.
That's true, you don't. But there is nothing wrong with doing it that way
PUT /x/y/z
PUT /x?y=z
Both of those URI are fine; general purpose components will do the right thing, URI templates describe them easily, and so on. There are tradeoffs between them, of course (convenience for html vs convenience of relative references); but you could easily have one of them re-direct to the other if you discovered later that you wanted to change things.

Sulu CMS: is it possible to restrict access to certain attributes of a specific template to certain roles?

We have a situation where we have two different roles of users: let's call them content_labourer and content_boss. There's a template we could call very_cool_content. On this template we've stated the following attributes:
title: some string value
api_content_id: an integer that accurately binds this content to some backend API content (we use this in our VeryCoolContentController to fire up some backend API stuff, obviously)
description: a text value
I want my content_boss to be able to set the value for all these attributes. After all, he's the boss.
However, my content_labourer is not privy to the whole API business and would never in a million years know which value he should enter there, let alone that he should even be able to enter/change the value of api_content_id. He should also not be able to set the value of title, because that's none of his business.
Now my question is: how do I protect these particular attributes from being changed by (or in the ideal case: even be visible to) users without the content_boss role?
I am sorry, but it is not possible to restrict access to single fields. But what you can do is to restrict the access to an entire page. Maybe you can make use of that instead, if you restructure your content somehow?

Elastic Search completion suggester configuration

I'm trying to set autocomplete/suggestions on my site's search form, using Elastic Search's completion suggester feature.
I have a list of products, which are grouped by categories (on multiple levels). The search feature should be able to suggest category names, which are of more interest to users than direct products.
Several of these categories have the same name but a different parent (e.g. 'milk' under parent category 'dairy products' and 'milk' under category 'baby'). When the user selects a category suggestion, she's redirected to another page, with more specific results than mere search method.
Additional metadata (url to redirect to, parent category id/name) are added in the payload field.
I use the output field to return normalized suggestions for different inputs. As stated in the documentation:
"The result is de-duplicated if several documents have the same output,
i.e. only one is returned as part of the suggest result."
But as explained, my outputs may have the same value, while being different results, as they will link to different pages. It is also possible in the future that different category levels will yield different actions.
I am reluctant to differentiate things by adding the full string (i.e. "milk in dairy products") as the output, because:
1. The parent category is conceptually not the output itself but a related metadata.
2. I intend to have some formatting in the results, this forces me to parse the output string to add HTML tags in it.
So, is it possible to deactivate the de-duplication?
One workaround I'm thinking of if it's not possible is to store a stringified json object in the output, with all the data 'll need, both the one displayed in the search form and the metadata currently in the payload. But Id' rather look into existing configuration before resorting to that.

Validating and update entities in Zend Framework 2 + Doctrine 2

The title may not be as accurate, if someone finds a better one and can update it, please do so :)
I have a small CMS to edit users.
I'm using Zend Framework 2 + Doctrine 2.
I have a fieldset + form to add a user and (possibly) the same one to update them.
The User entity has the following fields:id, username, password, email.
The fieldset has two validators that check if the username and the email already exist.
Since I'm using the same to update the users, when I change for example the username of the user and keep the email the same, it throws an error that the "email exists" (which is normal due to the validator) and the same when I change the username and keep the email etc.
What I want is to avoid that behavior and make it so it checks them only when they are really changed/updated.
I thought of some ways, but I'm not sure what the "best" approach would be to this.
Hardcode the whole thing, by checking if the fields change and then do the validation (which makes the whole fieldset pretty much useless)
Make a function in the User entity that accepts an array with the new values, then compares them to the old ones and passes the changed ones to a "validation" function that returns the errors (which is mostly like the previous way, but I guess a bit more structured)
Write a validator and attach it to a new form which will query the db to check if the email/username exists and it's not already in use by the particular id, but I'm not quite sure on how to write it since I can't figure out how to pass the id and the field to the validator
I guess the 3rd one would be the best since it does 2 jobs at one time, by checking if the field changed and is not already in use by another user.
What do you suggest? How do you deal with that kind of scenario?
I can post any code that is needed, but I think this is more of a structural problem and that the code I used is too common and easy to figure out.

Breeze column based security

I have a "web forms", "database first enitity" project using Breeze. I have a "People" table that include sensitive data (e.g. SSN#). At the moment I have an IQueryable web api for GetPeople.
The current page I'm working on is a "Manage people" screen, but it is not meant for editing or viewing of SSN#'s. I think I know how to use the BeforeSaveEntity to make sure that the user won't be able to save SSN changes, but is there any way to not pass the SSN#s to the client?
Note: I'd prefer to use only one EDMX file. Right now the only way I can see to accomplish this is to have a "View" in the database for each set of data I want to pass to the client that is not an exact match of the table.
You can also use JSON.NET serialization attributes to suppress serialization of the SSN from the server to the client. See the JSON.NET documention on serialization attributes.
Separate your tables. (For now, this is the only solution that comes to mind.)
Put your SSN data in another table with a related key (1 to 1 relation) and the problem will be solved. (Just handle your save in case you need it.)
If you are using Breeze it will work, because you have almost no control on Breeze API interaction after the user logs in, so it is safer to separate your data. (Breeze is usually great, but in this case it's harmful.)