Skip to content

Conversation

@nextrapi
Copy link

What does it do?

Updates the IsOwner guide for Strapi v4

Why is it needed?

The current guide is deprecated.

Important to note that I think this guide is useful and popular enough that it should be added to the sidebar but I haven't done that yet.

Related issue(s)/PR(s)

Fix for #652

@vercel
Copy link

vercel bot commented Jan 25, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/strapijs/documentation/DP1Apd2LsKUm4H3TnojFUJnV1vHV
✅ Preview: https://documentation-git-fork-nextrapi-dev-isowner-v4-strapijs.vercel.app

@strapi-cla
Copy link

strapi-cla commented Jan 25, 2022

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@derrickmehaffy derrickmehaffy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of controllers, this type of action should use route policies and route middlewares

@nextrapi
Copy link
Author

Hi @derrickmehaffy, thank you a lot for your feedback. I updated the code using policies and middlewares.
This is a strapi project with the example code: https://github.com/nextrapi/Strapi_v4_IsOwner

If you can give me any feedback on the code or the way its written, I can do another update and rewording.

@derrickmehaffy derrickmehaffy self-requested a review January 28, 2022 17:59
@derrickmehaffy
Copy link
Member

Hi @derrickmehaffy, thank you a lot for your feedback. I updated the code using policies and middlewares. This is a strapi project with the example code: https://github.com/nextrapi/Strapi_v4_IsOwner

If you can give me any feedback on the code or the way its written, I can do another update and rewording.

Yes I'll try and provide some feedback hopefully later today if I get some time or on monday if my schedule fills up

@Spasio
Copy link

Spasio commented Jan 29, 2022

Hi @nextrapi i try your solution and it's works perfectly, thanks a lot. But i have a little problem, when i try to make post request from my app i have an error:

{
  "status": 403,
  "name": "TypeError",
  "message": "Cannot set property 'author' of undefined",
  "details": {}
}

But from postman it works fine. Maybe you can tell me what i'm doing wrong? My axios call:

      axios({
        method: "POST",
        url: "http://localhost:1337/api/articles",
        headers: {
          "content-type": "application/json",
          Authorization: `Bearer ${window.localStorage.getItem("jwt")} `,
        },
        title: "Test article from app",
      });

@nextrapi
Copy link
Author

Hi @nextrapi i try your solution and it's works perfectly, thanks a lot. But i have a little problem, when i try to make post request from my app i have an error:

{
  "status": 403,
  "name": "TypeError",
  "message": "Cannot set property 'author' of undefined",
  "details": {}
}

But from postman it works fine. Maybe you can tell me what i'm doing wrong? My axios call:

      axios({
        method: "POST",
        url: "http://localhost:1337/api/articles",
        headers: {
          "content-type": "application/json",
          Authorization: `Bearer ${window.localStorage.getItem("jwt")} `,
        },
        title: "Test article from app",
      });

Hi @Spasio, thank you but I think your axios config is wrong. Try this:

var axios = require('axios');
axios({
  method: 'post',
  url: 'http://localhost:1337/api/articles',
  headers: { 
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjQzNDM1OTg2LCJleHAiOjE2NDYwMjc5ODZ9.byIvqOTfx-zNjN85v3OCirBAubaKt3YqOZ5mNI0y370', 
    'Content-Type': 'application/json'
  },
  data : JSON.stringify({"data":{"title":"Test"}})
})

I am however going to correct it so it returns the correct error!

@Spasio
Copy link

Spasio commented Jan 29, 2022

Hi @nextrapi i try your solution and it's works perfectly, thanks a lot. But i have a little problem, when i try to make post request from my app i have an error:

{
  "status": 403,
  "name": "TypeError",
  "message": "Cannot set property 'author' of undefined",
  "details": {}
}

But from postman it works fine. Maybe you can tell me what i'm doing wrong? My axios call:

      axios({
        method: "POST",
        url: "http://localhost:1337/api/articles",
        headers: {
          "content-type": "application/json",
          Authorization: `Bearer ${window.localStorage.getItem("jwt")} `,
        },
        title: "Test article from app",
      });

Hi @Spasio, thank you but I think your axios config is wrong. Try this:

