Laravel-Backpack / community-forum

A workspace to discuss improvement and feature ideas, before they're actually implemented.
28 stars 0 forks source link

[Bug] ValidateRequest on StoreFunction redirect to form #1160

Closed maarccnj93 closed 1 month ago

maarccnj93 commented 1 month ago

Bug report

What I did

When I try to save any project entity using the cruds created with backpack, when doing the $this->crud->validateRequest(); This redirects me to the form again without saving the entity. It's not showing me any errors either.

image image

Backpack, Laravel, PHP, DB version

Backpack 6.7 Laravel 11.9 php 8.2

When I run php artisan backpack:version the output is:

BACKPACK PACKAGE VERSIONS:

backpack/basset: 1.3.6 backpack/crud: 6.7.36 backpack/generators: v4.0.6 backpack/language-switcher: 2.0.0 backpack/permissionmanager: 7.2.1 backpack/theme-tabler: 1.2.13

maarccnj93 commented 1 month ago

I think the problem is that for some reason the form validation is not passing, but it is not showing me the error messages in the form.

karandatwani92 commented 1 month ago

Hey @maarccnj93

I've just tested this, and I'm unable to reproduce the behavior you are getting. For me, it pops a validation message or saves perfectly.

My code:

//rules in Request class
return [
    'title' => 'required|min:2|max:255',    
    'sku' => 'unique:products,sku,' . \Request::get('id'),    
    'status' => 'required',    
];

// store method in CRUD
public function store(){
    $this->crud->hasAccessOrFail('create');
    $request = $this->crud->validateRequest();
    $this->crud->registerFieldEvents();

    $item = $this->crud->create($this->crud->getStrippedSaveRequest($request));    
    $this->data['entry'] = $this->crud->entry = $item;

    \Alert::success(trans('backpack::crud.insert_success'))->flash();
    $this->crud->setSaveAction();
    return $this->crud->performSaveAction($item->getKey());
}
maarccnj93 commented 1 month ago

I think I've discovered the problem but not yet the solution.

I'm using a login using SSO with SAML. I found a small bug in the SSO library that causes the session to be lost every time the page is refreshed. To fix it I put a "Session()->regenerate();" on each page reload. It seems that this causes the session variables to be lost.

Since errors are saved in session variables they are lost. I need to find out why with backpack after logging in with SSO, the first page that loads has the session data correctly, but when changing views these are lost.

maarccnj93 commented 1 month ago

I have this code lo listen SignedIn.

Event::listen(\Slides\Saml2\Events\SignedIn::class, function (\Slides\Saml2\Events\SignedIn $event) {
            $messageId = $event->getAuth()->getLastMessageId();

            // your own code preventing reuse of a $messageId to stop replay attacks
            $samlUser = $event->getSaml2User();

            $userData = [
                'id' => $samlUser->getUserId(),
                'attributes' => $samlUser->getAttributes(),
                'assertion' => $samlUser->getRawSamlAssertion()
            ];

            if (isset($userData['attributes']['urn:oid:1.2.840.113549.1.9.1']['0'])){
                $email = $userData['attributes']['urn:oid:1.2.840.113549.1.9.1']['0'];
                $name = $userData['attributes']['urn:oid:2.5.4.42']['0'];
                $surnames = $userData['attributes']['urn:oid:2.5.4.4']['0'];
                $userName = $userData['attributes']['urn:oid:0.9.2342.19200300.100.1.1']['0'];
            }

            $user = User::where('email', $email)->first();

            if (!$user) {
                $user = User::create([
                    'name' => $name ." ".$surnames,
                    'email' => $email,
                    // Si no tienes una contraseña, puedes generar una aleatoria
                    'password' => Hash::make(Str::random(24)),
                    'username' => $userName
                ]);
            }else{
                $user->update([
                    'name' => $attributes['name'] ?? $name ." ".$surnames,
                ]);
            }

            $roles = app(LdapDataService::class);
            $roles = $roles->getUserGroupApli($user->username);

            foreach ($roles as $role) {
                $role = Role::findByName($role, 'web')->first();

                if(!$role){
                    Role::create(['guard_name' => 'web', 'name' => $role]);
                }

                $user->assignRole($role);
            }

            Auth::guard('web')->login($user);

        });

And I also have a "CheckIfAdmin" midelware which is where I detect that the login is lost when refreshing the page


    private function checkIfUserIsAdmin($user)
    {
        // return ($user->is_admin == 1);
        return true;
    }

    private function respondToUnauthorizedRequest($request)
    {
        if ($request->ajax() || $request->wantsJson()) {
            return response(trans('backpack::base.unauthorized'), 401);
        } else {
            return redirect()->guest(backpack_url('login'));
        }
    }

    public function handle($request, Closure $next)
    {

        if (!auth()->check()) {
            //When I do refresh this returns null
        }else{
           // The first load on page auth is OK!
        }

        if (backpack_auth()->guest()) {
            return $this->respondToUnauthorizedRequest($request);
        }

        if (! $this->checkIfUserIsAdmin(backpack_user())) {
            return $this->respondToUnauthorizedRequest($request);
        }

        return $next($request);
    }
pxpm commented 1 month ago

Hey @maarccnj93

This question goes a bit out of context for Backpack. It seems your integration is not properly done. The only thing I can help you with, and not sure if that's the problem, is that Backpack ships with a default Auth Guard called backpack. https://github.com/Laravel-Backpack/CRUD/blob/3714d7d90c8ae0b08b43866f86103aee0862ad28/src/config/backpack/base.php#L136 you can set it to null to use the default application guard.

In regards to session being lost, I belive you are missing some key middlewares from Laravel that handle session start/regeneration: https://github.com/24Slides/laravel-saml2?tab=readme-ov-file#middleware

So I would explore the options around setting up the correct middlewares, plus setting up the correct guards.

If you find an issue in Backpack, please let us know, but in this case, I think you first need to figure out your SSO setup first, and everything should work, as we use the default Laravel authentication mechanism.

Sorry but I can't be of much help as I never used that package.

Cheers