How would I manage (in the DSP), every user has his/her own Todo-List?


#1

subject sais it all:

  • let’s say, I want every user to have his/her own todo list, which is created when the user registers (or confirms his/her registration).

How would I do this in the DSP?

thx


Access to database rows
Returning the logged in user's name with a custom script
#2

(Somewhat) short answer:

  1. You’d add a field to the todo table which references the user id (the DSP will automatically store the user ID of the user creating the record).
  2. When your app makes a GET call to the todo table, you pass in the logged in user id as a filter parameter in the query to the todo table (you can get the user id from the /user api on login and store the id as a variable or make a method in your app that fetches the user id on demand at runtime).
  3. To ensure that other logged in users can’t create, read, update, or delete other users’ records, you should also add a service permission to the role (e.g. if you called your field ‘owner’ in the todo table, in service permissions in roles you could specify ‘owner’ = {user_id} as a security filter rule.

I’ll try to post a few code examples when I have time…


How to implement data access based on a table with user's permissions
#3

Hi Ben,

thanks for the info. A sample todo-app would be definitely quite informative here…

andy


Force Relational Query / Disallow user to see other users data
#4

Hi Andy,

There is a tutorial on an angular based Todo app here:

You would just need to extend it as Ben has suggested above.


#5

Hi Anthony,
Once I understand 2. & 3. I will do, but that implies first finding out how to master 2 & 3 :wink: (that"a where a tutorial would come in handy ;))

Andy


#6

Here’s a quick example of how you’d do this. This example uses Angular $resource to make a REST API call to the todo table…but pick your framework of choice. The key thing to do is pass the logged in user id into the REST call as a filter that fetches only those “to do” records belonging to the current logged in user.

On the backend in DreamFactory you can also specify record-level security so that only logged in users can perform CRUD on his or her own records (for example, this prevents me from authenticating, getting a session token, and then blowing away your records from the command line by guessing your user id and making REST calls).

First, write a little Angular service.

// In your services.js file create some simple services. Here's a service to fetch to do's by user id

var baseUrl = 'https://dsp-todo.cloud.dreamfactory.com';
var appName = 'todo';

angular.module('toDo.services', ['ngResource'])

  .service('GetUserToDosService', ['$resource', function ($resource) {
        return $resource(baseUrl + '/rest/db/todo',
            { appName: appName, fields: '@fields', filter: '@filter' },
            { query: { method: 'GET' , isArray: false }
            });
    }]);

Now inject this service into a controller. To make things easier I’m also injecting the UserDataService from our User Management Module for Angular. This makes it easy to fetch the logged in user’s id. You can also write your own method to get the id of the logged in user.

.controller('UserToDosCtrl', ['$scope', '$location', 'UserDataService', 'GetUserToDosService', function($scope, $location, UserDataService, GetUserToDosService) {
        
                $scope.params = {
                    fields: 'owner' + ',' + 'id' + ',' + 'name' + ',' + 'complete',
                    filter: 'owner=' + UserDataService.getCurrentUser().id
                };
    
      $scope.todos = GetUserToDosService.query($scope.params);
    
        }]);

Then write a simple view to iterate through the to do’s.

 ....
<tr ng-repeat="todo in todos.record">
                <td>{{todo.owner}}</td>
                <td>{{todo.name}}</td>
                <td>{{todo.complete}}</td>
 </tr>
....

Lastly, in the DreamFactory roles tab, you can lock down CRUD permissions on the todo table so only users can create, read, update, and delete their own to do’s. Create a role for users using the to do app, and grant PUT, POST, PUT, and DELETE permissions for the todo table. Also add an advanced filter, like so:

Field: owner
Operator: =
Value: {user.id}

Hope that helps with the basic idea.


Record-level security: advanced filters and non-GET requests
#7

Hi, Ben!
I am an iOS devloper, having the same questions as tiptronic. Thanks for your answer. But the solution doesn’t seem very secure to me. Anyone can acquire other user’s data if he has the other user’s user_id. Does session_id makes more sense to verify user’s authority? And have a kind of filter that will always compare session_id’s corresponding user and record creator? I am not an expert at backend programming, just a feeling…


#8

Hi Jane, great question! You are right about comparing the user id of the current session with the user id of the record creator. This is automatically handled for you by DreamFactory. In other words, when you specify to protect CRUD operations by user id in the DreamFactory admin console, DreamFactory enforces this logic automatically on the server at run time…so you don’t have to implement that server-side logic yourself.

We also support server-side scripting for more advanced security scenarios (e.g. stateful conditions with different logical branches). But in many cases, you can specify the rules right in the admin console and DreamFactory will handle the server-side security for you.

Hope that helps.


#9

Thank you! That’s very helpful! I am new to Dreamfactory too…, how to
specify the record to be protected from CRUD operations of other users
when different user’s record are in the same table?


How to prevent User to see the data from other User but stored in the same table?
#10

Hi Jane. This is how you specify the record to be protected from other users’ records in the same table. For example, we have the ‘todo’ table and in that table we need to have a field, call it ‘owner’, of field type ‘user_id’ in the todo table schema.

Then we set up a role, call it ‘todo users’, and we specify a service permission on that role for the table ‘todo’ such that ‘owner’ = {user_id}.

Let’s take the simplest example with two users and two records. User 1 authenticates and gets a session id. If user 1 attempts to access user 2’s record (even if user 1 manages to get user 2’s user id), DreamFactory will automatically reject the request (it knows about the rule and it knows the identity of user 1 in this session, so it blocks user 1 from operating on any records in the ‘todo’ table where ‘owner’ is not user 1). DreamFactory enforces the rule within the same table.

You can specify arbitrary filter rules in the same table as well. For example, you could set up a role and then set up any number of security filters for a given table. For example, you might say that users of this role can only view accounts in a specific region in the ‘accounts’ table.

Check out this blog post for more info http://blog.dreamfactory.com/data-segmentation-with-server-side-filtering-and-lookup-keys.


#11

Thank you very much! It’s so detailed


#12

Great, glad that helped!