var axios = require('axios');
axios({
  method: 'post',
  url: 'http://localhost:1337/api/articles',
  headers: { 
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjQzNDM1OTg2LCJleHAiOjE2NDYwMjc5ODZ9.byIvqOTfx-zNjN85v3OCirBAubaKt3YqOZ5mNI0y370', 
    'Content-Type': 'application/json'
  },
  data : JSON.stringify({"data":{"title":"Test"}})
})

I am however going to correct it so it returns the correct error!

Thanks for fast reply, your axios config solved my problem. Now everything working great!

@strapi-bot
Copy link

This pull request has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/isowner-policy-in-strapi-4-0/14824/5

@derrickmehaffy
Copy link
Member

} else {
      ctx.request.query.filters = { ...ctx.request.query.filters, [field]: userId };
      return true;
    }

You can't do this, setting stuff in the policy ctx won't travel down the chain. You can't set something in a policy only return true/false.

I think this policy could be simplified quite a bit.


I also don't understand the purpose of the middleware

@alpakaxaxa
Copy link

alpakaxaxa commented Feb 2, 2022

Hey everyone, at the moment my code in isOwner.js policy looks like this:

module.exports = async (ctx, next) => {
  const { id } = ctx.params;
  const userID = ctx.state.user.id;
  if (id) {
    // content type is hardcoded in this example
    const [entity] = await strapi.entityService.findMany('api::article.article', {
      filters: { id, author: userID },
    });
    if (entity) {
      return true;
    }
  }
  return false
}

As far as I have understood, this works for update, findOne and delete controllers (everything that works on one article). However, what would be the approach if I would want to filter the find controller in a policy? Or am I just able to filter in the controller, e.g. article.js:

module.exports = createCoreController('api::article.article', ({ strapi }) => ({
    async find(ctx) {
        const { data, meta} = await super.find(ctx);
        const { user } = ctx.state;
        let articles = onlyAuthorArticles(data, user);
        return {articles, meta}; 
    }
}));

function onlyAuthorArticles(articles, user) {
    let filteredArticles = articles.filter(article => article.attributes.author.data.id == user.id);
    return filteredArticles;
}

Filtering the ctx object in the policy file is not possible as @derrickmehaffy mentioned.

My approach works I am just not sure if it is the most sensible approach (I doubt that :D)

@pwizla pwizla self-assigned this Feb 3, 2022
@pwizla pwizla requested review from Convly and petersg83 February 3, 2022 09:23
@pwizla pwizla added size: medium If the PR includes 1+ file(s) with a total of 10 to 50 lines of text or <100 lines of code source: Dev Docs PRs/issues targeting the Developer Docs target: v4 Documentation PRs/issues targeting content from docs.strapi.io (main branch). issue: discussion pr: updated content PRs updating existing documentation content labels Feb 3, 2022
@pwizla
Copy link
Collaborator

pwizla commented Feb 18, 2022

@Convly and/or @petersg83 I'd like to have your review on the suggested changes, from a technical point of view, before I can have my technical writing review ready :-)

@leandrosena
Copy link

@nextrapi I am very grateful for this documentation PR.
I've been looking for a solution for a long time and this one fits like a glove, thanks 🚀 ❤️

@pwizla
Copy link
Collaborator

pwizla commented May 4, 2022

Hello @derrickmehaffy , @petersg83 and @Convly . I'm following up on this PR to have your technical feedback and see how we can go forward with it 😎

@pwizla pwizla changed the base branch from main to backup/main February 22, 2023 22:37
},
update: {
policies: [IsOwner],
middlewares: [SetOwner],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong, but this SetOwner won't do much since we can only update entities that belong to the current user.
If this is just to demonstrate where you can put the middleware, maybe we could add a comment next to it to explain things?

@pwizla
Copy link
Collaborator

pwizla commented Aug 22, 2023

Hello everyone! I'm closing this PR as the recommended way to add an "is-owner policy" equivalent in Strapi v4 is now documented: https://docs.strapi.io/dev-docs/backend-customization/middlewares#restricting-content-access-with-an-is-owner-policy

@pwizla pwizla closed this Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

issue: discussion pr: updated content PRs updating existing documentation content size: medium If the PR includes 1+ file(s) with a total of 10 to 50 lines of text or <100 lines of code source: Dev Docs PRs/issues targeting the Developer Docs target: v4 Documentation PRs/issues targeting content from docs.strapi.io (main branch).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants