How to use backend permissions in frontend - ruby-on-rails

I have a web application using Rails as backend and AngularJS as frontend and it has a rather complicated permission system that must hide/show buttons in the frontend accordingly.
For example, imagine something like ebay, if I created a product, I can edit, delete, etc.. but somebody can share a product with me and I can also edit, but not delete. So the permission is calculated by resource, and not using roles.
I thought adding a "permissions" attribute to each json object, something like:
[{
id: 1,
name: "product 1",
permissions: {
canEdit: true,
canDelete: false
}
},
{
id: 2,
name: "product 2",
permissions: {
canEdit: true,
canDelete: true
}
}]
Is there any best practice to send each resource permissions to the frontend?
Just to be clear, this permissions are only used to show/hide buttons, the backend still blocks this resources even if the person changes the values in the frontend

As the logic to figure out what a user can do with each item is determined on the server side, I reckon it's redundant to pass on the permissions associated with these items to client-side, unless additional processing is done on client-side based on user's interaction.
In your case, maybe you can just return different collections of objects, say an editable list and a read-only list to the client-side, based on permissions associated and then render actions based on which collection the item belongs to?

Related

Create calendar Permissions in Microsoft graph API not removable by end users

We would like to create calendar permissions on all users calendar in organization which allow a service (user mailbox) to read/write on users calendars.
There is no problem to do that by using Microsoft Graph endpoint : Create calendarPermission
But we would like this permission was not removable by end users. That's why we tried to use isRemovable property set to true. For example :
POST https://graph.microsoft.com/v1.0/users/UPN_OF_USER/calendar/calendarPermissions
Request Body
{
"emailAddress": {
"name": "VALID_USER_NAME",
"address": "VALID_USER_EMAIL_IN_TENANT#TENANT_DOMAIN"
},
"isInsideOrganization": true,
"isRemovable": false,
"role": "read"
}
But each time we add this permission, isRemovable property is set to true.
It doesn't seems isRemovable property is readonly in documentation
I tested the API in my environment and it came up with the same result. I tested couple of Scenarios and found that isInsideOrganization is decided by the My Organization user and isRemovable is default set to true for all users as they can be removed/deleted from the Sharee and Delegate list except for My Organization User as its the deciding authority of which permissions are assigned to what user.
It is also mentioned in calendar permission resource type Microsoft Documentation as shown below :
Scenarios:
Create a Permission for User inside the Organization by providing the two parameters and not providing the parameters as well:
With Parameters:
Without Parameters:
Create a Permission for User present outside the Organization by providing the two parameters and not providing the parameters as
well:
With Parameters:
Without Parameters:
Note : IsRemovable is set to false only for My Organization User as can be seen below:

Authentication Redirection and Security done right?

I am building an Application where alongside general public pages there will be a login page and 3 Dashboard Versions for each 3 role levels.
Table
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('firstname');
$table->string('surname');
$table->string('username');
$table->string('email')->unique();
$table->string('password', 60);
$table->string('role');
$table->rememberToken();
$table->datetime('created_at');
$table->datetime('updated_at');
});
With that i have another table Roles:
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('role_type');
});
Relationship
Users::hasOne('roles');
Roles::hasMany('users');
Essentially on login function i want to check the users role_type and then redirect them based on the role.
I would like to know if this table structure and idea is correctly thought out.
Additionally when a user accesses a specific route i will have the route either display login if no user or 404/503 if user is logged in But does not match a specific role_type.
Thanks guys
On your users table instead of the role column you have, it should be these two lines:
$table->integer('role_id')->unsigned()->nullable();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('set null');
The downside to this is it allows a null value for the 'role_id' column on users. The reason it needs this is to deal with what would happen if a Role that is assigned to a user is deleted.
But a better solution would be to use a many-to-many relationship, I personally would suggest using Entrust, since it has what you want built in, plus more options that you might want later.

