added login / logout functionality and authorization rules via bouncer

This commit is contained in:
Sockenklaus
2021-10-17 17:11:21 +02:00
parent 43ee300bd2
commit 4b222c9921
14 changed files with 665 additions and 18 deletions

View File

@@ -4,7 +4,8 @@
"./commands",
"@adonisjs/core/build/commands/index.js",
"@adonisjs/repl/build/commands",
"@adonisjs/lucid/build/commands"
"@adonisjs/lucid/build/commands",
"@adonisjs/bouncer/build/commands"
],
"exceptionHandlerNamespace": "App/Exceptions/Handler",
"aliases": {
@@ -15,14 +16,16 @@
},
"preloads": [
"./start/routes",
"./start/kernel"
"./start/kernel",
"./start/bouncer"
],
"providers": [
"./providers/AppProvider",
"@adonisjs/core",
"@adonisjs/lucid",
"@adonisjs/session",
"@adonisjs/auth"
"@adonisjs/auth",
"@adonisjs/bouncer"
],
"aceProviders": [
"@adonisjs/repl"

View File

@@ -261,6 +261,42 @@
"alias": "c"
}
]
},
"make:policy": {
"settings": {},
"commandPath": "@adonisjs/bouncer/build/commands/MakePolicy",
"commandName": "make:policy",
"description": "Make a new bouncer policy",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the policy to create"
}
],
"aliases": [],
"flags": [
{
"name": "resource-model",
"propertyName": "resourceModel",
"type": "string",
"description": "Name of the resource model to authorize"
},
{
"name": "user-model",
"propertyName": "userModel",
"type": "string",
"description": "Name of the user model to be authorized"
},
{
"name": "actions",
"propertyName": "actions",
"type": "array",
"description": "Actions to implement"
}
]
}
},
"aliases": {}

View File

@@ -0,0 +1,22 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class AuthController {
public async login({auth, request, response}: HttpContextContract) {
const username = request.input('username')
const password = request.input('password')
try {
await auth.attempt(username, password)
response.ok("Login successful")
} catch (error) {
return error
}
}
public async logout({auth, response}: HttpContextContract) {
await auth.logout()
return response.ok('Logged out successfully')
}
}

View File

