Neil
Neil

Reputation: 27

Role in loopback not working properly getting error 401

Hello I'm new to loopback and I'm stucked on the Role creation and use.So basically what I'm trying to do is to create 2 roles and based on these roles I want to restrict some users to access some resources.The problem is that on every attempt to get some information from the api I'm getting this

{
  "error": {
    "statusCode": 401,
    "name": "Error",
    "message": "Authorization Required",
    "code": "AUTHORIZATION_REQUIRED",
    "stack": "Error: Authorization Required\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\loopback\\lib\\application.js:433:21\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\loopback\\lib\\model.js:359:7\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\loopback\\common\\models\\acl.js:536:16\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\async\\dist\\async.js:3888:9\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\async\\dist\\async.js:473:16\n    at iteratorCallback (C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\async\\dist\\async.js:1064:13)\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\async\\dist\\async.js:969:16\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\async\\dist\\async.js:3885:13\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\loopback\\common\\models\\acl.js:518:17\n    at C:\\Users\\HP\\Desktop\\battle-horse\\battle-horse\\node_modules\\loopback\\common\\models\\role.js:447:21\n    at _combinedTickCallback (internal/process/next_tick.js:131:7)\n    at process._tickCallback (internal/process/next_tick.js:180:9)"
  }
}

In my application I have 2 models:

1.Client (which extends build in User Model) and has role ```bs_client```
2.Admin(which also extends the build in User Model)

Note that these models were created using loopback cli and has no relationship created yet.

lb model

I'm using Mongodb as database and here is my datasource file

  "mongodb": {
    "host": "",
    "port": 0,
    "url": "mongodb+srv://general:234234@#/#@##@?retryWrites=true&w=majority",
    "database": "database",
    "password": "password",
    "name": "mongodb",
    "user": "general",
    "useNewUrlParser": true,
    "includeSubDomains": true,
    "useUnifiedTopology": true,
    "connector": "mongodb"
  }

It seems that the data is being added correctly in my collections (Role, Rolemapping, Client and Access Token).

I'm assigning role to each client dynamically upon creation using this

 Client.observe('after save', function setRole(ctx, next) {

    if (ctx.instance) {
      if (ctx.isNewInstance) {
        // look up role based on type
        //
        app.models.Role.find({where: {name: 'bs_client'}}, function(err, role) {
          if (err) { return console.log(err); }
          if (role) {

            app.models.RoleMapping.create({
              principalType: app.models.RoleMapping.User,
              principalId: ctx.instance.id,
              roleId: role.id,
            }, function(err, roleMapping) {
              if (err) { return console.log(err); }

              console.log('User assigned RoleID ' + role.id + ' (' + ctx.instance.type + ')');
            });
          };
        });
      }
    } next();
  });

and here is my model-config.json

{
  "_meta": {
    "sources": [
      "loopback/common/models",
      "loopback/server/models",
      "../common/models",
      "./models"
    ],
    "mixins": [
      "loopback/common/mixins",
      "loopback/server/mixins",
      "../common/mixins",
      "./mixins"
    ]
  },
  "User": {
    "dataSource": "mongodb",
    "public": false
  },
  "AccessToken": {
    "dataSource": "mongodb",
    "public": false
  },
  "ACL": {
    "dataSource": "mongodb",
    "public": false
  },
  "RoleMapping": {
    "dataSource": "mongodb",
    "public": true,
    "options": {
      "strictObjectIDCoercion": true
    }
  },
  "Role": {
    "dataSource": "mongodb",
    "public": true
  },
  "Email": {
    "dataSource": "Email"
  },
  "Client": {
    "dataSource": "mongodb",
    "public": true
  },
}

and in client.json

"acls": [
    {
      "accessType": "*",
      "principalType": "CLIENT",
      "principalId": "bs_client",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "CLIENT",
      "principalId": "bs_client",
      "permission": "ALLOW"
    },
    {
      "accessType": "EXECUTE",
      "principalType": "CLIENT",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "create"
    },
    {
      "accessType": "WRITE",
      "principalType": "CLIENT",
      "principalId": "bs_client",
      "permission": "ALLOW"
    }
  ],

Following https://loopback.io/doc/en/lb3/Model-property-reference.html, everything should be working fine, why I'm not able to retrieve "clients" using the configuration above.

Thanks in advance.

Upvotes: 0

Views: 252

Answers (1)

MaxAlex
MaxAlex

Reputation: 3319

This line should look like this everywhere in "acls": "principalType": "ROLE",

example ACL:

  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "admin",
      "permission": "ALLOW"
    }
  ],    

Upvotes: 1

Related Questions