Skip to content
Alex Gisby edited this page Jul 20, 2014 · 5 revisions

Integrating Solution10\Auth isn't hard, but it's not a plug-and-play experience.

Don't worry, we'll guide you through it.

How Auth integrates

Auth is able to fit so nicely in any other framework due to it's use of Delegates.

A Delegate is a class that another class calls upon to do a task that it doesn't know how to perform. You could say it delegates a piece of work to another object and then just handles the result.

To get Auth working correctly, you'll need to implement at least one delegate, and perhaps two.

Solution10\Auth\SessionDelegate

The SessionDelegate is responsible for storing "Session" information. This is info that should persist between page views, but does not require permanent storage. It holds state.

99% of the time in PHP, we use the $_SESSION superglobal to handle this duty. If you're ok with this, you're in luck! Auth comes with a $_SESSION wrapper already and you can skip this section!

If you don't want to use $_SESSION directly (or at all), keep reading.

We're going to use the provided $_SESSION wrapper as an example. Open up src/Solution10/Auth/Driver/Session.php

The first thing to notice is that this implements SessionDelegate

class Session implements SessionDelegate

Your SessionDelegate will need to do the same, otherwise you'll get fatal errors.

We then have to implement three functions to handle the various state operations:

public function authRead($instance_name);
public function authWrite($instance_name, $auth_data);
public function authDelete($instance_name);

These are self-explanatory; reading, writing and deleting from the Session store.

You'll be asked to write the users ID into this storage, so make sure your Delegate's data store can handle that.

You're probably wondering about that $instance_name variable right? Solution10\Auth allows you to have multiple, totally different authentication systems running in parallel with each other, so when reading/writing data, you need to know the name of the instance that's asked for this operation. To learn more about the multiple instances, read these docs.

Solution10\Auth\StorageDelegate

The storage delegate handles the loading and saving of User data. Your data store could be anything, a database, flat files, a REST service, whatever; as long as you implement this Delegate correctly, Auth will work.

Auth does not provide a StorageDelegate out of the box. The reason is simple; I don't know your system, nor do I want to impose on your application design. I'll let you handle this bit.

I'm not going to go into every function on the storage delegate, as the DocBlocks on the Class itself are there to explain what is expected of each function. I will broadly explain what they're used for though.

Fetching functions

public function authFetchUserByUsername($instance_name, $username);
public function authFetchUserRepresentation($instance_name, $user_id);

These two are used to pull User information from database.

The first (authFetchUserByUsername) is used at login and should simply be a keyed array. The second is used in the user() function to return the full user object of the currently logged in session.

Package functions

public function authAddPackageToUser($instance_name, UserRepresentation $user, Package $package);
public function authRemovePackageFromUser($instance_name, UserRepresentation $user, Package $package);
public function authFetchPackagesForUser($instance_name, UserRepresentation $user);
public function authUserHasPackage($instance_name, UserRepresentation $user, Package $package);

These functions, unsurprisingly, involve the management of packages.

As a guideline, you should store the name of the package into the data-store rather than serializing and storing the object. Then in authFetchPackagesForUser you would re-construct based on those class names.

Override functions

public function authOverridePermissionForUser($instance_name, UserRepresentation $user, $permission, $new_value);
public function authFetchOverridesForUser($instance_name, UserRepresentation $user);
public function authResetOverridesForUser($instance_name, UserRepresentation $user);

These functions deal with Overrides of permissions. $permission will be a string denoting the permission in the packages to override and $new_value will be a boolean.

More can be read about Overrides in the Permissions docs.

A suggested Database Schema

Whilst you are of course totally free to use whatever schema, database or data-store you wish to integrate Auth, to help those who want to use a relational database, here's a quick schema that works nicely:

Users table

Field Type Notes
id uint autoincrement primary-key
username string(128)
password string(60)

User Packages Table

Field Type Notes
id unit autoincrement primary-key
user_id unit foreign-key(users.id)
package string(255)

User Overrides Table

Field Type Notes
id unit autoincrement primary-key
user_id unit foreign-key(users.id)
permission string(255)
value tinyint(1)

This schema will allow you to store everything and fetch it relatively easily.

(Indexes should be added to user_id in the two places it's a foreign to improve speed).

UserRepresentation

Your StorageDelegate will need to return the User objects that your app wants to work with.

This might be an instance of your User model if you're using an ActiveRecord ORM, or some sort of lib class. Solution10\Auth truly doesn't care, all we ask is that you return classes that implement Solution10\Auth\UserRepresentation.

It's dead easy, it's just the one function:

public function id();

The return can be an int, a string, a blob, whatever your app uses. This ID will be passed around to identify users, so make sure your StorageDelegate would understand it, and that your SessionDelegate can write it into it's data store.

Bringing it all together

So you've now written a fantastic SessionDelegate and a spectacular StorageDelegate that returns beautiful UserRepresentation implementers. How do you get Auth to use them?

Dead simple, pass them in the constructor when you fire up an instance:

$session = new FantasticSessionDelegate();
$storage = new SpectacularStorageDelegate();

$auth = new Auth('my-fancy-auth', $session, $storage);

And that, as they say, is that.