Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Working With Laravel Spark Classic #252

Closed
gelinger777 opened this issue Jan 30, 2022 · 5 comments
Closed

Not Working With Laravel Spark Classic #252

gelinger777 opened this issue Jan 30, 2022 · 5 comments
Assignees

Comments

@gelinger777
Copy link

SDK Version

6.5

PHP Version

PHP 7.4

Composer Version

2.x

What happened?

I am trying to integrate your plugin as a driver for Laravel Spark Classic.

In Config I have set it like

 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'spark',
        ],
    ],




 'providers' => [
        'users' => [
            'driver' => 'auth0',
            //'model' => App\Models\User::class,
        ],

Everything works pretty well with login and coming back . Even User is created (I have used custom user repository example from Laravel Auth0 Tutorial).

But on page where it should be used we get

Call to a member function "shouldHaveSelfVisibility" () on null

How can we reproduce this issue?

  1. Install latest laravel spark classic
  2. Integrate Auth0 using steps from Tutorial https://auth0.com/docs/quickstart/webapp/laravel/01-login
  3. try to login

Additional context

No response

@evansims
Copy link
Member

evansims commented Jan 30, 2022

Hi @gelinger777 👋 I'm not familiar with Spark personally and can't really speak to any specific integration quirks there, but "shouldHaveSelfVisibility" is not a method referenced anywhere in this library. What version of Laravel are you using? Can you list your Composer dependencies so we can see what else you're running that might be causing a conflict?

@evansims evansims self-assigned this Jan 30, 2022
@gelinger777
Copy link
Author

Dear @evansims thank you for your fast response. First of all here is the composer.json

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.3|^8.0",
        "auth0/login": "^6.5",
        "fideloper/proxy": "^4.4",
        "fruitcake/laravel-cors": "^2.0",
        "grocerycrud/enterprise": "2.*.*",
        "guzzlehttp/guzzle": "^7.3",
        "laravel/framework": "^8.40",
        "laravel/spark-aurelius": "*@dev",
        "laravel/tinker": "^2.5",
        "laravel/ui": "^2.0"
    },
    "require-dev": {
        "facade/ignition": "^2.5",
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.2",
        "nunomaduro/collision": "^5.0",
        "phpunit/phpunit": "^9.3.3"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": {
        "0": {
            "type": "path",
            "url": "./spark"
        },
        "hooks": {
            "type": "composer",
            "url": "https://larapack.io"
        },

        "1":
        {
            "type": "artifact",
            "url": "artifacts/"
        }
        
  
    }
}

I tried to dig a bit into Spark Classic Code and it has a model, which is in the closed composer package src

<?php

namespace Laravel\Spark;

use Illuminate\Support\Str;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Billable, HasApiTokens, Notifiable;

    /**
     * Get the profile photo URL attribute.
     *
     * @param  string|null  $value
     * @return string|null
     */
    public function getPhotoUrlAttribute($value)
    {
        return empty($value) ? 'https://www.gravatar.com/avatar/'.md5(Str::lower($this->email)).'.jpg?s=200&d=mm' : url($value);
    }

    /**
     * Make the team user visible for the current user.
     *
     * @return $this
     */
    public function shouldHaveSelfVisibility()
    {
        return $this->makeVisible([
            'uses_two_factor_auth',
            'country_code',
            'phone',
            'pm_type',
            'pm_last_four',
            'card_country',
            'billing_address',
            'billing_address_line_2',
            'billing_city',
            'billing_state',
            'billing_zip',
            'billing_country',
            'extra_billing_information'
        ]);
    }

    /**
     * Convert the model instance to an array.
     *
     * @return array
     */
    public function toArray()
    {
        $array = parent::toArray();

        if (! in_array('tax_rate', $this->hidden)) {
            $array['tax_rate'] = $this->taxPercentage();
        }

        return $array;
    }
}

And in the project itself We have defined (which is model generated by Spark itself ) User model like this

<?php

