I guess you are working through the same tutorial I am and having the same fun.
There are two parts to this. The first is making sure when you create an event you associate it with the required user.
in my project I have the relationship between events and users defined like this
note the name is “author”
on your controller /src/api/event/controller/event.js
'use strict';
/**
* event controller
*/
const {createCoreController} = require('@strapi/strapi').factories;
module.exports = createCoreController("api::event.event", ({strapi}) => ({
async me(ctx, next) {
const user = ctx.state.user
if (!user) {
return ctx.badRequest(null, [{messages: [{id: "No auth header found"}]}])
}
const data = await strapi.entityService.findMany("api::event.event", {
populate: 'image',
filters: {
"author": {
"id": user.id
}
},
});
if (!data) {
return ctx.notFound();
}
const sanitizedEvents = await this.sanitizeOutput(data, ctx);
return this.transformResponse(sanitizedEvents);
},
async create(ctx) {
const {id} = ctx.state.user; //ctx.state.user contains the current authenticated user
const response = await super.create(ctx);
const updatedResponse = await strapi.entityService
.update('api::event.event', response.data.id, {data: {author: id}})
return updatedResponse;
},
}));
That will ensure the event is created and associated with the authenticated user.
The next part is ensuring users can edit/delete only their own records. You could do this in the controller as shown here in some draft documentation I found which really helped https://github.com/nextrapi/documentation/blob/4cb0a1d2d0d8f6b2342f8ba29864e9d220791e81/docs/developer-docs/latest/guides/is-owner.md
cleaner though to do this in a policy as you can create as many as you need and chain them together
create a folder in /src/api/event/policies and add an is-owner.js file (name is important since will be used in a minute)
In this file add the following.
'use strict';
/**
* `is-owner` policy.
*/
module.exports = async (policyCtx, config, {strapi}) => {
// get user id/record to update/delete.
const {id : userId} = policyCtx.state.user;
const {id : eventId} = policyCtx.request.params;
strapi.log.info('In is-owner policy.');
const [event] = await strapi.entityService
.findMany('api::event.event', {
filters: {
id: eventId,
author: userId
}
})
// we have an event owned by the authenticated user
if (event) {
return true;
}
// we don't have an event owned by the user.
return false;
};
Return true if OK, false if not, this will move to the controller or the next policy (policies are evaluated before the request hits the controller).
Lastly, apply the policy to the routes you need, I wanted to ensure users can only update and delete their own records.
in /src/api/events/routes/events.js apply the policy like so
'use strict';
/**
* event router.
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::event.event', {
config: {
update: {
"policies" : ["is-owner"]
},
delete: {
"policies" : ["is-owner"]
}
}
});
Note the policy name matches the policy file name we created earlier. With all that done, if you try to modify a record you don’t own you get back
{
"data": null,
"error": {
"status": 403,
"name": "PolicyError",
"message": "Policy Failed",
"details": {}
}
}
Hopefully it helps.
