Hello I have model users, in which there is a foreign key of Orders model.
Now sails will automatically generate route /users/:id/orders. I have to disable this route. How to do this ? I have already tried to disable all routes of orders using: _config : { actions: false, rest: false, shortcuts: false } but it still doen't work
You can achieve this by adding custom routes, which will overwrite the blueprint action.
Use http://sailsjs.org/documentation/concepts/routes/custom-routes#?response-target-syntax
'/users/:id/orders': {response: 'forbidden'}
or http://sailsjs.org/documentation/concepts/routes/custom-routes#?function-target-syntax
'/users/:id/orders': function(req, res) {res.forbidden();}
You could control the access to this model through policies.
For blocking everything put the code below inside your /config/policies.js file:
Orders : {
'*': false
},
You could also overwrite the route
In /config/routes.js:
'/:collection/:id/:model': {response: 'forbidden'}
Or you could do the way you've done, disabling the rest routes on this model
Just make sure you put the whole block, including the export line:
module.exports = {
_config: {
rest: false
}
};
Related
I'm using graphql-shield on a subgraph and rover-cli to generate the schema.
I've set the fallback rule to deny everything as I don't want anything to be accessible by default. But now rover-cli fails when introspecting the subgraph. I'm aware that you can pass a token to rover but I'm unable to do so during my build process.
I've already looked at this issue: Apollo Server Federation with graphql-shield and on both graphql-shield & rover GitHub repository but not luck so far.
I've also tried to explicitly add SubgraphIntrospectQuery like so:
export const permissions = shield(
{
Query: {
SubgraphIntrospectQuery: allow,
},
},
{
fallbackRule: deny,
debug: true,
allowExternalErrors: true,
}
);
Thanks for your help!
Try this:
export const permissions = shield({
Query: {
_service: allow,
},
_Service: {
sdl: allow
}
},{
fallbackRule: deny,
debug: true,
allowExternalErrors: true,
});
This seems to be what Apollo uses when performing the introspection. You might also need to allow: "Query._entities", "Query._service", "_Entity.*", "_Service.*", "_Any.*" since these are also used by Apollo.
You should probably implement some form of security rather than using "allow" for these, but I hope this answers your question...
At the moment to implement nestjsx/crud is very easy to create a CRUD, but what happens if I want to omit the "Delete" ?
User service
#Injectable()
export class UserService extends TypeOrmCrudService<UserService>{
constructor(#InjectRepository(User) repo) {
super(repo)
}
}
Usercontroller
#Crud({
model: {
type: User
}
})
#Controller('todo')
export class UserController implements CrudController<UserService> {
constructor(public service: UserService) {}
}
It's very simple, with that I have my CRUD operations in less than one minute, but if I have to omit a operation, in this case, delete, do I have to create one by one my method? or how I can do it?
You can exclude or include specific routes using the routes property of the #Crud decorator. exclude allows you to list routes that will not be provided, while only lets you declare which routes will be provided.
You could use the following to specifically exclude the Delete route:
#Crud({
model: {
type: User
},
routes: {
exclude: ['deleteOneBase'],
}
See the nestjsx/crud routes section of the wiki for additional routes properties.
The #Crud decorator gives you lots of control over your routes. In addition to routes, you'll find the params and query properties to be incredibly useful.
How to apply multiple policies in sails on routes which are generated by sails like this : /users/:id/orders . I can apply a single policy like this in config/routes.js
'/users/:id/orders' : {
policy : 'isAuthenticated'
}
But how can apply more than one policy in similar manner
Sadly the documentation http://sailsjs.org/documentation/concepts/routes/custom-routes#?policy-target-syntax does not talk about chaining policies in routes.
As an alternative your could protect the populate action in your user controller like so: edit config/policies.js
UserController: {
populate: ['isAuthenticated', 'isAllowed']
}
http://sailsjs.org/documentation/reference/blueprint-api/populate-where
If you just want to apply the policy only to the orders association, you can retrieve the association parameter (/:model/:id/:association) from the req object inside the policy and handle your case:
module.exports = function(req, res, next) {
if (req.param('association') == 'orders') {
// do your magic
} else {
return next();
}
};
So I have model Alarms which is associated with Site model and others... Is it possible somehow set that by default when are required Alarm.findAll().then() I didn’t need to specify which associated models I need? It is necessary because Alarms table are using in many different situations and some different apps but in my case I need only entries which has site.
Or may be somehow I can add default joins to the model?
Usually when I encounter situations like this, I would just make a module which returns a promise of the query (with joins). So, for example you could make an alarm_util module
exports.getAlarm = function() {
return Alarms.findAll({
include: [{
model: Site,
include: [{
model: OtherModel
}]
}]
});
};
module.exports = exports;
And use it anywhere in your code like
alarm_util.getAlarm().then(alarm => {
// The rest of your logic here...
});
caveat: new to web programming. I have the following in a sails project:
// in models/User.js
// user has many videos
module.exports = {
attributes: {
videos: {
collection: 'video',
via: 'owner'
}
}
}
// in models/Video.js
// video has one user
module.exports = {
attributes: {
owner: {
model: 'user'
}
}
}
I'm using the REST blueprints with a /v1 prefix. I'm trying to either override GET /v1/user/:id/video, or make a custom route to GET /v1/user/:id/myGetVideo
So I've tried the following:
find and findOne methods in VideoController.js and UserController.js. These don't trigger for GET /v1/user/:id/video - I guess because the many-to-one association is treated differently
creating a custom route
// in routes.js
module.exports.routes = {
'get /user/:id/myGetVideo': 'UserController.myGetVideo'
}
This doesn't trigger anything because of the namespace, but it does trigger /user/:id/myGetVideo as expected. I don't want to add /v1 namespace here b/c that will proliferate and become an issue to change versions.
So, how do I either override the method I want, or put it in the namespace? Overriding the first method seems cleaner, but idk.
Thanks for any help!
Edit: Any comments on what is better practice for a REST API?
Got it with wildcards:
// in routes.js
module.exports.routes = { 'get /v*/user/:id/myGetVideo':'UserController.myGetVideo' }
not bullet-proof if the prefix scheme changes, but good enough