namespace App\Models;
// use Laravel\Spark\CanJoinTeams;
use Laravel\Spark\User as SparkUser;
use Illuminate\Contracts\Auth\MustVerifyEmail;
class User extends SparkUser implements MustVerifyEmail
{


    // use CanJoinTeams;
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'last_name',
        'country_code',
        'sub',
        'email',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'authy_id',
        // 'country_code',
        'phone',
        'two_factor_reset_code',
        'card_brand',
        'card_last_four',
        'card_country',
        'billing_address',
        'billing_address_line_2',
        'billing_city',
        'billing_zip',
        'billing_country',
        'extra_billing_information',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'trial_ends_at' => 'datetime',
        'uses_two_factor_auth' => 'boolean',
    ];



    /**
     * Make the team user visible for the current user.
     *
     * @return $this
     */
    public function shouldHaveSelfVisibility()
    {
        return $this->makeVisible([
            'uses_two_factor_auth',
            'country_code',
            'phone',
            'card_brand',
            'card_last_four',
            'card_country',
            'billing_address',
            'billing_address_line_2',
            'billing_city',
            'billing_state',
            'billing_zip',
            'billing_country',
            'extra_billing_information'
        ]);
    }

    /**
     * Convert the model instance to an array.
     *
     * @return array
     */
    public function toArray()
    {
        $array = parent::toArray();

        if (! in_array('tax_rate', $this->hidden)) {
            $array['tax_rate'] = $this->taxPercentage();
        }

        return $array;
    }
}

I guess problem comes from

use Laravel\Spark\User as SparkUser;

and the fact that in CustomUserRepository.php

I have followed the tutorial https://auth0.com/docs/quickstart/webapp/laravel/01-login to implement your plugin. And I suspect problem is the following part

 public function getUserByDecodedJWT(array $decodedJwt) : Authenticatable
    {
        $user = $this->upsertUser( $decodedJwt );
        return new Auth0JWTUser( $user->getAttributes() );
    }

with the type-casting :Authenticatable .

When I remove the :Authenticatable
as suggests @krthush in #144
I get Symfony\Component\ErrorHandler\Error\FatalError
Declaration of App\Repositories\CustomUserRepository::getUserByUserInfo(array $userinfo) must be compatible with Auth0\Login\Repository\Auth0UserRepository::getUserByUserInfo(array $userInfo): Illuminate\Contracts\Auth\Authenticatable

And now I am totally confused how to make this work, as I want Auth0 to be used in our simple project example...

@gelinger777
Copy link
Author

Also I have added

 public function shouldHaveSelfVisibility()
    {
        return $this->makeVisible([
            'uses_two_factor_auth',
            'country_code',
            'phone',
            'card_brand',
            'card_last_four',
            'card_country',
            'billing_address',
            'billing_address_line_2',
            'billing_city',
            'billing_state',
            'billing_zip',
            'billing_country',
            'extra_billing_information'
        ]);
    }

``` to user model, because I thought maybe it could help, but the problem is that it's not a problem of the function itself, but that the object is Null. 

@evansims evansims added question and removed triage labels Jan 31, 2022
@evansims
Copy link
Member

Hi @gelinger777 👋 Removing the Authenticatable return type hint won't have any impact on the resulting data type returned, which implements the Illuminate\Contracts\Auth\Authenticatable interface necessary for Laravel authenticated model types. The error being thrown when you remove it is because your modification to the code no longer supports the contract for the getUserByUserInfo method in the interface.

It appears the core issue you're facing is Spark Classic's user model type appears to extend the Illuminate\Foundation\Auth\User abstract type, which is incompatible with Illuminate\Contracts\Auth\Authenticatable that this library relies upon. I'm sure that design decision has to do with Spark's own authentication scheme approach.

Unfortunately, I'm unable to offer guidance on implementing with Spark Classic. As they have their own authentication and user model approach, I'd suggest reaching out to the support team at Spark about how their offering supports other authentication schemes. I'd also encourage you to reach out to the Auth0 Community for integration advice.

@gelinger777
Copy link
Author

Oh That's a good catch! Thank you @evansims . I will try to overcome then on my own. Thank you

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants