strapi / community-content

Contribute and collaborate on educational content for the Strapi Community
https://strapi.io/write-for-the-community
574 stars 400 forks source link

[SUBMIT] How we use Strapi Policy at Axolo #669

Closed cosydney closed 2 years ago

cosydney commented 2 years ago

My resource

Hey,

I've personnaly used Strapi for a few years and only started using Strapi Policy until recently. Would love to share how we use Strapi policy at our company (axolo.co) and may be inspire more developers to use that part of Strapi.

Let me know if you think this would be relevant. You can see some of what we wrote on our blog on https://axolo.co/blog

Regards,

Sydney

My content is

What do you all think? ❤️ I love it! 🚀 I can help you!

Thank you for submitting your article proposal.

malgamves commented 2 years ago

Hey @cosydney this seems interesting. We don't have a lot on this.

Could you share a more concise outline of your use case as well as how you plan on structuring the article?

cosydney commented 2 years ago

Hey Daniel,

Thank you for considering this.

Here is a structure we can come up with. Let me know what you think of it.

How do we use Strapi at Axolo:

Brief outline of what we do and how we use Strapi for our API

What are Strapi policies:

Refering to the Strapi doc, and a quick summary

How do we use Policies at Axolo:

There are 4 ways we use policies at Axolo. Here is the list with code examples:

1. Authenticated users as a Policy => like in the Strapi doc

2. Is Admin => Know if somebody making a request is an admin within his organization

3. Is a Paying organization

4. For our cron jobs => Some cron jobs we run only on weekend or on week days. We use different kind of policies for each of them.

Conclusion on policies

cosydney commented 2 years ago

Let me know @malgamves

malgamves commented 2 years ago

hey @cosydney will you have code examples for this? will people learn how to use policies in Strapi or learn how you implement policies in Strapi? Can we make the article do both?

cosydney commented 2 years ago

hey @malgamves, I've taken your suggestions into account. Let me know what do you think about that:

Strapi policies

Why did we build Axolo and what is Axolo?

We believe efficient communication when reviewing and writing code is essential for productive tech teams. Axolo.co is a tool to enable developers to engage and communicate in an easy way around pull requests. We integrate via GitHub and Slack, then for every pull request Axolo creates a temporary Slack channel so that you can discuss the pull request with your colleagues easily and with the right context (code review comments, code comments, GitHub checks, and GitHub actions).

How do we use Strapi at Axolo?

Strapi runs our backend and handles all the programming logic with our database. Strapi helped set up the models and create routes to interact with the GitHub and the Slack API. It also gives a great base for scaling up a project with the right structure (controllers, services, API, policies, models, etc...).

What are Strapi policies:

According to the Strapi documentation, "Policies are functions that execute specific logic on each request before it reaches the controller. They are mostly used for securing business logic.".

Policies are placed in your router and can be found under the /routes folder of your models. Usually inside api/{modelname}/routes/{modelname}.js.

What’s so great about Strapi policies?

Strapi policies allow you to create rules for your routes, whenever you need to implement a rule for a route, you can simply add a policy to your router to the selected route. It helps keep your code DRY (don’t repeat yourself) and it also prevents your controller from being surcharged. I personally often find myself re-using routes I’ve made a while ago.

Creating a Strapi policy :

To create a policy you need to create a folder in your src called policies and then you can give it the name that you feel is more relevant. The name of the file will be the name of the policy in your routes.

Applying a policy to a route :

To, apply a policy to a route you need to add a key to your route object like in the documentation:

// path: ./src/api/restaurant/routes/router.js

module.exports = {
 routes: [
   {
     method: 'GET',
     path: '/restaurants',
     handler: 'Restaurant.find',
     config: {
       /**
         Before executing the find action in the Restaurant.js controller,
         we call the global 'is-authenticated' policy,
         found at ./src/policies/is-authenticated.js.
        */
       policies: ['global::is-authenticated']
     }
   }
 ]
}

The policies key takes an array as an argument. You can add multiple policies to a single route if you'd like. Also the policy name is the name of the file.

How do we use Policies at Axolo:

There are 3 main ways we use policies at Axolo. Here is the list with code examples:

  1. Is-admin policy This policy helps us determine if somebody making a request is an admin within his organization.

Within Axolo we have two types of users. 1. Administrator who can edit the settings for their organization, and 2. Engineers who use our service day to day.

Both type of users are signed in to our service but only the administrator can edit the settings. To add a layer of security to our front ent, we used a Strapi policy, see below:

// path: ./src/policies/is-organization-admin.js

module.exports = (policyContext, config, { strapi }) => {
 if (policyContext.state.user.isAdmin) {
   return true
 }
 return 401;
};
  1. Is a paying customer

Some Axolo features are dedicated to paid customers. We’ve made sure a nonpaying user cannot access those routes by adding an is-paying-organization policy.

Our user model has and belongs to an organization model.

// src/policies/is-paying-org.js
module.exports = (policyContext, config, { strapi }) => {
 const id = policyContext.state.user.organization;
 const organization = await strapi.query('organization').findOne({ id });
 const { plan } = organization;
 if (plan === 'professional' || plan === 'trial') {
   return true;
 }
 return false
};
  1. To know the day of the week

We use Heroku as a hosting platform and Heroku scheduler as a cron job. The way these cron jobs work is by calling a specific route in our back end. Heroku only allows three possibilities for the cron job to be called: 1. every 10 minutes, 2. Every hour, or 3. Every day. Since some of our actions only need to be run during the week, on a specific day, or only during weekends, we have a dedicated policy for each of those cases:

Here is an example of a policy that check if we are a day of the week (monday,tuesday, wednesday, thursday, friday).

// src/policies/is-weekday-today.js
const moment = require('moment');

module.exports = (policyContext, config, { strapi }) => {
 const date = moment();
 const day = date.day();
 if (day >= 1 && day <= 5) {
     return true
 }
 return false
};

Conclusion on policies

Policies are useful to keep your controllers DRY (don't repeat yourself). When you see yourself using the same code over two controllers, or if you think you could be reusing some of the logic you implement in a controller, it probably is a good idea to create a policy for that.

Do you have any other use case for policies? Share them below so that anyone reading this article can get inspired by your way of having policies.

cosydney commented 2 years ago

@malgamves hey, any news on this?

TiaraOluwanimi commented 2 years ago

Hello, @cosydney. Could you please add this to a dropbox document so that it can be reviewed and code-tested asap? Thanks for your patience.

cosydney commented 2 years ago

Hey @TiaraOluwanimi,

Here is a dropbox link: https://paper.dropbox.com/doc/Strapi-policies--Bf0Glor~wnT6R6Opil67Rz2ZAQ-1MCRndFur0dRgd52wiXAW

Cheers

ShadaW11 commented 2 years ago

Hello @cosydney your article has been published on our blog. Thank you. Can you please issue your invoice as soon as possible following the guidelines mentioned here in the FAQ section? https://strapi.io/write-for-the-community