├── .editorconfig
├── .eslintrc
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── commands
└── MakePolicy.js
├── instructions.js
├── instructions.md
├── package-lock.json
├── package.json
├── providers
└── GuardProvider.js
├── src
├── Exceptions
│ └── index.js
├── Middleware
│ ├── Can.js
│ └── GuardInit.js
└── ViewBindings
│ ├── Can.js
│ └── Cannot.js
├── templates
├── Policy.mustache
└── acl.js
└── test
└── unit
└── view.spec.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | indent_style = space
7 | indent_size = 2
8 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@slynova",
3 | "env": {
4 | "node": true
5 | },
6 | "globals": {
7 | "use": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage
2 | node_modules
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test
2 | .editorconfig
3 | .eslintrc
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | # [1.0.0-beta.5](https://github.com/RomainLanz/adonis-guard/compare/1.0.0-beta.4...1.0.0-beta.5) (2018-09-11)
3 |
4 |
5 | ### Bug Fixes
6 |
7 | * **tag:** allow to have only one arg ([d44b585](https://github.com/RomainLanz/adonis-guard/commit/d44b585))
8 |
9 |
10 |
11 |
12 | # [1.0.0-beta.4](https://github.com/RomainLanz/adonis-guard/compare/1.0.0-beta.3...1.0.0-beta.4) (2018-07-20)
13 |
14 |
15 | ### Bug Fixes
16 |
17 | * **exception:** invoke correctly the exception ([c26d297](https://github.com/RomainLanz/adonis-guard/commit/c26d297))
18 | * **instructions:** replace this by cli ([e032d09](https://github.com/RomainLanz/adonis-guard/commit/e032d09))
19 | * **monkey-patch:** sometimes it happens to do bad code ([ef0eec9](https://github.com/RomainLanz/adonis-guard/commit/ef0eec9))
20 |
21 |
22 | ### Features
23 |
24 | * monkey patch [@slynova](https://github.com/slynova)/fence to fetch resource ([3614db1](https://github.com/RomainLanz/adonis-guard/commit/3614db1))
25 |
26 |
27 |
28 |
29 | # [1.0.0-beta.3](https://github.com/RomainLanz/adonis-guard/compare/1.0.0-beta.2...1.0.0-beta.3) (2018-07-05)
30 |
31 |
32 | ### Bug Fixes
33 |
34 | * **middleware:** condition is now inversed ([ff908ba](https://github.com/RomainLanz/adonis-guard/commit/ff908ba))
35 |
36 |
37 |
38 |
39 | # [1.0.0-beta.2](https://github.com/RomainLanz/adonis-guard/compare/1.0.0-beta.1...1.0.0-beta.2) (2018-07-05)
40 |
41 |
42 | ### Bug Fixes
43 |
44 | * **view:** corrects export statment of [@cannot](https://github.com/cannot) tag ([f68fc2c](https://github.com/RomainLanz/adonis-guard/commit/f68fc2c))
45 |
46 |
47 | ### Features
48 |
49 | * **middleware:** add can middleware ([d9cafda](https://github.com/RomainLanz/adonis-guard/commit/d9cafda))
50 |
51 |
52 |
53 |
54 | # 1.0.0-beta.1 (2018-07-05)
55 |
56 |
57 | ### Bug Fixes
58 |
59 | * **instructions:** copy the file to the correct place ([98dd5ec](https://github.com/RomainLanz/adonis-guard/commit/98dd5ec))
60 | * **middleware:** auth.user is accessible on ctx ([5f31ca2](https://github.com/RomainLanz/adonis-guard/commit/5f31ca2))
61 | * **Middleware:** remove wrong import ([2be31c4](https://github.com/RomainLanz/adonis-guard/commit/2be31c4))
62 | * **Middleware:** Use view from the context ([bf57e6b](https://github.com/RomainLanz/adonis-guard/commit/bf57e6b))
63 | * **view-global:** send directly Guard object ([9446a08](https://github.com/RomainLanz/adonis-guard/commit/9446a08))
64 |
65 |
66 | ### Features
67 |
68 | * **view:** add cannot tag ([60974a7](https://github.com/RomainLanz/adonis-guard/commit/60974a7))
69 | * **view:** add Guard global ([fa22088](https://github.com/RomainLanz/adonis-guard/commit/fa22088))
70 | * **view:** implement [@can](https://github.com/can) tag ([6ec3a00](https://github.com/RomainLanz/adonis-guard/commit/6ec3a00))
71 | * **view:** start working on can tag ([e9c6fe6](https://github.com/RomainLanz/adonis-guard/commit/e9c6fe6))
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Slynova
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Adonis Guard 🔰
2 |
3 | This package is an **authorization provider** built on top of [@slynova/fence](https://github.com/Slynova-Org/fence).
4 |
5 | ## Getting Started
6 |
7 | Install the package using the `adonis` CLI.
8 |
9 | ```bash
10 | > adonis install adonis-guard
11 | ```
12 |
13 | Follow instruction that are displayed ([or read them here](https://github.com/RomainLanz/adonis-guard/blob/master/instructions.md)).
14 |
15 | ## Defining your authorization
16 |
17 | ### Gate
18 | Gates must be defined inside the `start/acl.js` file. This file will be loaded only once when the server is launch.
19 | To define a gate, use the `Gate` facade.
20 |
21 | ```js
22 | // start/acl.js
23 | const Gate = use('Gate')
24 |
25 | Gate.define('gateName', (user, resource) => {
26 | // Payload
27 | // e.g. return user.id === resource.author_id
28 | })
29 | ```
30 |
31 | ### Policy
32 | You can generate a new policy by using the command `adonis make:policy {name}`.
33 | This will generate a file in `app/Policies/{Name}Policy.js`.
34 | To attach a policy to a resource, you need to call the `policy` method of the `Gate` facade.
35 |
36 | ```js
37 | // start/acl.js
38 | const Gate = use('Gate')
39 |
40 | Gate.policy('App/Models/MyResource', 'App/Policies/MyPolicy')
41 | ```
42 |
43 | ## Usage
44 |
45 | Adonis Guard automaticaly share an instance of the `guard` in the context of each request.
46 | To validate the authorization of a user you simply need to extract it from the context and run the gate/policy.
47 |
48 | ```js
49 | // Controller
50 | async show ({ guard, params }) {
51 | const post = await Post.find(params.id)
52 |
53 | if (guard.denies('show', post)) {
54 | // abort 401
55 | }
56 |
57 | // ...
58 | }
59 | ```
60 |
61 | ```js
62 | // RouteValidator
63 | async authorize () {
64 | const post = await Post.find(this.ctx.params.id)
65 |
66 | if (this.ctx.guard.denies('show', post)) {
67 | // abort 401
68 | }
69 |
70 | // ...
71 | }
72 | ```
73 |
74 | You can also use it in your view to choose to display or not an element.
75 |
76 | ```html
77 | @if(guard.allows('edit', post))
78 | Edit
79 | @endif
80 |
81 | @can('edit', post)
82 | Edit
83 | @endcan
84 |
85 | @cannot('edit', post)
86 |
Not allowed!
87 | @endcannot
88 | ```
89 |
90 | The `@can` and `@cannot` tags have the same signature as `guard.allows()` and `guard.denies()`.
91 |
92 | You can also use the middleware `can` in your route.
93 | Notice that this middleware doesn't work with resource. It will execute a gate with the loggedIn user only.
94 |
95 | ```js
96 | Route.get('/admin/posts', 'Admin/PostController.index')
97 | .middleware('can:viewAdminPosts')
98 | ```
99 |
100 | A second argument can be supplied that will replace a resource in your gate. This is useful when you want to have dynamic route rules.
101 |
102 | ```js
103 | Route.get('/admin/posts', 'Admin/PostController.index')
104 | .middleware('can:hasRole,admin,editor')
105 | ```
106 |
107 | `admin,editor` will be extracted into an array that you can retrieve as the second parameter in your gate.
108 |
109 | **Public API**
110 |
111 | ```js
112 | guard.allows('gateName/Policy Method', resource) // It will use per default the authenticated user or return false if not authenticated
113 | guard.denies('gateName/Policy Method', resource) // It will use per default the authenticated user or return true if not authenticated
114 | guard.allows('gateName/Policy Method', resource, user)
115 | guard.denies('gateName/Policy Method', resource, user)
116 | guard.can(user).pass('gateName').for(resource)
117 | guard.can(user).callPolicy('Policy Method', resource)
118 | ```
119 |
--------------------------------------------------------------------------------
/commands/MakePolicy.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const _ = require('lodash')
11 | const { singular } = require('pluralize')
12 | const { Command } = require('@adonisjs/ace')
13 | const { basename, join, sep } = require('path')
14 |
15 | class MakePolicy extends Command {
16 | /**
17 | * Command signature required by ace.
18 | *
19 | * @return {string}
20 | */
21 | static get signature () {
22 | return 'make:policy { name: Name of the policy }'
23 | }
24 |
25 | /**
26 | * Command description.
27 | *
28 | * @return {string}
29 | */
30 | static get description () {
31 | return 'Make a new Policy'
32 | }
33 |
34 | /**
35 | * Returns file name for policy.
36 | *
37 | *
38 | * @param {String} name
39 | *
40 | * @return {String}
41 | */
42 | $getFileName (name) {
43 | name = name.replace(/policy/ig, '')
44 |
45 | return `${singular(_.upperFirst(_.camelCase(name)))}Policy`
46 | }
47 |
48 | /**
49 | * Returns path to the policy file
50 | *
51 | * @param {String} name
52 | *
53 | * @return {String}
54 | */
55 | $getFilePath (name) {
56 | const baseName = basename(name)
57 | const normalizedName = name.replace(baseName, this.$getFileName(baseName))
58 |
59 | return `${join(process.cwd(), 'app/Policies', normalizedName)}.js`
60 | }
61 |
62 | /**
63 | * Returns name of resource from policy name.
64 | *
65 | * @param {String} name
66 | *
67 | * @return {String}
68 | */
69 | $getResourceName (name) {
70 | return this.$getFileName(name).replace('Policy', '').toLowerCase()
71 | }
72 |
73 | /**
74 | * Method called when command is executed. This method will
75 | * require all files from the migrations directory
76 | * and execute all pending schema files.
77 | *
78 | * @param {object} args
79 | *
80 | * @return {void}
81 | */
82 | async handle ({ name }) {
83 | const templatePath = join(__dirname, '../templates/Policy.mustache')
84 | const filePath = this.$getFilePath(name)
85 | const templateContent = await this.readFile(templatePath, 'utf-8')
86 |
87 | await this.generateFile(filePath, templateContent, {
88 | name: this.$getFileName(name),
89 | resource: this.$getResourceName(name),
90 | })
91 |
92 | const createdFile = filePath.replace(process.cwd(), '').replace(sep, '')
93 |
94 | // eslint-disable-next-line no-console
95 | console.log(`${this.icon('success')} ${this.chalk.green('create')} ${createdFile}`)
96 | }
97 | }
98 |
99 | module.exports = MakePolicy
100 |
--------------------------------------------------------------------------------
/instructions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { join } = require('path')
11 |
12 | module.exports = async function (cli) {
13 | await cli.copy(join(__dirname, 'templates/acl.js'), join(cli.helpers.appRoot(), 'start/acl.js'))
14 | .catch((e) => {})
15 | cli.command.completed('create', 'start/acl.js')
16 | }
17 |
--------------------------------------------------------------------------------
/instructions.md:
--------------------------------------------------------------------------------
1 | ## Registering provider
2 |
3 | The provider is registered inside `start/app.js` file under `providers` array.
4 |
5 | ```js
6 | const providers = [
7 | 'adonis-guard/providers/GuardProvider'
8 | ]
9 | ```
10 |
11 | ## Registering middleware
12 |
13 | Add the middleware `Adonis/Middleware/GuardInit` in the `start/kernel.js` file **after** `AuthInit`.
14 | Add the middleware `Adonis/Middleware/Can` in the `start/kernel.js` file in `namedMiddleware` array.
15 |
16 | ```js
17 | // start/kernel.js
18 | const globalMiddleware = [
19 | ...
20 | 'Adonis/Middleware/AuthInit',
21 | 'Adonis/Middleware/GuardInit',
22 | ...
23 | ]
24 |
25 | const namedMiddleware = {
26 | ...
27 | can: 'Adonis/Middleware/Can',
28 | ...
29 | }
30 | ```
31 |
32 |
33 | ## Loading acl.js
34 |
35 | Add the `start/acl.js` file to your Ignitor starting script.
36 |
37 | ```js
38 | // server.js
39 |
40 | new Ignitor(require('@adonisjs/fold'))
41 | .appRoot(__dirname)
42 | .preLoad('start/acl')
43 | .fireHttpServer()
44 | .catch(console.error)
45 | ```
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "adonis-guard",
3 | "version": "1.0.0-beta.5",
4 | "main": "index.js",
5 | "repository": "git@github.com:RomainLanz/adonis-guard.git",
6 | "author": "Romain Lanz ",
7 | "license": "MIT",
8 | "scripts": {
9 | "lint": "eslint src providers"
10 | },
11 | "dependencies": {
12 | "@adonisjs/generic-exceptions": "^3.0.1",
13 | "@slynova/fence": "^1.0.6",
14 | "lodash": "^4.17.21",
15 | "pluralize": "^8.0.0"
16 | },
17 | "devDependencies": {
18 | "@adonisjs/ace": "^5.0.8",
19 | "@adonisjs/fold": "^4.0.9",
20 | "@slynova/eslint-config": "^1.0.5",
21 | "cz-conventional-changelog": "^3.3.0",
22 | "edge.js": "^1.1.4",
23 | "eslint": "^7.20.0"
24 | },
25 | "config": {
26 | "commitizen": {
27 | "path": "./node_modules/cz-conventional-changelog"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/providers/GuardProvider.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { Gate, Helpers } = require('@slynova/fence')
11 | const { ServiceProvider } = require('@adonisjs/fold')
12 |
13 | class GuardProvider extends ServiceProvider {
14 | /**
15 | * Registers providers for all the Guard related
16 | * commands.
17 | *
18 | * @return {void}
19 | */
20 | $registerCommands () {
21 | this.app.bind('Guard/Commands/Make:Policy', () => require('../commands/MakePolicy')) // eslint-disable-line global-require
22 | }
23 |
24 | /**
25 | * Registers providers for all the Guard related
26 | * classes.
27 | *
28 | * @return {void}
29 | */
30 | $registerAlias () {
31 | this.app.singleton('Adonis/Addons/Gate', () => Gate)
32 | this.app.alias('Adonis/Addons/Gate', 'Gate')
33 |
34 | this.app.bind('Adonis/Middleware/Can', () => {
35 | const Can = require('../src/Middleware/Can') // eslint-disable-line global-require
36 | return new Can()
37 | })
38 |
39 | this.app.bind('Adonis/Middleware/GuardInit', () => {
40 | const GuardInit = require('../src/Middleware/GuardInit') // eslint-disable-line global-require
41 | return new GuardInit()
42 | })
43 | }
44 |
45 | $monkeyPatch () {
46 | Helpers.formatResourceName = (resource) => {
47 | return resource.$gate.namespace
48 | }
49 |
50 | Gate.policy = (resourceName, policyName) => {
51 | const resource = this.app.use(resourceName)
52 | resource.prototype.$gate = { namespace: resourceName }
53 |
54 | const policy = this.app.make(policyName)
55 |
56 | Gate.$getStorage().storePolicy(resourceName, policy)
57 | }
58 | }
59 |
60 | /**
61 | * Register namespaces to the IoC container
62 | *
63 | * @method register
64 | *
65 | * @return {void}
66 | */
67 | register () {
68 | this.$registerCommands()
69 | this.$registerAlias()
70 | this.$monkeyPatch()
71 | }
72 |
73 | boot () {
74 | const ace = require('@adonisjs/ace') // eslint-disable-line global-require
75 | ace.addCommand('Guard/Commands/Make:Policy')
76 |
77 | this.app.with('Adonis/Src/View', (View) => {
78 | const Can = require('../src/ViewBindings/Can')
79 | const Cannot = require('../src/ViewBindings/Cannot')
80 |
81 | View.tag(new Can())
82 | View.tag(new Cannot())
83 | })
84 | }
85 | }
86 |
87 | module.exports = GuardProvider
88 |
--------------------------------------------------------------------------------
/src/Exceptions/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { RuntimeException } = require('@adonisjs/generic-exceptions')
11 |
12 | class AuthorizationException extends RuntimeException {}
13 |
14 | module.exports = { AuthorizationException }
15 |
--------------------------------------------------------------------------------
/src/Middleware/Can.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { AuthorizationException } = require('../Exceptions')
11 |
12 | class Can {
13 | async handle ({ auth, guard }, next, [method, ...argument]) {
14 | if (!guard.can(auth.user).pass(method).for(argument)) {
15 | throw AuthorizationException.invoke('Unauthorized', 401, 'E_UNAUTHORIZED')
16 | }
17 |
18 | await next()
19 | }
20 | }
21 |
22 | module.exports = Can
23 |
--------------------------------------------------------------------------------
/src/Middleware/GuardInit.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { Guard } = require('@slynova/fence')
11 |
12 | class GuardInit {
13 | async handle (ctx, next) {
14 | const guard = Guard.setDefaultUser(ctx.auth.user || null)
15 |
16 | /**
17 | * Adding guard in the context
18 | */
19 | ctx.guard = guard
20 |
21 | /**
22 | * Sharing guard with the view
23 | */
24 | if (ctx.view && typeof (ctx.view.share) === 'function') {
25 | ctx.view.share({ guard })
26 | }
27 |
28 | await next()
29 | }
30 | }
31 |
32 | module.exports = GuardInit
33 |
--------------------------------------------------------------------------------
/src/ViewBindings/Can.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { BaseTag } = require('edge.js')
11 |
12 | class Can extends BaseTag {
13 | /**
14 | * The tag name.
15 | *
16 | * @return {String}
17 | */
18 | get tagName () {
19 | return 'can'
20 | }
21 |
22 | /**
23 | * Tag is a block tag.
24 | *
25 | * @return {Boolean}
26 | */
27 | get isBlock () {
28 | return true
29 | }
30 |
31 | /**
32 | * Compile the template.
33 | *
34 | * @param {Object} compiler
35 | * @param {Object} lexer
36 | * @param {Object} buffer
37 | * @param {String} options.body
38 | * @param {Number} options.lineno
39 | *
40 | * @return {void}
41 | */
42 | compile (compiler, lexer, buffer, { body, childs, lineno }) {
43 | const args = this._compileStatement(lexer, body, lineno).toStatement()
44 | const [ability, resource, user] = Array.isArray(args) ? args : [args]
45 |
46 | buffer.writeLine(`if (this.context.resolve('guard').allows(${ability}, ${resource}, ${user})) {`)
47 | buffer.indent()
48 |
49 | childs.forEach(child => compiler.parseLine(child))
50 |
51 | buffer.dedent()
52 | buffer.writeLine('}')
53 | }
54 |
55 | run () {
56 | }
57 | }
58 |
59 | module.exports = Can
60 |
--------------------------------------------------------------------------------
/src/ViewBindings/Cannot.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const { BaseTag } = require('edge.js')
11 |
12 | class Cannot extends BaseTag {
13 | /**
14 | * The tag name.
15 | *
16 | * @return {String}
17 | */
18 | get tagName () {
19 | return 'cannot'
20 | }
21 |
22 | /**
23 | * Tag is a block tag.
24 | *
25 | * @return {Boolean}
26 | */
27 | get isBlock () {
28 | return true
29 | }
30 |
31 | /**
32 | * Compile the template.
33 | *
34 | * @param {Object} compiler
35 | * @param {Object} lexer
36 | * @param {Object} buffer
37 | * @param {String} options.body
38 | * @param {Number} options.lineno
39 | *
40 | * @return {void}
41 | */
42 | compile (compiler, lexer, buffer, { body, childs, lineno }) {
43 | const args = this._compileStatement(lexer, body, lineno).toStatement()
44 | const [ability, resource, user] = Array.isArray(args) ? args : [args]
45 |
46 | buffer.writeLine(`if (this.context.resolve('guard').denies(${ability}, ${resource}, ${user})) {`)
47 | buffer.indent()
48 |
49 | childs.forEach(child => compiler.parseLine(child))
50 |
51 | buffer.dedent()
52 | buffer.writeLine('}')
53 | }
54 |
55 | run () {
56 | }
57 | }
58 |
59 | module.exports = Cannot
60 |
--------------------------------------------------------------------------------
/templates/Policy.mustache:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | class {{name}} {
4 | index (user) {
5 | //
6 | }
7 |
8 | store (user) {
9 | //
10 | }
11 |
12 | show (user, {{resource}}) {
13 | //
14 | }
15 |
16 | create (user) {
17 | //
18 | }
19 |
20 | update (user, {{resource}}) {
21 | //
22 | }
23 |
24 | edit (user) {
25 | //
26 | }
27 |
28 | destroy (user, {{resource}}) {
29 | //
30 | }
31 | }
32 |
33 | module.exports = {{name}}
34 |
--------------------------------------------------------------------------------
/templates/acl.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const Gate = use('Gate')
4 |
5 | //
6 |
--------------------------------------------------------------------------------
/test/unit/view.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * adonis-guard
5 | *
6 | * @license MIT
7 | * @copyright Slynova - Romain Lanz
8 | */
9 |
10 | const test = require('japa')
11 | const edge = require('edge.js')
12 |
13 | class View {
14 | constructor () {
15 | this.engine = edge
16 | this.tag = this.engine.tag.bind(this.engine)
17 | }
18 | }
19 |
20 |
21 |
--------------------------------------------------------------------------------