Deployd : Most secure, most elegant way to get all objects in a specific collection created by the logged-in user?

I think the title pretty much says it all... Brand new to Deployd, so any pointers about how best to go about this are appreciated.
To get the objects in a collection created by the user (I assume you're using the javascript library dpd.js):
// Get the current user:
var currentUser;
dpd.users.me(function(result, error) {
currentUser = result;
});
// query your collection with your currentUser id as parameter
dpd.yourcollection.get({creator:currentUser.id}, function(result) {
// Do something with the result
console.log(result);
});
Your collection should have a property "creator" that contains the id of the user who created the object (*).
Then, to secure your backend, go to the dashboard, in the ON_GET tab of your collection and secure it with this code:
cancelUnless(isMe(this.creator), "You have to be the creator to view this item", 401);
More info about cancellUnless() and isMe() here:
http://docs.deployd.com/docs/collections/reference/event-api.md#s-cancelIf%28%29,%20cancelUnless%28%29-764
The good practice to secure your collections is to allow queries only if user is logged:
cancelUnless(me,"You have to be connected to view this item", 401);
Users collections should be particularly well secured (allow ON_PUT only by admin or something like that).
*: to automatically store the currentUserId in the creator property, you could also add this in the ON_POST event in the dashboard:
this.creator = me.id;
More info here: http://docs.deployd.com/docs/collections/reference/event-api.md#s-me-764
As of version 0.8.9, event ONBEFOREREQUEST exists and you could just put this code in there:
cancelUnless(me);
query.creator = me.id;
This means that for every request sent to that endpoint, creator key would be queried to have the currently logged in user's id. If there's not currently logged in user, the request is canceled.

Does this User Permissions set-up make sense?

I am building a Rails 3 app and I am working on a design for a sophisticated user permissions tool where a Company user determines specific roles for each PM.
Imagine this scenario - the Company wants to establish specific roles over three types of data.
Project table
Client table
Corporate Account (i.e. Company table)
I am thinking of adding a Role polymorphic table with these fields:
user_id (the user this role applies to, unless all_users == true)
item type (such as "Project", "Client", or "Company", unless all_items == true)
item id (as above)
role (such as "read", "edit", "destroy", or even "custom")
all_users (boolean: does this item's role apply to all users)
all_items (boolean: does this user's role apply to all items)
company_id (the company who 'owns' this role)
I feel that CanCan would be a nice lean way of accomplishing this, but here's my question. 1. Is the above table a good way to do this? 2. Could CanCan tie in with this to create an effective solution?
Your table seems like a sensible way to implement a very complicated authorization scheme, which seems to be what you're after.
As far as CanCan goes, yes it will tie in perfectly with this. All CanCan does is provide you with the ability to define authorization on actions, models, etc. according to certain criteria. These criteria could be anything (e.g. day of the month, etc.) but are usually tied to roles. So all you'll have to do is specify the authorization rights according to the information in your Role table and the specific model instance that is going to be evaluated.

Dynamic data validation in ASP.NET MVC

I've recently read about the model validation capabilities of ASP.NET MVC which are all very cool until a certain point. What happens if the application doesn't know the data that it works with because it is all stored in DB and built together at runtime. Just like in Drupal, I'd like to be able to define custom types at runtime, and assign runtime validation rules as well. Obviously, the idea of assigning attributes to well established models is now gone. What else could be done ? I am thinking in terms of rules being stored as JSON objects in the DB fields or something like that.
Have you looked at the jquery validation plugin? One of the options you have there is to declare your UI validation in Javascript. For example for my contact page I have the following validation being used.
$(document).ready(function () {
$("#ContactForm").validate({
rules: {
Name: "required",
Email: {
required: true,
email: true
},
Subject: "required",
Message: "required"
}
});
});
This is a very baisc usage of the plugin.
Obviously you will still need some sort of backend validation, but for you UI this sounds ideal to your scenario.

Resources