Field Level Permission in Spring Domain Object. View and Edit permission based filtering of object - mysql

I am looking for a spring based solution for this problem. I have solved this in crude way but looking for better solution.
I have a client server architecture application.
Based on user permission, I am able to :
get list of fields for loggedin user which he is not permitted to write.
get list of fields for loggedin user which he is not permitted to read.
Now, how can I verify that the object to be written into database is as per user permission in an efficient way. I can iterate over fields, check if its value is different from that stored in db and reject accordingly. Is there any effecient way ?
Example:
One domain entity "Account" which is stored in MongoDB.
class Account {
String name;
String email;
String mobile;
}
Corresponding DTO Object to be returned to client
class AccountDto {
String name;
String email;
String mobile;
}
Two User -> User A, User B
Scenario:
User A can edit [ name ] but not email, mobile.
User A can view [name, email] but not mobile.
How can I design to return only those field which he is permitted to view. I donot want to create numerous DTO based on every user permission.
How can I write a code to check that the Object to be written to database is valid as per permission assigned to loggedin user. I dont want to iterate over fields and check field permission and then discard. Expensive operation.
My solution: Whenever user is going to write to db, I can fetch the existing record , compare with the record he is going to write and reject if field value is changed if he has not that permission. But this adds DB read cost and is not that generic solution.

Related

What to do if some fields are not put by user in form submission?

I have a webform in ASP.NET this form includes almost 40 fields from which some are picture upload fields.
If some fields are not related to user he/she will not put any value in them so how can I handle this if some values are not insert by user in form. So that its doesn't through an error due to empty fields.
This isn't to do with program logic as much as it is business logic so you could do this:
When a user does not input any data into a field you could:
1) Allow your database table(s) to accept null values for when this case occurs and treat the data that you use in future as though it may contain nulls.
2) Populate any fields that the user did not enter any information in with 'dummy data'. This is to say that you could do something like:
string someForm = "";
if(string.isNullOrEmpty(txtSomeForm.Text))
{
someForm = "N/A";
}
Then you check within your program for whether the string that was input by the user, and saved to the database equals "N/A" (non-applicable). If it equals "N/A" then you know it's not relevant to the user.

Is there any Mql command to print the connection between two admin objects?

In Enovia Mql, if we want to print the details of a connection between a person and its company object what is the command. For Ex: Business objects can be explored using "Expand", similarly what is the way for Admin Objects?
I think we need some clarification on question as when you talk about "connection between a person and its company object" that means you are talking about business objects.
But for admin objects query is different.
I will try to answer both the questions.
A. Admin object query
print person PERSONNAME;
B. Business object information:
as you need all connection information below query will help you.
expand bus Person PERSONNAME - type Company select rel id attribute.value;
as we have mentioned "type Company" the expand will only consider connected Company type of objects.
"select rel" clause selects information from relationships.
You can add any selectable for relationship in above query.
also for more information on expand you can use following query in mql and check expand bus section.
help bus;
Please try to perform below query:
Print person XYZ selectable;
Thanks_Sachin
May be it would be good if you have mentioned specific admin object names.
As per current schema design admin objects are not connected in the way business object are connected. But admin objects are referenced/added to another admin object.
For example Attribute admin object is added to type object.
print type Part select attribute
Similarly type admin object is added into policy admin object.
Print policy Engineering selet type store format;
In above example we can see type ,store and format admin objects being referenced from policy.
Similar way each admin object is referenced/added to another admin object

How to model data for a JSON API and a Document Database

I am making a simple REST API in front of a NoSQL database that stores records as documents similar to JSON (but not exactly the same). Each record has some fields, including id for the database, and also including some derived fields, like dateCreated.
Any time I GET anything, I want to return the objects with all the fields.
// GET /users returns an array of these in JSON
// [{id:"xxx", name:"Bobby", dateCreated:"YYYY-MM-DD"]
data User = User { id :: String, name :: String, dateCreated :: XXX }
But any time I POST or PUT anything, they client should send an object with the id field and any derived fields missing. The database is responsible to create the id when I save it, and I would create some derived fields
// POST /users would need you to post only the name.
// {name:"Henry"}
data PartialUser = PartialUser { name :: String }
If resource represents objects of type User, what should I call the thing client is sending to me? Would you make all the derived fields Maybe values? Or would you create a second object called PostedUser or something?
It can be many things:
a request body
the representation of the intended resource state of the client
a command DTO which you can send to the domain logic in order to process it by CQRS
I would make it CreateUser command, but if you don't want to use CQRS and DDD, then you would probably call it as PartialUserRepresentation, or you don't create a data structure, just use the properties to create a new User entity. Ofc. if you use entities.
So I would say it depends on the architecture of your system.

