<commit_before><?php namespace Orchestra\Authorization;

use RuntimeException;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Orchestra\Contracts\Auth\Guard;
use Orchestra\Memory\ContainerTrait;
use Orchestra\Contracts\Memory\Provider;
use Orchestra\Contracts\Authorization\Authorization as AuthorizationContract;

class Authorization implements AuthorizationContract
{
    use AuthorizationTrait, ContainerTrait;

    /**
     * Acl instance name.
     *
     * @var string
     */
    protected $name;

    /**
     * Construct a new object.
     *
     * @param  \Orchestra\Contracts\Auth\Guard  $auth
     * @param  string  $name
     * @param  \Orchestra\Contracts\Memory\Provider|null  $memory
     */
    public function __construct(Guard $auth, $name, Provider $memory = null)
    {
        $this->auth    = $auth;
        $this->name    = $name;
        $this->roles   = new Fluent('roles');
        $this->actions = new Fluent('actions');

        $this->roles->add('guest');
        $this->attach($memory);
    }

    /**
     * Bind current ACL instance with a Memory instance.
     *
     * @param  \Orchestra\Contracts\Memory\Provider  $memory
     *
     * @return void
     *
     * @throws \RuntimeException if $memory has been attached.
     */
    public function attach(Provider $memory = null)
    {
        if ($this->attached() && $memory !== $this->memory) {
            throw new RuntimeException(
                "Unable to assign multiple Orchestra\Memory instance."
            );
        }

        // since we already check instanceof Orchestra\Memory\Provider,
        // It safe to just check for not NULL.
        if (! is_null($memory)) {
            $this->setMemoryProvider($memory);
            $this->initiate();
        }
    }

    /**
     * Initiate acl data from memory.
     *
     * @return $this
     */
    protected function initiate()
    {
        $name = $this->name;
        $data = ['acl' => [], 'actions' => [], 'roles' => []];
        $data = array_merge($data, $this->memory->get("acl_{$name}", []));

        // Loop through all the roles and actions in memory and add it to
        // this ACL instance.
        $this->roles->attach($data['roles']);
        $this->actions->attach($data['actions']);

        // Loop through all the acl in memory and add it to this ACL
        // instance.
        foreach ($data['acl'] as $id => $allow) {
            list($role, $action) = explode(':', $id);
            $this->assign($role, $action, $allow);
        }

        return $this->sync();
    }

    /**
     * Assign single or multiple $roles + $actions to have access.
     *
     * @param  string|array  $roles      A string or an array of roles
     * @param  string|array  $actions    A string or an array of action name
     * @param  bool          $allow
     *
     * @return $this
     */
    public function allow($roles, $actions, $allow = true)
    {
        $this->setAuthorization($roles, $actions, $allow);

        return $this->sync();
    }

    /**
     * Verify whether current user has sufficient roles to access the
     * actions based on available type of access.
     *
     * @param  string  $action     A string of action name
     *
     * @return bool
     */
    public function can($action)
    {
        $roles = $this->getUserRoles();

        return $this->checkAuthorization($roles, $action);
    }

    /**
     * Verify whether given roles has sufficient roles to access the
     * actions based on available type of access.
     *
     * @param  string|array  $roles      A string or an array of roles
     * @param  string        $action     A string of action name
     *
     * @return bool
     *
     * @throws \InvalidArgumentException
     */
    public function check($roles, $action)
    {
        return $this->checkAuthorization($roles, $action);
    }

    /**<commit_msg>Add `Orchestra\Authorization\Authorization::canIf()` helper to only check for acl metric if the action exist, otherwise return false.<commit_after><?php namespace Orchestra\Authorization;

use RuntimeException;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Orchestra\Contracts\Auth\Guard;
use Orchestra\Memory\ContainerTrait;
use Orchestra\Contracts\Memory\Provider;
use Orchestra\Contracts\Authorization\Authorization as AuthorizationContract;

class Authorization implements AuthorizationContract
{
    use AuthorizationTrait, ContainerTrait;

    /**
     * Acl instance name.
     *
     * @var string
     */
    protected $name;

    /**
     * Construct a new object.
     *
     * @param  \Orchestra\Contracts\Auth\Guard  $auth
     * @param  string  $name
     * @param  \Orchestra\Contracts\Memory\Provider|null  $memory
     */
    public function __construct(Guard $auth, $name, Provider $memory = null)
    {
        $this->auth    = $auth;
        $this->name    = $name;
        $this->roles   = new Fluent('roles');
        $this->actions = new Fluent('actions');

        $this->roles->add('guest');
        $this->attach($memory);
    }

    /**
     * Bind current ACL instance with a Memory instance.
     *
     * @param  \Orchestra\Contracts\Memory\Provider  $memory
     *
     * @return void
     *
     * @throws \RuntimeException if $memory has been attached.
     */
    public function attach(Provider $memory = null)
    {
        if ($this->attached() && $memory !== $this->memory) {
            throw new RuntimeException(
                "Unable to assign multiple Orchestra\Memory instance."
            );
        }

        // since we already check instanceof Orchestra\Memory\Provider,
        // It safe to just check for not NULL.
        if (! is_null($memory)) {
            $this->setMemoryProvider($memory);
            $this->initiate();
        }
    }

    /**
     * Initiate acl data from memory.
     *
     * @return $this
     */
    protected function initiate()
    {
        $name = $this->name;
        $data = ['acl' => [], 'actions' => [], 'roles' => []];
        $data = array_merge($data, $this->memory->get("acl_{$name}", []));

        // Loop through all the roles and actions in memory and add it to
        // this ACL instance.
        $this->roles->attach($data['roles']);
        $this->actions->attach($data['actions']);

        // Loop through all the acl in memory and add it to this ACL
        // instance.
        foreach ($data['acl'] as $id => $allow) {
            list($role, $action) = explode(':', $id);
            $this->assign($role, $action, $allow);
        }

        return $this->sync();
    }

    /**
     * Assign single or multiple $roles + $actions to have access.
     *
     * @param  string|array  $roles      A string or an array of roles
     * @param  string|array  $actions    A string or an array of action name
     * @param  bool          $allow
     *
     * @return $this
     */
    public function allow($roles, $actions, $allow = true)
    {
        $this->setAuthorization($roles, $actions, $allow);

        return $this->sync();
    }

    /**
     * Verify whether current user has sufficient roles to access the
     * actions based on available type of access.
     *
     * @param  string  $action     A string of action name
     *
     * @return bool
     *
     * @throws \InvalidArgumentException
     */
    public function can($action)
    {
        $roles = $this->getUserRoles();

        return $this->checkAuthorization($roles, $action);
    }

    /**
     * Verify whether current user has sufficient roles to access the
     * actions based on available type of access if the action exist.
     *
     * @param  string  $action     A string of action name
     *
     * @return bool
     */
    public function canIf($action)
    {
        $roles = $this->getUserRoles();

        if (is_null($this->actions->search($action))) {
            return false;
        }

        return $this->checkAuthorization($roles, $action);
    }

    /**
     * Verify whether given roles has sufficient roles to access the
     * actions based on available type of access.
     *
     * @param  string|array  $roles      A string or an array of roles
     * @param  string        $action     A string of action name
     *
     * @return bool
     *
     * @throws \InvalidArgumentException
     */
    public function check($roles, $action)
    {
        return $this->checkAuthorization($roles, $action);
    }

    /**
{'fraction_non_alphanumeric': 0.12363808621506395, 'fraction_numerical': 0.0, 'mean_word_length': 2.103638368246968, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3086644', 'n_tokens_mistral': 2383, 'n_tokens_neox': 2360, 'n_words': 688}