@@ -7,10 +7,8 @@ import Database from '@ioc:Adonis/Lucid/Database'
// TODO: #1 Implement paginator for Employee-Index
export default class EmployeesController {
public async index ({}: HttpContextContract) {
const report = Database.manager.report()
console.log(report)
public async index ({bouncer}: HttpContextContract) {
await bouncer.authorize('employees.index')
return await Database.from('employees').select('*')
}
@@ -35,8 +33,14 @@ export default class EmployeesController {
}
public async show ({params}: HttpContextContract) {
return await Employee.find(params.id)
public async show ({params, bouncer}: HttpContextContract) {
const emp = await Employee.findOrFail(params.id)
if (await bouncer.denies('employees.show', emp)){
return 'Not admin or wrong user'
}
return emp
}
public async update ({params, request}: HttpContextContract) {

View File

@@ -25,6 +25,12 @@ export default class User extends BaseModel {
@hasOne(() => Employee)
public employeeProfile : HasOne<typeof Employee>
@column()
public role : string
@column()
public isActive : boolean
@beforeSave()
public static async hashPassword(user: User) {
if(user.$dirty.password){

16
contracts/bouncer.ts Normal file
View File

@@ -0,0 +1,16 @@
/**
* Contract source: https://git.io/Jte3v
*
* Feel free to let us know via PR, if you find something broken in this config
* file.
*/
import { actions, policies } from '../start/bouncer'
declare module '@ioc:Adonis/Addons/Bouncer' {
type ApplicationActions = ExtractActionsTypes<typeof actions>
type ApplicationPolicies = ExtractPoliciesTypes<typeof policies>
interface ActionsList extends ApplicationActions {}
interface PoliciesList extends ApplicationPolicies {}
}

View File

@@ -0,0 +1,23 @@
import Hash from '@ioc:Adonis/Core/Hash'
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
import User from 'App/Models/User'
export default class Users extends BaseSchema {
protected tableName = 'users'
public async up () {
this.schema.alterTable(this.tableName, (table) => {
table.boolean('is_active').defaultTo(false)
table.string('role')
.defaultTo('employee')
.notNullable()
})
}
public async down () {
this.schema.alterTable(this.tableName, (table) => {
table.dropColumn('is_active')
table.dropColumn('role')
})
}
}

View File

@@ -0,0 +1,31 @@
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import Logger from '@ioc:Adonis/Core/Logger'
import Employee from 'App/Models/Employee'
export default class EmployeeSeeder extends BaseSeeder {
public async run () {
try {
await Employee.createMany([
{
firstName: 'Pascal',
lastName: 'König',
shorthand: 'PK'
},
{
firstName: 'Sandra',
lastName: 'Sühl',
shorthand: 'SS'
},
{
firstName: 'Karin',
lastName: 'Behr',
shorthand: 'KB'
}
])
} catch (error) {
Logger.error(error)
}
}
}

21
database/seeders/User.ts Normal file
View File

@@ -0,0 +1,21 @@
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import User from 'App/Models/User'
import Logger from '@ioc:Adonis/Core/Logger'
export default class UserSeeder extends BaseSeeder {
public async run () {
try {
await User.create({
username: 'admin',
password: 'admin',
role: 'admin',
email: 'test@test.de',
isActive: true
})
}
catch(error) {
Logger.error(error.message)
}
}
}

418
package-lock.json generated
View File

@@ -9,11 +9,13 @@
"version": "1.0.0",
"dependencies": {
"@adonisjs/auth": "^8.0.10",
"@adonisjs/bouncer": "^2.2.5",
"@adonisjs/core": "^5.4.0",
"@adonisjs/lucid": "^16.2.1",
"@adonisjs/repl": "^3.1.6",
"@adonisjs/session": "^6.1.2",
"luxon": "^2.0.2",
"phc-argon2": "^1.1.2",
"proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13",
"source-map-support": "^0.5.20",
@@ -144,6 +146,27 @@
"@adonisjs/http-server": "^5.0.0"
}
},
"node_modules/@adonisjs/bouncer": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@adonisjs/bouncer/-/bouncer-2.2.5.tgz",
"integrity": "sha512-f060bMQwjJBAQ2pTtUrCbJ3n3/J3nQvzdrpWpWSEzdn8bdZALGh2R1nIhH0cVh8lMQuXzowo9ojxjWGFI0LfmQ==",
"dependencies": {
"@poppinss/utils": "^3.2.0"
},
"peerDependencies": {
"@adonisjs/auth": "^8.0.0",
"@adonisjs/core": "^5.1.0",
"@adonisjs/view": "^6.0.0"
},
"peerDependenciesMeta": {
"@adonisjs/auth": {
"optional": true
},
"@adonisjs/view": {
"optional": true
}
}
},
"node_modules/@adonisjs/config": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@adonisjs/config/-/config-3.0.5.tgz",
@@ -563,6 +586,121 @@
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"node_modules/@kdf/salt": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@kdf/salt/-/salt-2.0.1.tgz",
"integrity": "sha512-1RBY7HcGYuWBm0+4ygjdRerN+mhpuT5picGB6+azqUXsz/IZljegrKkeHRiV6wuxY8n4HrxOuw8ou7JuGxRWdQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz",
"integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==",
"dependencies": {
"detect-libc": "^1.0.3",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.1",
"nopt": "^5.0.0",
"npmlog": "^4.1.2",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"tar": "^6.1.0"
},
"bin": {
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/minipass": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz",
"integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/tar": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@@ -1277,6 +1415,17 @@
"integrity": "sha512-cQH/NP250gOF9k3TTDhVsTOPSAvyH4MhKVZ4ryYiihA+vnP27sut1gVIrRas3Evl5d2wEgWVGI5DgdP/ZFSk0w==",
"dev": true
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/aggregate-error": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -1421,6 +1570,21 @@
"safe-buffer": "~5.1.0"
}
},
"node_modules/argon2": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.28.2.tgz",
"integrity": "sha512-8oRk3kPlL0lLletENzhpbF9zoZJqvIHwTkjBseMrg1uD4gBMqhqnjJz1z3lEtwT0oqQAEkEwsEpsjaQBBRHcWw==",
"hasInstallScript": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.1",
"@phc/format": "^1.0.0",
"node-addon-api": "^3.0.2",
"opencollective-postinstall": "^2.0.3"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -3996,6 +4160,18 @@
"npm": ">=1.3.7"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -4696,7 +4872,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"dependencies": {
"semver": "^6.0.0"
},
@@ -4711,7 +4886,6 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
@@ -5226,6 +5400,17 @@
"lodash": "^4.17.21"
}
},
"node_modules/node-fetch": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -5669,6 +5854,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/opencollective-postinstall": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
"bin": {
"opencollective-postinstall": "index.js"
}
},
"node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -5995,6 +6188,20 @@
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"node_modules/phc-argon2": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/phc-argon2/-/phc-argon2-1.1.2.tgz",
"integrity": "sha512-R+1G4/lZHPQrLKiYBSio7xhU0vhfP5mxLYJBuWWiGAtynorRM4QtQGZcvnT4BTaRZOUaCaqlR4PC8cBrQmxZ3A==",
"dependencies": {
"@kdf/salt": "^2.0.1",
"@phc/format": "^1.0.0",
"argon2": "^0.28.2",
"tsse": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@@ -6591,7 +6798,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -7686,6 +7892,11 @@
"node": ">=0.8"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"node_modules/truncatise": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz",
@@ -7696,6 +7907,17 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tsse": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tsse/-/tsse-2.0.0.tgz",
"integrity": "sha512-KiYDxhCTbCUQWXtCSF2OWafC71C/ZUZP6TyCh/w7nPjzY1ZLY70KtDSfmePs3H4vSdxQotqdJvAkGAofxsQ05w==",
"dependencies": {
"safe-buffer": "^5.1.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -7977,6 +8199,11 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"optional": true
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"node_modules/webpack-merge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
@@ -7986,6 +8213,15 @@
"lodash": "^4.17.15"
}
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -8153,6 +8389,14 @@
"media-typer": "^1.1.0"
}
},
"@adonisjs/bouncer": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@adonisjs/bouncer/-/bouncer-2.2.5.tgz",
"integrity": "sha512-f060bMQwjJBAQ2pTtUrCbJ3n3/J3nQvzdrpWpWSEzdn8bdZALGh2R1nIhH0cVh8lMQuXzowo9ojxjWGFI0LfmQ==",
"requires": {
"@poppinss/utils": "^3.2.0"
}
},
"@adonisjs/config": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@adonisjs/config/-/config-3.0.5.tgz",
@@ -8507,6 +8751,90 @@
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"@kdf/salt": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@kdf/salt/-/salt-2.0.1.tgz",
"integrity": "sha512-1RBY7HcGYuWBm0+4ygjdRerN+mhpuT5picGB6+azqUXsz/IZljegrKkeHRiV6wuxY8n4HrxOuw8ou7JuGxRWdQ=="
},
"@mapbox/node-pre-gyp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz",
"integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==",
"requires": {
"detect-libc": "^1.0.3",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.1",
"nopt": "^5.0.0",
"npmlog": "^4.1.2",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"tar": "^6.1.0"
},
"dependencies": {
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"minipass": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz",
"integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"requires": {
"abbrev": "1"
}
},
"tar": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@@ -9042,6 +9370,14 @@
"integrity": "sha512-cQH/NP250gOF9k3TTDhVsTOPSAvyH4MhKVZ4ryYiihA+vnP27sut1gVIrRas3Evl5d2wEgWVGI5DgdP/ZFSk0w==",
"dev": true
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
}
},
"aggregate-error": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -9156,6 +9492,17 @@
}
}
},
"argon2": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.28.2.tgz",
"integrity": "sha512-8oRk3kPlL0lLletENzhpbF9zoZJqvIHwTkjBseMrg1uD4gBMqhqnjJz1z3lEtwT0oqQAEkEwsEpsjaQBBRHcWw==",
"requires": {
"@mapbox/node-pre-gyp": "^1.0.1",
"@phc/format": "^1.0.0",
"node-addon-api": "^3.0.2",
"opencollective-postinstall": "^2.0.3"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -11168,6 +11515,15 @@
"sshpk": "^1.7.0"
}
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -11687,7 +12043,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
},
@@ -11695,8 +12050,7 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -12111,6 +12465,14 @@
"lodash": "^4.17.21"
}
},
"node-fetch": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -12454,6 +12816,11 @@
"is-wsl": "^2.2.0"
}
},
"opencollective-postinstall": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
},
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -12701,6 +13068,17 @@
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"phc-argon2": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/phc-argon2/-/phc-argon2-1.1.2.tgz",
"integrity": "sha512-R+1G4/lZHPQrLKiYBSio7xhU0vhfP5mxLYJBuWWiGAtynorRM4QtQGZcvnT4BTaRZOUaCaqlR4PC8cBrQmxZ3A==",
"requires": {
"@kdf/salt": "^2.0.1",
"@phc/format": "^1.0.0",
"argon2": "^0.28.2",
"tsse": "^2.0.0"
}
},
"picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@@ -13152,7 +13530,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
@@ -14003,6 +14380,11 @@
"punycode": "^2.1.1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"truncatise": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz",
@@ -14013,6 +14395,14 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"tsse": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tsse/-/tsse-2.0.0.tgz",
"integrity": "sha512-KiYDxhCTbCUQWXtCSF2OWafC71C/ZUZP6TyCh/w7nPjzY1ZLY70KtDSfmePs3H4vSdxQotqdJvAkGAofxsQ05w==",
"requires": {
"safe-buffer": "^5.1.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -14235,6 +14625,11 @@
}
}
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"webpack-merge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
@@ -14244,6 +14639,15 @@
"lodash": "^4.17.15"
}
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@@ -24,11 +24,13 @@
},
"dependencies": {
"@adonisjs/auth": "^8.0.10",
"@adonisjs/bouncer": "^2.2.5",
"@adonisjs/core": "^5.4.0",
"@adonisjs/lucid": "^16.2.1",
"@adonisjs/repl": "^3.1.6",
"@adonisjs/session": "^6.1.2",
"luxon": "^2.0.2",
"phc-argon2": "^1.1.2",
"proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13",
"source-map-support": "^0.5.20",

67
start/bouncer.ts Normal file
View File

@@ -0,0 +1,67 @@
/**
* Contract source: https://git.io/Jte3T
*
* Feel free to let us know via PR, if you find something broken in this config
* file.
*/
import Bouncer from '@ioc:Adonis/Addons/Bouncer'
import User from 'App/Models/User'
import Employee from 'App/Models/Employee'
/*
|--------------------------------------------------------------------------
| Bouncer Actions
|--------------------------------------------------------------------------
|
| Actions allows you to separate your application business logic from the
| authorization logic. Feel free to make use of policies when you find
| yourself creating too many actions
|
| You can define an action using the `.define` method on the Bouncer object
| as shown in the following example
|
| ```
| Bouncer.define('deletePost', (user: User, post: Post) => {
| return post.user_id === user.id
| })
| ```
|
|****************************************************************
| NOTE: Always export the "actions" const from this file
|****************************************************************
*/
export const { actions } = Bouncer
.define('employees.index', (user: User) => {
return user.role === 'admin'
})
.define('employees.show', (user: User, employee : Employee) => {
return user.role === 'admin' || user.id === employee.userId
})
/*
|--------------------------------------------------------------------------
| Bouncer Policies
|--------------------------------------------------------------------------
|
| Policies are self contained actions for a given resource. For example: You
| can create a policy for a "User" resource, one policy for a "Post" resource
| and so on.
|
| The "registerPolicies" accepts a unique policy name and a function to lazy
| import the policy
|
| ```
| Bouncer.registerPolicies({
| UserPolicy: () => import('App/Policies/User'),
| PostPolicy: () => import('App/Policies/Post')
| })
| ```
|
|****************************************************************
| NOTE: Always export the "policies" const from this file
|****************************************************************
*/
export const { policies } = Bouncer.registerPolicies({})

View File

@@ -20,4 +20,15 @@
import Route from '@ioc:Adonis/Core/Route'
Route.resource('employees', 'EmployeesController').except(['create', 'edit'])
Route.group(() => {
Route.post('login', 'AuthController.login').as('login')
})
.prefix('api/v1')
Route.group(() => {
Route.get('logout', 'AuthController.logout').as('logout')
Route.resource('employees', 'EmployeesController').apiOnly()
})
.prefix('api/v1')
.middleware('auth')

View File

@@ -30,7 +30,8 @@
"@adonisjs/repl",
"@adonisjs/lucid",
"@adonisjs/session",
"@adonisjs/auth"
"@adonisjs/auth",
"@adonisjs/bouncer"
]
}
}