My loopback model-relation is not working - mongodb

As I created my user model on top of User-built in model and created a new model library. But if I'm trying to make a relationship its giving the error "unauthorized".
Here are my files:
user.json
{
"name": "user",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"phone": {
"type": "string"
},
"age": {
"type": "string"
}
},
"validations": [],
"relations": {
"library": {
"type": "hasMany",
"model": "Library",
"foreignKey": ""
}
},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
],
"methods": {}
}
and my library.json
{
"name": "Library",
"base": "PersistedModel",
"strict": false,
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"category": {
"type": "string"
},
"bookTitle": {
"type": "string"
},
"author": {
"type": "string",
"required": true,
"index": false
}
},
"validations": [],
"relations": {
"user": {
"type": "belongsTo",
"model": "user",
"foreignKey": ""
}
},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
],
"methods": {}
}
As you could see that foreign key is empty what exactly it means I don't know why we need to left empty that and user login is working fine. It returns me the access token which I'm setting at the top right.
I didn't find the appropriate answer as I'm saving my database to MongoDB.

please try this add in library.json
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
}
]
and in user.json file add these
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
},{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
}
],
u need to give the owner permission for both the models.
Please let me know if you are facing any issue

Related

How to setup up Loopback ACL so that all authenticated can create but only owner can update

I am using Loopback version 3.24 and want to set up ACL on my model such that any authenticated user can create a new object, but only object owner can update the object.
Currently, I have the following ACL settings:
{
"name": "MyModel",
"plural": "MyModels",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"profileId": {
"type": "number",
"required": true
},
...
},
"validations": [],
"relations": {
"profile": {
"type": "belongsTo",
"model": "Profile",
"foreignKey": "profileId"
}
},
"acls": [
{
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
},
{
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW",
"property": "create"
}
],
"methods": {}
}
But the API responds with 401-unauthorized when an authenticated user POSTs a new object.
There was no problem with the ACL configuration. The problem was that I was not sending the access_token along with the request. After I added the access_token parameter, the request completed successfully.

Loopback: Relation Through - not working

So, I am stuck on an issue, that should be simple, and I am sure I am missing something obvious
I am following this documentation:
so I have 3 tables
client, team, client-team
client.json
{
"name": "client",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"teams": {
"type": "hasMany",
"model": "team",
"foreignKey": "teamId",
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
team.json
{
"name": "team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"type": {
"type": "string",
"required": true,
"default": "first-team"
},
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"clients": {
"type": "hasMany",
"model": "client",
"foreignKey": "clientId",
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
client-team.json
{
"name": "client-team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"clientId": {
"type": "string",
"required": true
},
"teamId": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientId"
},
"team": {
"type": "belongsTo",
"model": "Team",
"foreignKey": "teamId"
}
},
"acls": [],
"methods": {}
}
so all the relations set correctly (I think)...
then in my clients I do have 1 client
[
{
"name": "Client name",
"id": "59876185508eb519385779c6"
}
]
and in my teams I have many, but for sure this:
[
{
"type": "type",
"name": "Team name",
"id": "5ae8a37add2989a32d37f83d"
}
]
And then I go to my
localhost:3000/explorer
To POST a client-team
like this
{
"clientId": "59876185508eb519385779c6",
"teamId": "5ae8a37add2989a32d37f83d"
}
and I get the 200 response with:
{
"clientId": "59876185508eb519385779c6",
"teamId": "5ae8a37add2989a32d37f83d",
"id": "5ae961873a7e3b33f0579fc3"
}
so the connection is there....
But then, when I go to "GET client/id" and do
id: 59876185508eb519385779c6
filter: {"include":["teams"]}
this is the response
{
"name": "Chelsea FC",
"id": "59876185508eb519385779c6",
"teams": []
}
The same happens in the "GET teams/id" and I use
id: 5ae8a37add2989a32d37f83d
filter: {"include":["clients"]}
or if I go to "GET teams/{id}/clients"
and put
id: 5ae8a37add2989a32d37f83d
I get
[]
So what am I doing wrong? I am sure I am missing a stupid, obvious thing :/
using mongo if that makes any difference
There are three issues here:
You described mongodb identifiers as string, that's why you store strings in database instead of object ids. (it's not required as the datasource should understand the real type)
Your models start from lower case letter. The same should be in the relations also. (the first part of the problem, it's fixing issue with ids)
Incorrect relations for client and team models (the second part of the problem, it's fixing includes)
client-team.json
{
"name": "client-team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"clientId": {
"type": "objectId", // !!! changed (not required)
"required": true
},
"teamId": {
"type": "objectId", // !!! changed (not required)
"required": true
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "client", // !!! changed
"foreignKey": "clientId"
},
"team": {
"type": "belongsTo",
"model": "team", // !!! changed
"foreignKey": "teamId"
}
},
"acls": [],
"methods": {}
}
client.json
{
"name": "client",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"teams": {
"type": "hasMany",
"model": "team",
"foreignKey": "clientId", // !!! changed (we describing id of this model, not team)
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
team.json
{
"name": "team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"type": {
"type": "string",
"required": true,
"default": "first-team"
},
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"clients": {
"type": "hasMany",
"model": "client",
"foreignKey": "teamId", // !!! changed (the same as the previous)
"through": "client-team"
}
},
"acls": [],
"methods": {}
}

