Query Backend Roles

6 posts, 0 answers
  1. Dan
    Dan avatar
    12 posts
    Member since:
    Jan 2014

    Posted 14 Mar 2014 Link to this post

    Can mobile app's query against Backend Roles?  I want to allow my app's admin to see what role each user is in through the app.  Right now, I can only grab the guid of roles (from the users query), not the role names.  The guid is useless to my admin.  I want to display the role name, not the role's guid to the admin.  Is there anyway to display the role name in my app without hard-coding the mapping between role guid and role name in my app?
  2. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 17 Mar 2014 Link to this post

    Hello Dan,

    Thank you for your question!

    The 'Roles' content type belongs to the Metadata API of Telerik Backend Services. Thus, it is accessible only with MasterKey authentication. Due to the properties of the master key, it should not be deployed with the client app, or exposed to public. Even in the case of the administrator of your app it would be suitable to retain the secrecy of the master key. Preserving the secrecy of the master key would require to implement some logic into the Cloud Code (server layer) of the backend project that will query the "Roles" content type (by authenticating with Master Key) and return the needed data about "Roles" to the client app.

    Could you please be more specific on the administrator role and the business case of your app?  There might be different approaches depending on the operations this one is going to execute in regard to the "Roles" content type: read, write, update, delete. Also, would it be a dedicated admin app or all users will be authenticated through the same client interface?
     
    In some cases, even embedding the role name into the User object would be a suitable approach.

    We would appreciate if you could provide this information so that we are better equipped to assist you further.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform. For more information on the new name, and to learn more about the Platform, register for the free online keynote and webinar on Wednesday, February 12, 2014 at 11:00 a.m. ET (8:00 a.m. PT)
     
  3. Dan
    Dan avatar
    12 posts
    Member since:
    Jan 2014

    Posted 17 Mar 2014 in reply to Anton Dobrev Link to this post

    Thanks for the reply.  The admin will be using the same app as all users, he'll have access to a section of the app (the admin section) that no other users will.  At first, the admin will only be doing read operations against the Roles data (he will just be able to see what roles users are in and change the roles).  The need to create, update and delete roles will likely be something I'll need to add before too long.  It's not feasible to manually update hard-coded role mappings every time the admin deletes and adds roles. 

  4. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 18 Mar 2014 Link to this post

    Hi Dan,

    Thank you for getting back to us!

    In order to avoid the setting the Master Key in the client app, one approach could be to create, for example, two "proxy" content types that will serve the requests by the administration for "Users" and "Roles". Set the type-level permissions for these content types to "Role-based" and assign the Administrator role to them.

    Below, you can refer to the examples w/ Cloud Code for each of the "proxy" content types:

    1. AdminHandler Content Type (proxies the "Users")

    var parameters = Everlive.Parameters;
    var masterKey = parameters.masterKey;
     
    var url = "https://api.everlive.com/v1/" + parameters.apiKey + "/Users/";
    var options = {
        headers: {
            "Authorization": "MasterKey " + masterKey
        }
    };
      
    Everlive.Events.afterRead(function (request, response, context, done) {
     
        if (true) { // TODO additional validation
            if (request.itemId) {
                url += request.itemId;
            }
            Everlive.Http.request('GET', url, options, function (err, response) {
                if (err) {
                    console.log(JSON.stringify(err));
                } else {
                    console.log(JSON.stringify(response.body)); // see the output in the 'Logs' section
     
                    Everlive.Response.setObjectResult(
                        JSON.parse(response.body)
                    );
                }
                done();
            });
        } else {
            done();
        }
     
    });
     
    // other event handlers are omitted for brevity
    Everlive.Events.beforeUpdate(function (request, context, done) {
     
        var data = request.data;
        console.log(JSON.stringify(data));
        var itemId = data.Id;
     
        var usersData = Everlive.Sdk.withMasterKey().data("Users");
        usersData.updateSingle({
                Id: itemId,
                'Role': data.Role
            },
            function (data) {
                console.log(JSON.stringify(data));
            },
            function (error) {
                console.log(JSON.stringify(error));
            });
     
     
        done();
     
    });

    2. RolesHandler (proxies the "Roles" Metadata Content Type)

    var parameters = Everlive.Parameters;
    var masterKey = parameters.masterKey;
     
    var url = "https://api.everlive.com/v1/Metadata/Applications/" + parameters.apiKey + "/Roles/";
    var options = {
        headers: {
            "Authorization": "MasterKey " + masterKey
        }
    };
      
     
    Everlive.Events.beforeRead(function (request, context, done) {
       
        done();
    });
      
    Everlive.Events.afterRead(function (request, response, context, done) {
     
        if (true) { // TODO additional validation
            if (request.itemId) {
                url += request.itemId;
            }
            Everlive.Http.request('GET', url, options, function (err, response) {
                if (err) {
                    console.log(JSON.stringify(err));
                } else {
                    console.log(JSON.stringify(response.body)); // see the output in the 'Logs' section
     
                    Everlive.Response.setObjectResult(
                        JSON.parse(response.body)
                    );
                }
                done();
            });
        } else {
            done();
        }
     
    });

    Here is a very simple client-side code that resolves the response of these handlers and can read and update the users' roles (please, add several roles in the backend before testing it). There are some tradeoffs by creating such proxies, as the server sorting, paging, filtering, might not be accessible at the client side.

    In the sample code, we have tried to showcase the available approaches into the Cloud Code and you may want to tailor it to your use case with some additional optimization and validation. For example, Power Fields expression can be added before reading the Users to retrieve the name of their role, without retrieving all roles. Also, a meaningful note would be that by default, a single user can be in only one role.

    In the client - side are used:
     - DataSource component of Kendo UI
     - Everlive dialect for the Kendo UI data source component



    Please, let us know if this is helpful for you.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform. For more information on the new name, and to learn more about the Platform, register for the free online keynote and webinar on Wednesday, February 12, 2014 at 11:00 a.m. ET (8:00 a.m. PT)
     
  5. Mike
    Mike avatar
    2 posts
    Member since:
    Dec 2011

    Posted 09 Apr 2015 in reply to Anton Dobrev Link to this post

    Hi Anton... 

    I could not find any example of authenticating with MasterKey... Do you have a link or an example you can share?

  6. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 09 Apr 2015 Link to this post

    Hello,

    @MIke

    Please, take a look into this documentation article about the REST API with an example how to pass the master key as a header.

    The JS SDK can be instantiated with a master key as explained here or in the following way in case it is used in the cloud code.

    Please, take a look into the Security article and the Master Key section prior to designing its usage in your app. Usually, you can move out a functionality that relies on the master key to a Cloud Function, instead of using the master key in a client app.

    I hope that this helps.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
Back to Top