Lost roles and permission feature not working anymore

System Information
  • Strapi Version: 4.4.5
  • Operating System: Linux
  • Database: better-sqlite
  • Node Version: 18.8.0
  • NPM Version: 8.19.1
  • Yarn Version: 1.22.19

I have the following models created when for example I uncheck the method find for path /api/categories under public role I still get the categories instead of restricting and return with 403 error.

You can see from the screenshot

I tried that with every role tried to restart server, it was working before not sure what happen so that its not working anymore.

Can anyone tell me why I lost roles and permission restriction?


Strange. Do try to stop your server and then start it again.

Make sure that your endpoints are correctly spelled too (it happens to me a lot) :wink:

@TreciaKS Actually sorry I forgot to mention that I modified the authenticate strategy this the modification made inside strapi-server.js for users-permissions plugin, I managed to find the issue causing that but I found a bug on the last return line where public permissions returned when setting authenticated to false I get a correct restriction depending on paths selected from admin UI but I lose functionality of populate with some relations or fields and when setting authenticated to true I get the populate to show all relations I sent in URL for populate but permission and restriction not working properly as selected in admin UI:

 strapi.container.get('auth').register('content-api', {
      name: 'app-user-verifier',
      authenticate: async (ctx) => {
        
          const permissionService = strapi.service('plugin::users-permissions.permission')
          let token;
          
          if(ctx.request && ctx.request.headers && ctx.request.headers.authorization ) {
            const parts = ctx.request.header.authorization.split(/\s+/);

            if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {
              return null;
            }
      
            token = parts[1];

            ctx.request.body = { ...ctx.request.body, access_token: token }
          }
          // else {
          //   return { error: 'Invalid token' };
          // }

          try {
            const {payload, isValid} = await extractToken(ctx)
            if(isValid) {
              
              if(!payload.app_id && !ctx.request.originUrl.contains('register')) {
                return { error: "Missing app_id in token" };
              }

              const advancedSettings = await getAdvancedSettings();

              console.log(advancedSettings)

              ctx.request.body = {...ctx.request.body, firebase_decoded_token: payload}
              const exist = await alreadyExist(ctx)
              if(exist) {
                const userProfile = await getProfile(ctx, ['firebase_user', 'shipping_address', 'billing_address'])
                const firebaseUser = await fetchFirebaseAuthDetails(userProfile.firebase_user.uid)
                delete userProfile.firebase_user
                ctx.state.user = userProfile
                const system_user = firebaseUser.users_permissions_user
                // console.log(permissionService)
                // console.log(system_user.role.id)
                const permissions = await permissionService.findRolePermissions(system_user.role.id)
                console.log(permissions)

                // await Promise.resolve(firebaseUser.users_permissions_user.role.id)
                //   .then(strapi.services['plugin::users_permissions.permission'].findRolePermissions)
                //   .then(map(strapi.services['plugin::users_permissions.permission'].toContentAPIPermission));

                // const ability = await strapi.services['plugin::users_permissions.permission']
                const ability = await strapi.contentAPI.permissions.engine.generateAbility(permissions);

                return {
                  authenticated: true,
                  credentials: userProfile,
                  ability
                }
              }

            }

          } catch(err) {
            // return new ForbiddenError("")  
          }

          const publicPermissions = await permissionService.findPublicPermissions()
          // .then(map(getService('permission').toContentAPIPermission));
    
          if (publicPermissions.length === 0) {
            return { authenticated: false };
          }

          const ability = await strapi.contentAPI.permissions.engine.generateAbility(publicPermissions);

          return {
            authenticated: false, // This needs to be always false for public permissions otherwise it will allow the user to access route
            credentials: null,
            ability
          }
          
        },
        // verify: async (ctx) => {
        //   console.log('verifying auth ...', ctx)
        //   return ctx;
        //   // return false
        // }
    })

UPDATE: To illustrate more, this is an example of request I send that has populate feature:

http://localhost:1337/api/products?populate[0]=categories&populate[1]=media_sources&populate[2]=owner

Note: I did made sure paths are correct and made sure that relations are not private fields.

Anyone here can help??

Update on the Issue:

For anyone else experiencing this problem, it was confirmed to be a human error.

Here’s what happened:

  • We’re using the Config Sync plugin to synchronize changes between local, staging, and live instances.
  • The issue arose because the editor role permissions weren’t set correctly on my local environment.
  • When making non-permission-related changes and exporting files with Config Sync, the incorrect permissions from my local environment were inadvertently overwriting the correct permissions on the target instances.

Lessons Learned:

  • Double-check editor role permissions on local environments before syncing to avoid unintended overwrites.
  • This experience highlights the importance of meticulous configuration management, especially when working with synchronization tools.

Hope this helps others! :slight_smile: