GithubHelp home page GithubHelp logo

gatekeeper's People

Contributors

awnage avatar elazar avatar enygma avatar harikt avatar jdudley1123 avatar sdh100shaun avatar ser5 avatar sidroberts avatar stof avatar swader avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gatekeeper's Issues

Allow for customization of password policy rules

Right now Gatekeeper does no password policy enforcement, it just uses the password as is. The ability should be added, maybe as a callback somehow, to define a set of rules on the value provided by the user.

Possible implementation:

<?php
Gatekeeper::setPasswordPolicy(function($password) {
    if (strlen($password) < 8) {
        throw new \Exception('Invalid password length!');
    }
});
?>

This would need to be appended to the UserModel somehow so it could be triggered on user create.

can't setup with empty db password

➔ ./vendor/bin/setup.sh 
--- Executing Gatekeeper setup ----------

> No configuration found, please enter database information:

Hostname [localhost]: 
Database name [gatekeeper]: 
Username: mysql
Password: 
Password cannot be empty!

this is annoying restriction, it's my dev machine do i have create separate user to test this project?

Create "Security" documentation page

A "Security" page should be added to the documentation talking about the measures Gatekeeper uses to protect the users and their data. This should include:

  • Remember Me token handling
  • Reset password functionality
  • Password storage methods
  • Restrictions

etc. The idea is that this provides a "behind the scenes" look at how Gatekeeper is working to protect the data it works with and functionality it includes (summary, not really intended for code samples or anything).

Allow for a PSR-3 logger to be injected to track actions in the system

Currently there's no visibility around the actions taken as a part of the Gatekeeper handling. Functionality should be added allowing the injection of a PSR-3 compliant logger (following the Psr\Log\LoggerInterface) and used through out the system.

If the logger exists, actions should be logged using the appropriate level. Example:

  • Login attempt through authenticate logged as "info"
  • Login failure logged as "error"
  • Record not found issues as "warning"
  • Password reset code failures as "error"

Think about adding in a logging "level" where only certain actions from a set are logged (HIGH, MED, LOW possibly)

Add soft delete

Users should be soft-deletable so that an "undo" action can be easily provided when deleting users. I suggest adding a "deleted" flag into the users (and groups, possibly) table, and a "deleted_on" timestamp.

Removing user-group links

When removing users, the links between users and groups don't get deleted for related users. This should be set up with foreign keys and DELETE constraints so these extra relationships don't get left behind. Was this done on purpose? I noticed I have to do a lot more cleaning now, something I hadn't expected.

Allow for validation of more complicated permission/group schemes

Right now multiple calls are needed to get the user groups and permissions and ensure they have what they need. A way should be introduced, via some kind of schema, to allow checks for permissions/groups with various combinations of ands and ors (or even just permission/group sets).

Installation and configuration

Here is the page:
http://gatekeeper-auth.readthedocs.org/en/latest/installation-and-configuration/

"Create a database named gatekeeper and create a user for it (this is configured later)"
I'm not sure that users wish to create one more database for storing users... I think they'll try to use existing database. This interferes with issue #6, which seems to suppose same idea... I'm not quite sure if creating different database should be mentioned in the manual.

"Open both of these files and update the connection information to match the database you created earlier."
This is not enough. A developer also needs to change paths.migrations to the actual directory, relative to the directory we run phinx from.

<?php
require_once 'vendor/autoload.php';
Gatekeeper::init();
?>

This short example gives an error, as one should use not just Gatekeeper, but \Psecio\Gatekeeper\Gatekeeper.

Issue at install (Solved)

I use Ubuntu 16.04. Nginx server and installed with composer.

I create Database ok, i can connect to mysql correct. Gatekeeper create database and returns Ok.

But in call the init function:

require_once 'vendor/autoload.php';
use \Psecio\Gatekeeper\Gatekeeper;

Gatekeeper::init();

I returned fatal error:

"PHP message: PHP Fatal error: Uncaught Error: Class 'psecio\gatekeeper\Gatekeeper' not found in /var/www/html/index.php:12

Perhaps is Composer error, i don't know. Require_once is ok but use fails.

Adding groups on user creation doesn't seem to work

If I use following code:

$gkUserData = array(
    'username'      => $userData['email_address'],
    'password'      => '111111',
    'email'         => $userData['email_address'],
    'first_name'    => $userData['first_name'],
    'last_name'     => $userData['last_name'],
    'groups'        => array($groupId),
);
Gatekeeper::register($gkUserData);
//Gatekeeper::findUserByUsername($userData['email_address'])->addGroup($groupId);
foreach (Gatekeeper::findUserByUsername($userData['email_address'])->groups as $group) {
    var_dump($group->name);
}

var_dump() vardumps me nothing.
If I uncomment the line with addGroup() method, var_dump() gives me right results.

Also please note that Gatekeeper::register() doesn't return the id of newly created user, so instead of Gatekeeper::findUserById($userId) I have to use somewhat inconvenient Gatekeeper::findUserByUsername($userData['email_address'])

Note 2:
http://gatekeeper-auth.readthedocs.org/en/latest/users/#creating-users

// Use can use permission names
$credentials['groups'] = array('group1', 'group2');

should be changed to

// Use can use group names
$credentials['groups'] = array('group1', 'group2');

Finish auth token handling

There's a bit of functionality already in the system to support two-factor authentication tokens, but it needs to be finished out. This includes:

  • Updating the create_auth_token_table migration to add the verifier column
  • Creating the interface/abstract class to define the Verifier structure
  • Creating verifiers for GAuth and Yubikey (using enygma/gauth and enygma/yubikey)
  • Adding calls from someplace, maybe just the main Gatekeeper class for verifying the provided token information.

This could be in multiple places too...maybe a method on the UserModel that takes in an abstract token instance and runs the matching verifier based on the current configuration. This will need some way to get values from the current configuration (like Gatekeeper::getConfig) for things like secret keys or API credentials.

Change Remember Me token over to use HMAC signing

Something similar to:

  1. defining a "secret" value for the hashing
  2. calling hash_hmac with a one-time nonce (generated from a randomized source)
<?php

$token = $nonce.hash_hmac($hash, $secret, $nonce);

// verify with `hash_equals` on validate
if (hash_equals($hash, $input) === true) {
    echo "woo!";
}
?>

Rename setup.sh

I suggest renaming setup.sh to gk_setup.sh or gatekeeper_setup.sh. Due to it not being namespaced, it can be hard to figure out what it refers to when a lot of aliases for a lot of different projects are put into vendor/bin.

Method to check if user inherits permission (from group)

Not so much an issue as a suggestion, it would be nice if there was a method to check if the user inherits a specific permission via groups its assigned to.

Currently I can't see any function that does that, specifically mentioning in the docs that:

You can check the user's immediate permissions (not the ones on groups they belong to) with the hasPermission method

But no information on how to check if the user gets a permission from a group.

Too few fields for users

As I can see here:
http://gatekeeper-auth.readthedocs.org/en/latest/users/#creating-users
there is login, password, first name and last name fields, plus some technical info like id, resetCode, created etc.

Usually a ton more of fields is required.
Today I tried to import some data into users table and found that there is too few fields for a name - only first and last. We here, at Russia, have one more name - you can call it "Middle name", "Second name" or "Patronymic". I think, "middle_name" or "middleName" would be OK for database. One can't store someone's name without a middle name.

Often developers have to store much more additional information, like work phone, mobile phone, web site address, company name and others. Is there a solution for this? Is any work planned to address this issue?

Cyrillic is stored strangely

Here is the code:

Gatekeeper::createGroup(array(
    'name'        => 'spam_receivers',
    'description' => 'Получатели рассылки',
));
$group = Gatekeeper::findGroupByName('spam_receivers');
var_dump($group->name, $group->description);

As you can see, there are two words in description.
The PHP script is written in UTF-8.

When I look into the "groups" table, I see this: "Получатели"
It is one word stored in an unknown way for me.
var_dump() gives me this:

string(14) "spam_receivers"
string(20) "Получатели"

It manages to decode the garbage back to cyrillic, but the second word is lost anyway.

Users cyrillic UTF data is stored in the same way - as garbage.

I think UTF-8 should be stored as UTF-8 without any magic.
BTW, groups table has right encoding of "utf8_general_ci".

Count

Suggest adding count default method into datasources, like find, save, etc. Returns total number of rows in given table.

Will prepare PR in relatively near future if someone else doesn't do it first.

groups table structure

I read here
http://gatekeeper-auth.readthedocs.org/en/latest/groups/#creating-a-group
that "One thing to note, the group name must be unique".
But groups.name field doesn't have UNIQUE index. I think it should. Currently I can call Gatekeeper::createGroup() with same name multiple times and no errors occur. Additional groups haven't been created, though. Looks like Gatekeeper silently ignores such cases.

And description field is defined as varchar(20). Kind of we cannot put very informative description here =) I think varchar(255) or text would be more useful.

Relations

Seeing as MySQL is pretty much hardcoded into Gatekeeper and in this state it will never be able to support another SQL engine, no matter how similar, I wonder why foreign relations and constraints are created during the first setup migration? As is, when deleting users or groups, the relations stick around, polluting the database with leftovers.

Create system to resolve all permissions

A method needs to be created to allow the resolution of all of a users permissions and groups (especially the parent/child perms & groups) to combine into one master list that can be passed into the inGroup or hasPermission methods for evaluation.

This should probably come in the form of PermissionResolver and GroupResolver classes that can be given a User instance.

created Field being updated when model is updated (saved)

I think the update function should not set the 'created' date and only set the 'update' date.

public function update(\Modler\Model $model)
    {
        $data = $model->toArray();
        $data['created'] = date('Y-m-d H:i:s');  // <- This should be removed
        $data['updated'] = date('Y-m-d H:i:s');

        list($columns, $bind) = $this->setup($data);
        $update = array();
        $properties = $model->getProperties();

        foreach ($bind as $column => $name) {
            $colName = $properties[$column]['column'];
            $update[] = $colName.' = '.$name;
        }

        $sql = 'update '.$model->getTableName().' set '.implode(',', $update).' where ID = '.$model->id;
        return $this->execute($sql, $data);
    }

Re-apply groups

In typical user management CRUD apps, it's a common case to have to remove users from a group or add them to them - it would be easier if we could do this like so:

$user->changeGroups($_POST['groups']);

Right now, we have to:

  1. Get group IDs from a form
  2. Compare with current group IDs on a user
  3. Revoke any that no longer appear in data from form
  4. Add any new ones that appear in data from form

This is, for obvious reasons, incredibly impractical.

I suggest implementing a new changeGroups method which would remove ALL groups from a user, and at the same time add those we're feeding it. The method should be wrapped in a transaction in order to be safe against failures and leaving a user without groups should something break mid-way.

Test on PHP 7

I tried to make a switch over to PHP 7 on a server using this in one of the sites living on it and it borked something. I didn't have enough time to debug it correctly before restoring to PHP 5.6.x but there was something amiss.

Need to run the unit tests on PHP 7 and see if there's any issues.

$envPath in loadConfig

I suggest moving the check

        $envPath = ($envPath !== null) ? $envPath : getcwd();

from the loadConfig method to the loadDotEnv method, and throwing a proper exception if the path was specified but loading failed. That calls for an exception, rather than just false, because something unexpected occurred. It's not a case for a soft fallback to false. Took me a while to debug what was happening as I encountered this.

I believe the loadDotEnv method is a better home for this check, considering that's the only method in which the actual parsing of the file and loading of the config values actually happens.

I realize, however, that this would be a BC break.

Thoughts? Should I submit a PR anyway?

documentation

I'm a little bit confused about the documentation. Granted, I am not an advanced programer, I am somewhere in advanced beginner to intermediate.

First, I don't have access to composer on my hosting, so I downloaded the repository and uploded the SRC folder to my project, so apparently the whole quick setup isn't going to work for me. I couldn't find the in the repo anywhere.

I do see that I can configure it manually using

<?php
require_once 'vendor/autoload.php';
use \Psecio\Gatekeeper\Gatekeeper;

Gatekeeper::init();
?>

and

