hasPermission spring Security - spring

what does this means ?
#PreAuthorize("hasPermission('DEVICE', {'DELETE','CREATE'})")
whether it checks Device object has DELETE AND CREATE both permission or any one of it?

As said in comment, it depends on which PermissionEvaluator you have. If you use the built-in ACL system, this will delegate to DefaultPermissionGrantingStrategy. The javadoc says:
The method will iterate through each of the permissions in the order specified. For each iteration, all of the sids will be considered, again in the order they are presented. A search will then be performed for the first AccessControlEntry object that directly matches that permission:sid combination. When the first full match is found, the grant or deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return true. If the ACE specifies to deny access, the loop will stop and the next permission iteration will be performed.
(sids = security identities, the user's principal and authorities)
In practice this means only one of the permissions is required for the method to return true.

Related

nested complicated ACL in laravel

I'm using spatie/laravel-permission as ACL system in my project. it's good.
I'm adding payment/accounting/invoice to my project and in this level there is another ACL needed on users works.
for example user A have a feature F1 as our service. until 1 month he/she can use all sections in F1. after that some features in F1 limited until new invoice payed with user.
so in my controller an Edit method I use authorizeForUser just in user ACL level. now I should add another ACL in F model like authorizeForF(F1->id)?!
and another problem is that this is very complicated and if I forgot to add this, I missed some money!!
I have a solution:
seed in a table save all Uri,methods (with foreach on Route::getRoutes()) as a unic row and assign a score for each of them (default 0). in a route middllware, analyze every request uri and compare it with score.(for example uri is /profile/advaence and administrator assign score 2 for that)
if the uri have more than zero score, user's accountant will checked to continue or redirect to payment if needed.
this give the administrator of website abbility to assign each uri score and developer has no Responsibility about that.
just I'm worry about uri. because administrors usually don't undrestand them easyly. so, I need another seed for some uri to explain as title.
is it good?

single permissions in search guard

I went through the latest documentation of search guard, https://docs.search-guard.com/latest/roles-permissions and could only find a short explaination for single permissions:
Single permissions either start with cluster: or indices:, followed by
a REST-style path that further defines the exact action the permission
grants access to.
So one permission could be on cluster level or on indices level.
indices:data/read/search
So the part before : could be indices or cluster, but I'm not clear how to understand the parts after semicolon, and what are these parts seperated by "/".
Can someone please explaine me more about this or point me to some documentation, which I maybe missed?
Thanks
Dingjun
This is actually not related to Search Guard but to Elasticsearch. When you interact with Elasticsearch, e.g. indexing data or searching data, what you are really doing is executing actions. Each action has a name, and this name is in the format you outlined.
For example, have a look at org.elasticsearch.action.search.SearchAction:
public class SearchAction extends Action<SearchRequest, SearchResponse, SearchRequestBuilder> {
public static final SearchAction INSTANCE = new SearchAction();
public static final String NAME = "indices:data/read/search";
private SearchAction() {
super(NAME);
}
...
}
The permission schema of Search Guard is based on these Elasticsearch action names. So the naming conventions is actually an Elasticsearch naming convention.
Elastic does not publish a list of these action names anymore. AFAIK in X-Pack Security you cannot actually go down to this level of detail regarding permissions, that's probably why they stopped to do so.
The Search Guard Kibana plugin comes with a list of permissions you might use as a guideline:
https://github.com/floragunncom/search-guard-kibana-plugin/blob/6.x/public/apps/configuration/permissions/indexpermissions.js
https://github.com/floragunncom/search-guard-kibana-plugin/blob/6.x/public/apps/configuration/permissions/clusterpermissions.js
The question is if you really need to implement security on such a fine-grained level. That's what the action groups are for. These are pre-defined sets of permissions and should cover most use cases. Also, they are updated with each release if the permissions in Elasticsearch change, so it's safer to use action groups than to rely on single permissions. But as always, it depends on the use case.

CouchDB: limit action to logged users

I'm working with validate_doc_update function. I've heard about userCtx, but simply calling log(userCtx); helps no way: there's no records in the log.
How determine in validation is current user logged or not and maybe perform some checks to verify against user rights (which may be made by simple fields like role:editor in _users database)?
The user context is accessible under req.userCtx.
A common check of the loggedIn-status is if (req.userCtx.name !== null)
The access right roles of a user doc are accessible under req.userCtx.roles. The corresponding settings for a doc can be included hard-coded in the validate_doc_update function or in the doc itself.

How to work with not (yet) registered devise Users

I have a User model, for login and registration, its email field is used (everything vanilla from the devise gem).
I want (other) users to be able to e.g. add Users to a team, with the email-address as the identifier.
That is fine when the User is already existing (pseudo #team.users.add(User.find_by(email: other_users_email))) but I am unsure how to handle situations where the user does not yet exist (did not [yet] register).
When a (new) User sets up a new account, for the example above after successfull registration current_user.teams should show up correctly.
I do not want to force these potentially new users to use the system (e.g. using devise_invitable) and bother them with an email.
I followed the path of creating the User when a user with the given email does not yet exist, but then when the user actually tries to setup an account, it fails (email not unique).
Alternatively, I could remodel the TeamMember-part and let it optionally either store an email-adress or the reference to an existing User. Then what I would need is to check for "open" TeamMembers directly after User-Account-creation (so, TeamMembers with the given email). I could also do this on each requst, but that looks too expensive to me. There might be race conditions, but I could live with that (and check for the every-now-in-a-millenia-gap with a cron-job).
Any pointers? I am sure this is not that unusual.
I'd do this:
When a user A adds user B to a team by email, create the object for that user B, but set a flag, something like auto_created_and_inactive: true
When user B signs up on the site, you just have to handle this in your users#create: first, try to find an auto-created record and update it (set a password or whatever; also reset the flag). Or otherwise proceed with the usual route of creating a new record.
I have to admit that I did not yet tried #sergio-tulentsevs approach (implement RegistrationController#create). But to complete what I sketched in my question:
User model can define an after_confirmation method, which is called after ... confirmation! So, if I store every information about a potential user with a reference to his/her email-adress, once he/she registered I can query this information and e.g. complete Team-Memberships.
# app/models/user.rb
def after_confirmation
# (pseudo-code, did not try)
self.teams < TeamMembership.open.where(email: self.email)
end

Getting all available permissions spring security acl

I have to implement access controls in my application and I am using spring ACLs for it. My model has User, groups, permissions.
The problem I am trying to solve is to get permissions on a domain object for a user. I was able to get all the access control entries for that user (principal sid, and group sids), and using that I was able to get a final set of permissions by taking a union over all the permissions. Lets say the combined mask is 111, which would be Read, Write, and Create permissions going by the permissions defined in BasePermissions.
The problem I am facing now is I cant find any way to get a list of all defined base permissions so that I can compare the mask to individual permissions. The base permission class does not seem to provide any such method. I do not want to hardcode cases in an if-then clause, since the number of permissions might increase in future.
Any pointers would be appreciated. Thanks.
You can check for the permission by using the AclPermissionEvaluator by passing an array of Permission instances to hasPermission method as a parameter. Check the source in the given link for implementation.
#Autowired
private PermissionEvaluator permissionEvaluator ;
........
Object permission = new Permission[]{permissionFactory.buildFromName("READ"),permissionFactory.buildFromName("WRITE"), permissionFactory.buildFromName("CREATE")};
permissionEvaluator.hasPermission(authentication, oid, permission);
And as mentioned in this answer do not forget to register the AclPermissionEvaluator in your spring context.
UPDATE: To get all the permission that a user has on a domain object --
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
.......
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
// Lookup only ACLs for SIDs we're interested in
Acl acl = aclService.readAclById(oid, sids);
List<AccessControlEntry> aces = acl.getEntries();
List<String> permissionsList = new ArrayList<String>();
for (AccessControlEntry ace : aces ) {
permissionsList.add(ace.getPermission().getPattern());
}
As #Ravi said: use the method readAclById from the class JdbcAclService will not work if you use the BasicLookupStrategy.class. Becasuse the LookupStrategy.readAclsById (ignored the second paramter sids). I suggest you write your custom lookupstragey.
What you are trying to do is check if a CumulativePermission has a specific permission. You can do it using this method:
public static boolean containsPermission(Permission cumulativePermission, Permission singlePermission) {
return (cumulativePermission.getMask() & singlePermission.getMask()) == singlePermission.getMask();
}

Resources