User Management

A more advanced tutorial on how to use the framework to manage users.

Modifying the entry point.

You first need to register a new resource in index.php.

$app->registerResource('users');
		

Adding configurations.

You will then need to add new configurations to DevConfigs.php to enable users flow features.

<?php

namespace BeRest\GettingStarted;

use BeRest\API\Application;
use BeRest\API\Components\Configs;

class DevConfigs extends Configs
{
    public function preRun(Application $app)
    {
        parent::preRun($app);

        $app['redis.host'] = '127.0.0.1';
        $app['redis.port'] = '6379';

        $app['mysql.host'] = '127.0.0.1';
        $app['mysql.port'] = '3306';
        $app['mysql.user'] = 'root';
        $app['mysql.password'] = '123456';
        $app['mysql.db'] = 'berest';

        $app['mailgun.key'] = 'key-xxx';
        $app['mailgun.public_key'] = 'pubkey-xxx';
        $app['mailgun.domain'] = 'mg.berest.io';

        $app['translator.directory'] = ROOTDIR . '/vendors/composer/BeRest/API/src/BeRest/API/Locales';

        $app['email.from_name'] = 'BeRest';
        $app['email.from_email'] = 'v@berest.io';
        $app['email.directory'] = ROOTDIR . '/vendors/composer/BeRest/API/src/BeRest/API/Emails';

        $app['app.name'] = 'BeRest';
        $app['links.app'] = 'https://app.berest.io';
        $app['links.confirm'] = 'https://app.berest.io/confirm/';
        $app['links.forgot_password'] = 'https://app.berest.io/reset-password/';
        $app['links.invite'] = 'https://app.berest.io/accept/';
    }
}
		

Adding user classes

The first class we will add is the model which will simply extend the user model provided with the framework.

<?php

namespace BeRest\GettingStarted\Models;

use BeRest\API\Models\User as BaseUser;

class User extends BaseUser
{
}
		

The user model provided with the framework assumes the following fields are defined in the users table.

- id
- email
- password
- permissionLevel
- status
- name
- dateCreated
- dateUpdated
		

Then, we will add the manager which will also extend the users manager provided with the framework which assumes the table is named users in the database.

<?php

namespace BeRest\GettingStarted\Managers;

use BeRest\API\Managers\Users as BaseUsers;

class Users extends BaseUsers
{
}
		

Finally, we will add the controller which also extend the users controller provided with the framework.

<?php

namespace BeRest\GettingStarted\Controllers;

use BeRest\API\Controllers\Users as BaseUsers;

class Users extends BaseUsers
{
}
		

Securing existing resources.

To secure existing resources and make sure only users having access to them can actually access them we need to add the field userId to the existing models. Here is what our previous Resource.php would look like.

<?php

namespace BeRest\GettingStarted\Models;

use BeRest\API\Models\Base;

class Resource extends Base
{
    public $name;
    public $userId;
}
		

User management flow

The first step is to create a user. In the case where you have in your configurations users.self_signup set to true, users can signup by themselves.

curl -X POST -H "Content-Type: application/json" \
     -d '{"name":"Vincent Lamanna","email":"v@berest.io","password":"123456","permissionLevel":"0"}' \
     http://127.0.0.1/users
		

This will create a new user and return a secure token as the password which you can use in subsequent API calls instead of re-using the actual password. If you have in your configurations users.validate_email set to true, the email address of the user will be validated. If you have in your configurations users.confirm_email set to true, users will receive an email asking them to confirm their account. Otherwise, they will receive a welcome email.

The link in the confirmation email will have a destination to users.confirm_link appending a token to that URL. To confirm the user account, you will make the following API call.

curl -X PUT -H "Content-Type: application/json" \
     -d '{"status":"7844d3dc54729735c3c304e520ebab7d"}'
     http://v%40berest.io:6956ccdd329b81b2a5d715a53021c3f3@127.0.0.1/users/1
		

This will change the status of the user to 1 and will send a welcome email to the user.

If you have in your configurations users.self_signup set to false, only admin users can send an invite to new users. Making the following API call will send an invite to the new user.

curl -X POST -H "Content-Type: application/json"
     -d '{"email":"v@berest.io","permissionLevel":"0","name":"Vincent Lamanna"}'
     http://v%2Badmin%40berest.io:123456@127.0.0.1/users
		

The link in the invite email will have a destination to users.invite_link appending a token to that URL. To accept the invite, you will make the following API call.

curl http://invite:7844d3dc54729735c3c304e520ebab7d@127.0.0.1/users/me
		

To perform a login, you can make the following API call.

curl http://v%40berest.io:123456@127.0.0.1/users/me
		

This will return a secure token that can be used as the password in subsequent API calls.

To start a reset password flow, you can make the following API Call which will send an email to the user. For security reason, this call will never fail.

curl -X PUT -H "Content-Type: application/json"
     -d '{"email":"v@berest.io","password":"reset"}'
     http://127.0.0.1/users/me
		

The link in the forgot password email will have a destination to users.forgot_password_link appending a token to that URL. The reset the password, you will make the following API Call.

curl -X PUT -H "Content-Type: application/json"
     -d '{"email":"6956ccdd329b81b2a5d715a53021c3f3","password":"123456"}'
     http://127.0.0.1/users/me
		

User Permissions

Some API calls will require higher permission levels to access resources not owned by the user.

By default, a controller requires a permission level of 100 to perform such actions.

If you want to change this behaviour, you can do so by overriding the routes property of the controller. For example this would be the new routes property to make getting a resource or listing resources public.

public static $routes = [
    'get_' => ['function' => 'getAll'],
    'get_/{id}' => ['function' => 'getOne'],
    'post_' => ['function' => 'create', 'permissions' => ['admin' => 100], 'authenticate' => 'hasAccess'],
    'put_/{id}' => ['function' => 'update', 'permissions' => ['admin' => 100], 'authenticate' => 'hasAccess'],
    'delete_/{id}' => ['function' => 'delete', 'permissions' => ['admin' => 100], 'authenticate' => 'hasAccess']
];
		

Similarly, if you want to have multiple levels of users, you can specify for each action what the permission level is for the access.

public static $routes = [
    'get_' => ['function' => 'getAll'],
    'get_/{id}' => ['function' => 'getOne'],
    'post_' => ['function' => 'create', 'permissions' => ['admin' => 75], 'authenticate' => 'hasAccess'],
    'put_/{id}' => ['function' => 'update', 'permissions' => ['admin' => 50], 'authenticate' => 'hasAccess'],
    'delete_/{id}' => ['function' => 'delete', 'permissions' => ['admin' => 100], 'authenticate' => 'hasAccess']
];