How to create a reference in loopback?

I'm new with loopback and I have some issues with relations.
I have these two models:
course
{
"name": "course",
"plural": "courses",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"toughtBy":{
"type": "embedsMany",
"model": "teacher",
"foreignKey":"",
"options": {
"validate": true,
"forceId": false
}
},
"acls": [],
"methods": {}
}
teacher
{
"name": "teacher",
"plural": "teachers",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"lastName": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
How can I add a existing teacher in an existing course ?
I tried a use the API put /courses/{id}/toughtBy/{fk}, but I get an empty body.
To confirm but I believe you did not create a course first prior to calling
POST api/courses/1/thoughtBy/1, thus you are trying to update a related model instance from a model instance that doesn't exists.
By the way, rather than using course embedsMany teacher, I would recommend you use the following patter:
course hasAndBelongsToMany teacher
then use
POST api/courses/ to create a course
POST api/teachers to create a teacher
POST api/courses/link/ with teacherid=1 and courseid=1 to link the both

How do I change the schema of a postgres data source in strongloop?

I'm trying to tell strongloop that my gallery table has moved to the products schema. Adding it to the model definition in common/models/gallery.json seemingly has no effect. New to strongloop. What am I doing wrong?
My current schema. "schema": "products" is the only thing added.
{
"name": "gallery",
"plural": "galleries",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true,
"schema": "products"
},
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"uuid": {
"type": "uuid"
},
"test": {
"type": "string"
},
"order": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
uuid is a placeholder
Answer is here: https://docs.strongloop.com/display/public/LB/PostgreSQL+connector
Correct options value:
"options": {
"validateUpsert": true,
"postgresql": {
"schema": "products"
}
}

Loopback.io find with include

I'm using Loopback.io, with MongoDB. I can't figure how to use the "include" filter.
The goal is to have "theuser" be included fully in the "group" when done a find() or findOne(). All I get now is the id's in an array. Thanks
theuser.json:
{
"name": "theuser",
"plural": "theusers",
"base": "User",
"idInjection": true,
"properties": {
"peerId": {
"type": "string",
"required": false
},
"peerStatus": {
"type": "string",
"required": false
}
},
"validations": [],
"relations": {
"notes": {
"type": "hasMany",
"model": "note",
"foreignKey": "ownerId"
},
"groups": {
"type": "hasMany",
"model": "group",
"foreignKey": "groupId"
}
},
group.json:
{
"name": "group",
"plural": "groups",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"host": {
"type": "belongsTo",
"model": "theuser",
"foreignKey": "ownerId"
},
"clients": {
"type": "hasMany",
"model": "theuser",
"foreignKey": "clientId"
}
},
"acls": [],
"methods": []
}
I'm trying to find a group like so:
Group.findOne({
filter: {
where: {"ownerId": 1},
include: {relation: "clients"}
}
}
Group.findOne({
where: {
ownerId: 1
},
include: 'clients'
}, cb);