<?php
// You can specify your own .env path
Gatekeeper::init('/path/to/directory');

// You can also force the use of your own database configuration
$config = array(
    'type' => 'mysql',
    'username' => 'gatekeeper-user',
    'password' => 'gatekeeper-pass',
    'name' => 'gatekeeper',
    'host' => 'gatekeeper-db.localhost'
);
Gatekeeper::init(null, $config);
?>

does this mean for every script I need to start with this code?

I see it says "You can pass in options to the init call if you don't necesarily want to use the .env configuration file handling." but their are no ENV files for me to configure.

What am I missing?

How to change a password?

This code gives me false as the result:

use \Psecio\Gatekeeper\Gatekeeper;
Gatekeeper::disableThrottle();

$user = Gatekeeper::findUserById(1);
$password = 'aaaaaa';
$user->password = $password;
$user->save();
$result = Gatekeeper::authenticate(array('username' => $user->username, 'password' => $password));
var_dump($user->id, $result);

hasPermission() function always return false

I find that hasPermission() have wrong in UserModel.php.

the function return ($perm-&gt;id !== null &amp;&amp; $perm->id === $permId) ? true : false;
should be modified as return ($perm-&gt;id !== null &amp;&amp; $perm->permissionId === $permId) ? true : false;

I have a suggestion

hasPermission() return true only if the requested permission isn't expired

please check it

Logging in and remembering work suspiciously

I tried to run this code:

use \Psecio\Gatekeeper\Gatekeeper;
Gatekeeper::disableThrottle();
$r = Gatekeeper::authenticate(array('username' => 'blah', 'password' => 'meh'), true);
echo '<pre>';
var_dump($r, Gatekeeper::checkRememberMe());
echo '</pre>';

which gave me true, false.
Umm, that means that user is authenticated successfully but not.
I tried to investigate and inside Gatekeeper::authenticate() found this line:

if (self::$throttleStatus === true && $result === true) {

Which, if I understood correctly, means that "remember me" works only when throttling is enabled... eh...
Looks like if I remove self::$throttleStatus === true remembering does work - but recalling still doesn't.

Digging further inside RememberMe::setup() I found this:

        if ($userToken->id !== null || $this->isExpired($userToken)) {
            return false;
        }

$userToken->id !== null condition triggers and the false is returned.
I don't understand this logic and cannot suggest anything more. I don't think it works as intended, though... are these bugs?

User registration with groups inserts odd rows

When I put this POST data directly into the Gatekeeper::register method:

screenshot 2016-03-13 09 12 03

Then my records go from this:

screenshot 2016-03-13 09 08 27

to this:

screenshot 2016-03-13 09 10 04

and I also get an additional MySQL error: DB ERROR: [23000] Duplicate entry '1-12' for key 'group_id'

In other words, when inserting this data, GK not only tries to insert a group-user pair twice, it also for some reason grabs the ID of the last inserted user-group pair row and uses that ID as the next user ID.

Am investigating further.

Setup won't complete using remote database

Perhaps my own configuration is incorrect, but executing setup.sh for a remote database caused a 'MySQL Connection Failure' error. A simple edit to the setup.sh script fixed the issue, just thought i'd mention it here in case others have the same problem.

Can user change their password?

I don't understand very well Password reset. Password reset give to user chance to change their password? Or only allows user restart their account?

How user can change their password?

EDIT: finally i have made a DataBase query and update password field using pasword_hash native php 7 function.

Upstream phinx issue with MySQL >= 5.6 prevents setup

As of MySQL 5.6 the default is to enable STRICT_TRANS_TABLE which blows up the phinx log table creation. They are unwilling to add the appropriate patch due to Travis's MySQL version incompatibility. See: cakephp/phinx#243

To disable STRICT_TRANS_TABLE you need to edit /etc/my.cnf (and /usr/my.cnf on CentOS)

sql_mode=NO_ENGINE_SUBSTITUTION

I have submitted a new patch (cakephp/phinx#638) that will hopefully be accepted...

Add ability to use alternative models

There's a lot of stuff I'd expand the User model with to match the needs of my application. However, since it's not injected as a dependency into GK, but instantiated on the spot where needed, this is not easy. One option would be to make a UserModelWrapper class which consumes GK's default User class and thus decorates it with new functionality, but then collections won't work out of the box, and when iterating through them, I would need to manually instantiate my decorator again and feed each GK user into it to get my functionality.

Instead, it would be great if you defined an interface for the User class, and let us set up Gatekeeper to use a fully custom class if needed (atm GK is even fully coupled to MySQL - even if a Postgre datasource existed, it wouldn't work - see line 313 for example).

Setup should check if vars exist, not just append

After executing the full setup procedure, the script will write vars into .env regardless of whether or not they're already there:

DB_USER=homestead
DB_PASS=secret
DB_HOST=localhost
DB_NAME=adoptify_gk

MAILGUN_KEY=key-foo
MAILGUN_DOMAIN=mydomain-or-sandbox-url

DEBUG=true
DB_USER=homestead
DB_PASS=secret
DB_HOST=localhost
DB_NAME=adoptify_gk

This is a nuisance in projects that come with an example .env already populated with some values. The script should check if they exist and only replace them.

Furthermore, and somewhat related to #51, these constants should be namespaced as GK_DB_USER or something, since it's not only possible but also highly likely that a different database (with a different user account and maybe even server) will be used for the actual application.

setup.sh

Executing setup.sh I get this response:
cp: cannot stat ./vendor/psecio/gatekeeper/phinx.dist.yml': No such file or directory sed: can't read ./phinx.yml: No such file or directory sed: can't read ./phinx.yml: No such file or directory sed: can't read ./phinx.yml: No such file or directory sed: can't read ./phinx.yml: No such file or directory rm: cannot remove ./phinx.yml-e': No such file or directory
cp: cannot stat ./vendor/psecio/gatekeeper/.env.dist': No such file or directory sed: can't read ./.env: No such file or directory sed: can't read ./.env: No such file or directory sed: can't read ./.env: No such file or directory sed: can't read ./.env: No such file or directory rm: cannot remove ./.env-e': No such file or directory
--- Running migrations ----------

./setup.sh: line 87: vendor/bin/phinx: No such file or directory
DONE!

No tables has been created in the DB.
Any hint?

P.S.: Is a .sql file available?

Regards

Define a table "prefix"

Currently the Gatekeeper tables are relatively commonly named (users, groups, etc) and those could conflict with a system's current tables. A prefix option should be added to the .env handling allowing the prefix to be included on the tables. If no prefix is defined, it will revert to the current default table names.

Consider possibly adding the ability to migrate the data structure too, adding a method that would check for a prefix and, if found and not currently in use, use a SELECT INTO or something similar to migrate each of the tables. A special set of Phinx migrations could be included for this too.

How use Token Id Session how current session?

I authenticate, Ok. Remeber user with cookies Ok. But, how use token session (for permanent login) instead PHPSESSID?

I view that my browser use default PHPSESSID session and not Token generated. How i use this token how id_session?

no idea how to setup gatekeeper

sorry i am a newbie, but I am confused and havetotally no idea how to setup/install gatekeeper,

I looked at:
"http://gatekeeper-auth.readthedocs.io/en/latest/installation-and-configuration/"

and installed composer and inserted the CMD command and the cmd get stuck there, and nothing happens

I then cloned the whole gatekeeper library with git,

then I accessed bin\setup.sh

and inserted real & correct hostname/username/password etc for a remote server and when I press enter
it showed error connecting or no error at all and the window closed

How do I migrate gatekeeper to the real server instead of localhost?

How to check if an object exists?

One can use something like Gatekeeper::findGroupById(1) to get a group. I thought that this method, if it can't find the record, returns null - I doubt that not finding the record is an exceptional case - but it does throw an exception.

Am I right that there is no way to check if object exists in a clean way? Like:

if (is_null(Gatekeeper::findGroupByName('group_name'))) {
   Gatekeeper::createGroup($attrs);
}

Do we have to deal with exceptions every time for this? If it is so, I think it's not a right way.

Tokens should be stored as securely as passwords

A token allows you to log in as a user, so should be considered largely equivalent to a password (though they don't have the reuse issue). Why are they stored with a simple hash instead of bcrypt/scrypt/pbkdf2?

Does anyone actually use this?

I was all set to use Gatekeeper as a "drop in" authorization system for a new site I was working on, but I stopped when I realized it had no functions for updating user information, including passwords, and as noted by others, no support for deleting tokens/cookies when a user "logs off". I also found it was relying on deprecated mcrypt functions in the "randomlib" component and ended up being much more complex than my needs. (I could deal with the complexity if I didn't have to start out by adding fundamental missing features.)

It didn't help my view any that it pulls in eight different components that I had to go research independently to see what they did and how they might be useful.

The documentation says that update of users is provided but that's simply untrue. In fact, methods for updating any of the records are not provided. My mood was not improved by having to decipher the "phinx" files to figure out how the database should be laid out, since I was unable to use the provided "migrate" tool (an artifact of my environment.) It all feels half-done and I've decided my time is better spent doing things on my own more simply. I do appreciate the example of how to deal with some more tricky things such as "remember me" and "forgot password".

Problem with Throttling

Unfortunately in its current configuration an attacker could force a denial of service on a particular user account indefinitely.

If an attacker know's the username of a victim, he/she can lock out a user if you deploy gatekeeper with the throttling enabled, by issuing no less than y fake requests every x minutes which is trivial to discover by probing the auth system and measuring the timings.

Problem:
Using this information leads to a denial of service in which the attacker places y fake requests and leads to gatekeeper locking the username for x minutes, where the attacker then repeats the number of requests, and again locks the account.

Solution:

  1. Tie IP addresses into throttle logs and only present the locked page to the IP address which has initiated the login attempt.

Integration of "login tokens" for login rate limiting

Allow the use of "login tokens" (see here) to help prevent against login DoS and provide rate limiting on login attempts.

These tokens allow for a "next allowed login time" check to slow down the login process event further. Additional handling would be required to verify the current token timeout, possibly based on internally logged authenticate attempts.

Integrate something like HybridAuth for social logins

http://www.sitepoint.com/social-logins-php-hybridauth
http://hybridauth.sourceforge.net/index.html

The system would need to be changed to check if it's a "social" user and if so only require that the connection to the service has been made, that user details are present (name, email, etc) and an identifier is set for the service.

This would also require the settings for the social connections to be set in the .env configuration file to be passed along to the social service (corresponding to an application set up on their side).

Allow for the "cloning" of users

Functionality should exist that allows for a "clone" action on a user (user1) with provided:

  • username
  • password
  • email
  • first name/last name

...based on a provided user model instance (user1) and create a new user (user2). This should replicate all permissions and groups of user1 into user2.

Possible interface:

<?php

$result = Gatekeeper::cloneUser($user1, [
  'username' => 'ccornutt2',
  'password' => 'super-secret',
  'email' => '[email protected]',
  'firstName' => 'Chris',
  'lastName' => 'Cornutt2'
]);

// $result should be a boolean based on success of operation
?>

3.0 total revamp

Since 2.x has been out for a while, and we have PHP 7 now, I would recommend (and would like to help with) planning for a full BC-breaking 3.0 version with the following upgrades / requirements:

  • PHP 7+ only
  • Exceptions instead of true / false returns on failures
  • At least MySQL and PostgreSQL out of the box
  • Oauth integration for logins with social networks (league/oauth could be useful)

What do you think? I wouldn't mind directing some of my SitePoint firepower towards this goal, in order to make it the kickass popular package it was always meant to be. Is this realistic?

Gatekeeper::getGroupByName() - throws wrong exception

I accidentally wrote Gatekeeper::getGroupByName() instead of Gatekeeper::findGroupByName() and it gave me wonderful we-need-to-go-deeper error:

PHP Fatal error:  Class 'Psecio\Gatekeeper\Handler\Exception\ModelNotFoundException' not found in /blah/htdocs/core/lib/vendor/psecio/gatekeeper/src/Psecio/Gatekeeper/Handler/FindBy.php on line 63

I presume, \Psecio\Gatekeeper\Exception\ModelNotFoundException class is meant.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.