# Nico Auth

## Usage

Download or clone from url `https://gitlab.com/amar-lamichhane/nico-auth.git`


* Add service providers to app.php providers list 
```php
'providers'=>[
     ...,
     NicoAuth\ServiceProvider::class,
]
```


* Publish config to local config folder. 
```bash
php artisan vendor:publish --class=NicoAuth\ServiceProvider
```


* Run `php artisan migrate` to run the migrations for NicoAuth

### Config 

* `namespaces`: Array of namespaces you application is going use. `app` is the default global option.
You can have as many namespaces as you want. 
* `providers`: Associative array of namespace and class name. Each namespace, with an exception to `app`, 
should have a class name assigned to it. It must be an instance of eloquent model. 
* `userModel`: A model/class that is used for authentication. Usually it will be User Eloquent Model. 
But you are free to use any class as long as it is an instance of `Illuminate\Database\Model`.


## Nico Auth Command

##### Add permission
```bash
php artisan nicoAuth:permission users.create --namespace=app
```
Of course you can add multiple permission by listing the permissions
```bash
php artisan nicoAuth:permission user.create user.remove user.invitation --namespace=app
```

##### Remove permission
```bash
php artisan nicoAuth:permission users.create --remove
```

##### List of available permissions
```bash
php artisan nicoAuth:permissions
```
To get list of permission only from a specific namespace
```bash
php artisan nicoAuth:permissions --namespace=app
```

##### Permission group
```bash
php artisan nicoAuth:permissionGroup {name} {--namespace=app} {--perm=*} {--namespaceId=validId} {--mode=write|append|remove|drop}
```

The namespace id should be a valid id for the given namespace with an exception to app.

Example to add a permission group
```bash
php artisan nicoAuth:permissionGroup superuser --namespace=app --perm=user.create --perm=user.remove --perm=user.invite
```

##### User Permission
We can give a user an explicit permission by User permission API
```bash 
nicoAuth:userPermission {userEmail} {--namespace=app} {--perm=*} {--namespaceId=validId} {--mode=write|append|remove|drop}
```

##### Assign permission Group to a user

```bash 
php artisan nicoAuth:userGroup {userEmail} {--namespace=app} {--remove}
```

For Example
```bash 
>>>php artisan nicoAuth:userGroup amar.smartmobe@gmail.com --namespace=app
>>>Choose one of the permission group.:
[0]root
[1]superuser
[2]manager
>2
>>>User 'amar.smartmobe@gmail.com' is successfully added to permission group 'app.manager'
```

## Authentication API

### Pre-requisites

Set user model in the config

```php
[
...,
'userModel'=>\App\User::class, //This must be an instance of NicoAuth\Contracts\Authenticatable
...,
]
```

Use the NicoAuths Traits in the user model

```php
use NicoAuth\Contracts\Authenticatable;
use Illuminate\Database\Model;
use NicoAuth\Database\Traits;

class User extend Model implements Authenticatable {
    use NicoAuths;
}
```
##### Load current permissions and permission groups of the Authenticatable

```php
$user = User::find(1);
$user->loadPermissionAndPermissionGroups(); 
```

##### Check if a user falls under a userGroup
```php
$user = User::find(1);
$user->loadPermissionAndPermissionGroups();
if($user->isA('app.manager')){//The argument should be prefixed with a namespace.
    //perform managerial task here
}  
```
if your namespace is other than app then you should supply the namespace id. E.g.
```php
$user = User::find(1);
$user->loadPermissionAndPermissionGroups();
if($user->isA('building.manager',$buildingId=233){
    //Perform managerial task for building
} 
```

##### Assign user to a permission Group

```php
$user = User::find(1);
$user->assignGroup(PermissionGroup::find(1);
```

##### Give a user explicit permissions

```php
$user = $user::find(1);
//If your namespace is other than app, you must supply a valid namespaceId
$user->permit(['user.create','user.remove'],$namespace='app',$namespaceId=null);
```
##### Revoke permissions
```php
$user = $user::find(1);
$user->revoke(['user.create','user.update'],$namespace='app',$namespaceId=null);
```

##### Rewrite all permissions for a user.

```php
$user = User::find(1);
$user->rewritePermission(['room.add','room.remove'],$namespace="app",$namespaceId=null);
//Explicit permission is re-written with the given list of permissions
```

##### Magic Methods

Sometime you might want to have a userGroup that is un-changing throughout the application and have its own method that could be accessed. 
You can achieve it. 

###### Update your config
```php
[
    'roles'=>[
            'root'=>'app.root',
            'superuser'=>'app.superuser',
            'roomManager'=>'building.roomManager'
    ]
]
```

The format is `'methodName'=>'fullyQualifiedGroup'`

Now you can have a method in the Authenticatable. Each method is prefixed by 'is'.

```php
$user = User::find(1);
$user->loadPermissionAndPermissionGroups();
if($user->isRoot()){
    //root action
}
if($user->isRoomManager($namespaceId = 1)){
    //do something with room manager.
}
```