Parse JS SDK: How to set a default User ACL? - parse-platform

Conveniently this is blank in the JS Docs
Does an ACL have to be explicitly applied when each User is created?

I had the same question. The following appears to work, applied right after new User is created (before calling the signUp method):
var user = new Parse.User();
user.set( userObj )
var acl = new Parse.ACL();
// apply desired ACL methods here..
// by default, public read/write will be restricted
user.setACL( acl );
user.signUp( null, ... )
Initially, I tried passing user into new Parse.ACL() per Parse's docs, but that was not working.
(I'm now reading up on the Cloud Code because perhaps such security logic be better done there?)

Related

Multiple IdPs with Sustainsys.Saml2 for the HTTPModule and AspNetCore

In a previous post (Sustainsys.SAML2 with a multitenant application) I asked about the process of adding multiple IdPs to my configuration. I have that working but need a little help on implementing this for a multitenant application.
Anders posted this response from Sustainsys:
The IdentityProviders property on the options is a collection. Just add more IdentityProvider objects to it. To select what Idp to invoke, put an item in the AuthProps with key idp and set the value to the EntityId of the Idp you want to use. It's possible to alter the collection when running.
I just need a quick code example of Anders' response of "To select what Idp to invoke, put an item in the AuthProps with key idp and set the value to the EntityId of the Idp you want to use." It seems the IdP gets put into the relaystate so when the ACS gets hit, it knows which IdP to use. Anyway, just need some help to complete my understanding of this for use in our multitenant application.
I answered my own question back in the original post. Check out:
Sustainsys.SAML2 with a multitenant application
A quick code (.NET Core using Sustainsys.Saml2) example:
var actionParams = new { authenticationType = "Saml2", returnUrl };
var properties = new AuthenticationProperties
{
RedirectUri = _linkGenerator.GetUriByAction(HttpContext, "LoginExternalCallback", null, actionParams)
};
properties.Items.Add("idp", new EntityId("someID").Id); // <--- **That's the important line**
return Challenge(properties, "Saml2"); // <--- Return Challenge from the controller

Can't save object in Cloud Code

I'm having an issue when running a function in Cloud Code. It is supposed to check the existence of an object and, if it does exist, create a new user:
Parse.Cloud.define("createUser", function(request, response) {
// Query the existing company by id
var query = new Parse.Query(Parse.Object.extend("Company"));
query.equalTo("objectId", request.params.company.existing.id);
query.find().then(function(result){
var user = new Parse.User();
user.set("username", request.params.username);
user.set("password", request.params.username);
user.set("email", request.params.email);
user.set("permissions", ["User"]);
var company = result[0];
user.signUp(null, {
success: function(user){
// Asign company ACL for User write permission
var cACL = company.getACL();
cACL.setWriteAccess(user.id, true);
company.setACL(cACL);
// Save company
company.save();
console.log(company);
// Establish user-company relationship
var cRelation = user.relation("associated");
cRelation.add(company);
// Save user
user.save();
console.log(user);
// Finish
response.success(user);
},
error: function(user, error){
response.error(JSON.stringify({code: -8000, message: "User creation failed"}));
}
});
}, function(error){
response.error(JSON.stringify({code: -8001, message: "Invalid company"}));
});
});
I first query Parse for the existence of said object. If it does exist I create a new user with the parameters received. In the completion block of the user creation I assign the proper ACLs (to the company object) and later on save them. That's when I encounter the first issue: the ACLs are not saved (checked in the dashboard). I console.log the company for debugging purposes and it shows the ACLs are correctly set. So I assume it must be a saving problem.
NOTE: The user is created, but whatever I try to do later doesn't work.
Later on I add this object to a relationship previously defined in the dashboard, but I have the same problem with that: the relationship does not come up in the dashboard, even though when I console.log the object it shows that the relationship was properly set.
I'm lost here. I don't understand why this isn't working and I've read tons of online documentation and still can't find the answer.
Okay, after a day of work I finally found out my problem. I had ACLs set everywhere and I had no privilege for saving the objects I was trying to save. So saving was indeed failing.
I should note that if you are having the same problem I did, you can easily solve it using the Master Key. To do so, you need to call Parse.Cloud.useMasterKey() before executing any requests that must be authenticated.
This only works in Cloud Code, and you should definitely know what you are doing when you use the Master Key because it basically gives read and write privileges to anyone, everywhere, for everything. So make sure your logic is flawless because you might get big security problems if it's not used wisely. As Uncle Ben said: With great power comes great responsibility.
Hope this helps someone.

new RoleManager<IdentityRole> error missing arguments in VS 2015

I want to implement User and Role Manager in VS 2015 using the Identity.EntityFramework": "3.0.0-rc1-final".
Among others I have created a class IdentityManager.
My main problem is creating a method to check the existence of a Role as follows.
public bool RoleExists(string name)
{
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
return RoleManager.RoleExists(name);
}
I keep getting the error on new RoleManager<IdentityRole>:
There is no argument given that corresponds to roleValidators, keyNormalizer, errors, logger,contextAccessor"
Yes, basically all the parameters I am not specifying but I have no idea how to approach these.
I am very new at this and have been searching and trying for days now, if someone can just point me in the right direction I am willing to do the legwork and testing, I just need some documentation.
I am having a similar issue - it looks like the roles are not the best option in identity 3.0
This thread (ASP .NET 5 MVC 6 Identity 3 Roles Claims Groups) helped me get something working, but its sad that this is not better documented.
Here are my attempts at improving that. Asp.net.Identity (3.0.0.0-rc1-final)
in Startup.cs --> ConfigurationServices
//Define your policies here, they are strings associated with claims types, that have claim strings...
//they need to be in AspNetUserClaims table, user id, department, Dev to be allowed access to the Dev policy
//add the auth option, below that makes it work, and in the api controller, add the
//[Authorize("Dev")] attribute
//services.AddAuthorization(
// options =>
// {
// options.AddPolicy("Dev", policy => { policy.RequireClaim("department", "Dev"); });
// });

Using parse.com, can multiple, authenticated users access the same data?

How can I "pair" multiple users, and have them access the same data - perhaps some of the users in a group having read only rights? As a use case, think of a family sharing calendars, each using their own login, but being able to see each other's calendar.
You should have a look at Roles and Security in the Parse docs.
I'm no expert, but I would assume that you would create a role for a family and then restrict the access to either classes or objects (depending on your approach) with Access Control Lists. In that way you can have a group/role that has the same permissions for same objects and classes.
Adapted from the docs:
Creating a role
// By specifying no write privileges for the ACL, we can ensure the role cannot be altered.
var roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
var familyRole = new Parse.Role("MyFamilyRole", roleACL);
familyRole.save();
Then
var calEvent = new Parse.Object("CalendarEvent");
var familyACL = new Parse.ACL();
familyACL.setPublicReadAccess(false)
familyACL.setPublicWriteAccess(false)
familyACL.setRoleReadAccess("MyFamilyRole", true);
calEvent.setACL(familyACL);
calEvent.save();
This can of course be done more efficiently by using defaultACLs and other functionality. But these are the basics.
Btw, I reference the JS api, since you didn't specify a platform.

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