Laravel Eloquent how to limit access to logged in user only

I have a small app where users create things that are assigned to them.
There are multiple users but all the things are in the same table.
I show the things belonging to a user by retrieving all the things with that user's id but nothing would prevent a user to see another user's things by manually typing the thing's ID in the URL.
Also when a user wants to create a new thing, I have a validation rule set to unique but obviously if someone else has a thing with the same name, that's not going to work.
Is there a way in my Eloquent Model to specify that all interactions should only be allowed for things belonging to the logged in user?
This would mean that when a user tries to go to /thing/edit and that he doesn't own that thing he would get an error message.
The best way to do this would be to check that a "thing" belongs to a user in the controller for the "thing".
For example, in the controller, you could do this:
// Assumes that the controller receives $thing_id from the route.
$thing = Things::find($thing_id); // Or how ever you retrieve the requested thing.
// Assumes that you have a 'user_id' column in your "things" table.
if( $thing->user_id == Auth::user()->id ) {
//Thing belongs to the user, display thing.
} else {
// Thing does not belong to the current user, display error.
}
The same could also be accomplished using relational tables.
// Get the thing based on current user, and a thing id
// from somewhere, possibly passed through route.
// This assumes that the controller receives $thing_id from the route.
$thing = Users::find(Auth::user()->id)->things()->where('id', '=', $thing_id)->first();
if( $thing ) {
// Display Thing
} else {
// Display access denied error.
}
The 3rd Option:
// Same as the second option, but with firstOrFail().
$thing = Users::find(Auth::user()->id)->things()->where('id', '=', $thing_id)->firstOrFail();
// No if statement is needed, as the app will throw a 404 error
// (or exception if errors are on)
Correct me if I am wrong, I am still a novice with laravel myself. But I believe this is what you are looking to do. I can't help all that much more without seeing the code for your "thing", the "thing" route, or the "thing" controller or how your "thing" model is setup using eloquent (if you use eloquent).
I think the functionality you're looking for can be achieved using Authority (this package is based off of the rails CanCan gem by Ryan Bates): https://github.com/machuga/authority-l4.
First, you'll need to define your authority rules (see the examples in the docs) and then you can add filters to specific routes that have an id in them (edit, show, destroy) and inside the filter you can check your authority permissions to determine if the current user should be able to access the resource in question.

save values from 2 classes in grails

I have 2 classes named User.groovy and Employee.groovy and I used MYSQL to save the data. What I want is to create a new User account and save it to the User table and also save some of the data to Employee table. How can I do this? I've tried extending the user to Employee but the data only saved to User and not to Employee. But If I don't extend the User, the data is only saved to Employee. What should I do so that the data simultaneously saves to two database tables at the same time? Please help me.
Actually have this in my class user:
class User {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
.....}
and employee:
class Employee {
String name
String email
String jobDesc
....}
So what should I do next? I'm sorry for this, I'm still starting to learn grails.
Grails paradigm (as far as scaffolding is concerned) is one form - one object. As long as you stick to this paradigm, you get all the goodies, such as input validation and error reporting for free (you may also consider using the Fields plugin here http://grails.org/plugin/fields).
However, sometimes you need to collect info and create two or more objects through single form. Usually this happens when you need to initiate new subscription and collect info for both subscription details (say, Subscription entity) and user info (User entity). This is where command objects come to rescue.
http://grails.org/doc/latest/guide/theWebLayer.html#commandObjects
So, instead of expanding/bending SubscriptionController or UserController (or UserController and EmployeeController, as per your example), you create SignUpController, which handles SignUpCommand object. The SignUpCommand object is not intended to be saved, it is used as a backing object for the SignUpController.create form. When it validates, you use the signUpCommand object data to initialize 2 domain objects (that is Subscription and User) and save these objects individually within the same transaction.
You can either delegate the save operation to a service say,
if (signUpCmd.validate()) {
SignUpService.save(signUpCmd))
}
or create and save both objects right on the spot within controller
if (signUpCmd.validate()) {
Subscription subscription = new Subscription(plan: signUpCmd.plan, ...)
subscription.save()
User user = new User(username: signUpCmd.username, ...)
user.save()
}
it is mostly matter of taste and style.
Instead of calling save() directly to your user instance, call a service class that saves both the user and the employee in one atomic operation. Like, for instance:
class UserController {
/*Injection of your service in the controller class*/
def userService
And then in the save action in this same controller:
userService.save(user) // userService.save(params)
And inside this service method you will extract the data (user or params, whatever floats your boat) you want to save in a different table as long as the usual user object.