Skip to content
This repository has been archived by the owner on May 20, 2023. It is now read-only.

Commit

Permalink
Adds missed files
Browse files Browse the repository at this point in the history
  • Loading branch information
butschster committed Nov 25, 2021
1 parent 1857fbb commit 9bb74bb
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 0 deletions.
46 changes: 46 additions & 0 deletions app/Modules/User/Interfaces/Console/Commands/CreateUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Modules\User\Interfaces\Console\Commands;

use Cycle\ORM\ORMInterface;
use Cycle\ORM\TransactionInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Modules\User\Domain\User;

class CreateUser extends Command
{
protected $signature = 'user:create {username?} {password?}';

public function handle(TransactionInterface $transaction, ORMInterface $orm)
{
if (! config('auth.enabled')) {
$this->error('Authentication is disabled.');

return;
}

$username = $this->argument('username') ?? env('AUTH_USERNAME', 'admin');
$password = $this->argument('password') ?? env('AUTH_PASSWORD', Str::random(8));


$user = $orm->getRepository(User::class)->findOne(['name' => $username]);
if ($user) {
$this->error(sprintf('User with given username [%s] exists. Try another name.', $username));

return;
}

$transaction->persist(new User($username, Hash::make($password)));
$transaction->run();

$this->info('User created.');
$this->table([], [
['Username', $username],
['Password', $password],
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Migration;

use Cycle\Migrations\Migration;

class OrmDefault1e5a31b92337b8a5a635afa30098a402 extends Migration
{
protected const DATABASE = 'default';

public function up(): void
{
$this->table('users')
->addColumn('remember_token', 'string', [
'nullable' => false,
'default' => null,
])
->addColumn('uuid', 'string', [
'nullable' => false,
'default' => null,
])
->addColumn('name', 'string', [
'nullable' => false,
'default' => null,
])
->addColumn('password', 'string', [
'nullable' => false,
'default' => null,
])
->addIndex(["name"], [
'name' => 'users_index_name_619fdbaa03862',
'unique' => true,
])
->setPrimaryKeys(["uuid"])
->create();
}

public function down(): void
{
$this->table('users')->drop();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Migration;

use Cycle\Migrations\Migration;

class OrmDefault1e5a31b92337b8a5a635afa30098a403 extends Migration
{
protected const DATABASE = 'default';

public function up(): void
{
$this->table('stored_events')
->addColumn('event_id', 'string', [
'nullable' => false,
'default' => null
])
->addColumn('event_type', 'string', [
'nullable' => false,
'default' => null
])
->addColumn('aggregate_root_id', 'string', [
'nullable' => false,
'default' => null
])
->addColumn('version', 'integer', [
'nullable' => false,
'default' => null
])
->addColumn('payload', 'json', [
'nullable' => false,
'default' => null
])
->setPrimaryKeys(["event_id"])
->create();
}

public function down(): void
{
$this->table('stored_events')->drop();
}
}
106 changes: 106 additions & 0 deletions resources/js/Pages/Auth/Login.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<div class="h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-sm w-full space-y-8">
<div class="flex flex-col items-center">
<svg class="text-blue-600 fill-current w-2/3" xmlns="http:https://www.w3.org/2000/svg" viewBox="0 0 117 24">
<path
d="M46.3 12.6c0 1.5-.2 2.7-.7 3.4-.5.8-1.3 1.2-2.3 1.2-.9 0-1.5-.4-2-1.1l-.1.9h-2.3V3.5h2.5v4.8c.5-.7 1-1 1.8-1 1.1 0 1.9.4 2.4 1.2.5.7.7 1.8.7 3.3v.8Zm-2.5-.7c0-1 0-1.6-.3-2-.1-.3-.5-.5-1-.5s-.9.2-1.1.7v4.3c.2.5.6.7 1.2.7.4 0 .8-.1 1-.5l.2-1.8V12ZM51.6 16.1c-.5.7-1.2 1-2 1-1 0-1.6-.2-2-.8-.5-.6-.7-1.5-.7-2.6V7.5h2.4v6.2c0 1 .4 1.4 1 1.4.5 0 1-.2 1.2-.7v-7H54V17h-2.3l-.1-.9ZM54.6 12c0-1.6.3-2.8.8-3.5.6-.8 1.4-1.2 2.4-1.2.8 0 1.5.4 2 1v-.8h2.3V17c0 1.2-.3 2.1-1 2.8-.7.6-1.7 1-3 1l-1.6-.4a3 3 0 0 1-1.3-.8l.9-1.7c.2.3.5.5.9.6.4.2.7.2 1 .2.6 0 1 0 1.3-.4.2-.2.3-.6.3-1.2v-.9c-.4.7-1 1-1.8 1-1 0-1.8-.4-2.4-1.2-.5-.8-.8-2-.8-3.3V12Zm2.5.6c0 .9 0 1.5.3 1.9.2.4.6.6 1.1.6.5 0 .9-.2 1.1-.6V10c-.2-.4-.6-.6-1-.6-.6 0-1 .2-1.2.6a4 4 0 0 0-.3 2v.6ZM62.7 12c0-1.6.3-2.8.9-3.5.5-.8 1.3-1.2 2.3-1.2.9 0 1.6.4 2 1l.1-.8h2.3V17c0 1.2-.4 2.1-1 2.8-.7.6-1.7 1-3 1-.5 0-1-.2-1.6-.4a3 3 0 0 1-1.3-.8l.8-1.7c.3.3.6.5 1 .6.3.2.7.2 1 .2.6 0 1 0 1.2-.4.3-.2.4-.6.4-1.2v-.9c-.5.7-1.1 1-1.9 1-1 0-1.8-.4-2.3-1.2-.6-.8-.9-2-.9-3.3V12Zm2.5.6c0 .9.1 1.5.4 1.9.2.4.6.6 1 .6.6 0 1-.2 1.2-.6V10c-.3-.4-.6-.6-1.1-.6-.5 0-.9.2-1.1.6a4 4 0 0 0-.4 2v.6ZM75.9 9.9H75c-.6 0-1 .2-1.3.8V17h-2.5V7.5h2.3v1c.5-.8 1-1.2 1.7-1.2l.7.1V10ZM80 17.2c-1.4 0-2.3-.4-3-1.2-.8-.7-1.1-1.8-1.1-3.2V12c0-1.5.3-2.6 1-3.5.6-.8 1.5-1.2 2.8-1.2 1.2 0 2 .4 2.7 1.2.6.7.9 1.9.9 3.4V13h-5c0 .7.2 1.2.5 1.5.3.3.7.5 1.3.5.8 0 1.5-.3 2-.8l1 1.5c-.3.4-.7.7-1.3 1-.6.2-1.2.4-1.9.4Zm-1.6-5.9h2.4v-.2c0-.6 0-1-.2-1.3-.2-.3-.5-.4-1-.4-.4 0-.7.1-.9.4-.2.4-.3.9-.3 1.5ZM83.5 12c0-1.6.3-2.8.8-3.5.6-.8 1.4-1.2 2.4-1.2.9 0 1.5.4 2 1l.1-.8H91V17c0 1.2-.3 2.1-1 2.8-.7.6-1.6 1-3 1l-1.6-.4a3 3 0 0 1-1.2-.8L85 18c.2.3.5.5 1 .6.3.2.6.2 1 .2.5 0 1 0 1.2-.4.2-.2.3-.6.4-1.2v-.9c-.5.7-1.1 1-1.9 1-1 0-1.8-.4-2.4-1.2-.5-.8-.8-2-.8-3.3V12Zm2.5.6c0 .9.1 1.5.3 1.9.3.4.6.6 1.1.6.5 0 1-.2 1.2-.6V10c-.3-.4-.7-.6-1.2-.6s-.8.2-1 .6a4 4 0 0 0-.4 2v.6ZM96.5 17l-.2-.7c-.5.6-1 .9-1.9.9-.8 0-1.4-.3-2-.8-.5-.5-.7-1.2-.7-2 0-1 .3-1.8 1-2.4.6-.5 1.5-.8 2.7-.8h.7v-.8c0-.4 0-.7-.2-.9-.1-.2-.3-.2-.6-.2-.6 0-1 .3-1 1H92c0-.8.3-1.6 1-2.1.6-.6 1.4-.9 2.4-.9s1.9.3 2.5.8c.5.6.8 1.3.8 2.4v4.4c0 .8.1 1.5.4 2v.1h-2.5ZM95 15.2l.7-.1.4-.4v-2h-.6c-.4 0-.7.1-1 .4-.2.3-.3.6-.3 1 0 .8.2 1.1.8 1.1ZM102.4 5.2v2.3h1.3v1.9h-1.3V14c0 .4 0 .6.2.8l.6.2.5-.1v2l-1.3.2c-1.6 0-2.5-1-2.5-2.8v-5h-1v-2h1V5.3h2.5Z"/>
<path
d="M103.6 12c0-1.5.3-2.6 1-3.5.7-.8 1.6-1.2 2.8-1.2 1.3 0 2.2.4 2.9 1.2.7.9 1 2 1 3.5v.6c0 1.4-.3 2.5-1 3.4-.7.8-1.6 1.2-2.8 1.2-1.3 0-2.2-.4-2.9-1.2-.7-.9-1-2-1-3.5V12Zm2.5.6c0 1.7.5 2.5 1.4 2.5.8 0 1.3-.7 1.3-2.1v-1a4 4 0 0 0-.3-2c-.3-.4-.6-.6-1-.6-.5 0-.8.2-1 .6a4 4 0 0 0-.4 2v.6ZM116.7 9.9h-.9c-.7 0-1.1.2-1.4.8V17H112V7.5h2.3v1c.5-.8 1-1.2 1.7-1.2l.7.1V10ZM7.1 23.1c-1.3-.3-2.3-1-3-1.8-.6-.9-1-2-1-3.4v-2.3c0-1.8-.8-2.7-2.4-2.7v-1.7c1.6 0 2.4-.9 2.4-2.7V6c0-1.3.4-2.4 1-3.3.7-.8 1.7-1.5 3-1.8l.5 1.3C6 2.8 5.2 4 5.2 6.2v2.3c0 1.7-.6 2.9-1.9 3.6 1.3.6 2 1.8 2 3.6V18c0 2 .7 3.3 2.3 3.8L7 23.1ZM25.3 21.8c1.5-.5 2.3-1.7 2.4-3.7v-2.5c0-1.7.6-3 2-3.5-1.4-.7-2-1.9-2-3.6V6.2c0-2.1-.8-3.4-2.4-4l.4-1.2c1.4.3 2.4 1 3 1.8.7.8 1 2 1 3.4v2.3c0 1.8.8 2.7 2.4 2.7V13c-1.6 0-2.4.9-2.4 2.7V18c0 1.4-.3 2.5-1 3.4-.7.8-1.7 1.5-3 1.8l-.4-1.3Z"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M11.4 7.6a4.7 4.7 0 0 1 9.4 0V8l1.6-1.7a.6.6 0 1 1 .8.7l-1.5 1.7c.5.5.7 1.1.7 1.8v1.4l-.1.8h2a.6.6 0 0 1 0 1.2h-2.2c-.2 1-.5 2-1 2.8l-.4 1-.1.1 2 2.1a.6.6 0 0 1-.8.8l-1.9-2a5.3 5.3 0 0 1-8-.2l-2.1 2a.6.6 0 1 1-.8-.8l2.2-2.2-.6-1.4c-.3-.7-.6-1.5-.7-2.2H7.6a.6.6 0 1 1 0-1.2h2v-2.1c-.1-.7.1-1.3.5-1.8L8.5 7a.6.6 0 0 1 .9-.8L11 8l.4-.2v-.2Zm7.7 0v.1h-6a3 3 0 0 1 6 0Zm.6 1.8h-7.5a1 1 0 0 0-1 1l.1 1.5c0 1.2.4 2.3.8 3.4l.6 1.3a3.6 3.6 0 0 0 6.5.2l.4-1c.7-1.2 1-2.6 1-4v-1.4c.1-.6-.3-1-.9-1Z"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M17.8 10.5a.6.6 0 0 1 .8.8L16.8 13l2 2a.6.6 0 1 1-.9.7l-1.9-2-2 2a.6.6 0 1 1-.7-.8l1.9-2-1.8-1.7a.6.6 0 0 1 .8-.8l1.8 1.8 1.8-1.8Z"/>
</svg>
<h2 class="mt-6 text-2xl text-gray-600 font-bold">Sign-in</h2>
</div>
<form @submit.prevent="submit" class="mt-8 space-y-6">
<div v-if="hasErrors" class="bg-gray-50 border p-5">
<div class="font-bold text-red-600">Whoops! Something went wrong.</div>

<ul class="mt-3 list-disc list-inside text-sm text-red-600">
<li v-for="(error, key) in errors" :key="key">{{ error }}</li>
</ul>
</div>

<div>
<label for="username" class="sr-only">Username</label>
<input id="username"
v-model="form.name"
type="text"
required
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 font-bold focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Username">
</div>
<div>
<label for="password" class="sr-only">Password</label>
<input id="password"
v-model="form.password"
type="password"
autocomplete="current-password"
required
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 font-bold focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Password">
</div>

<div class="flex items-center">
<button type="submit"
class="group relative flex justify-center py-2 px-4 border border-transparent text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Sign in
</button>

<div class="flex items-center ml-5">
<input id="remember-me" name="remember-me" v-model="form.remember" type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300">
<label for="remember-me" class="ml-2 block text-sm text-gray-600">Remember me</label>
</div>
</div>
</form>
</div>
</div>
</template>

<script>
import {computed, defineComponent} from 'vue'
import {usePage} from "@inertiajs/inertia-vue3";
export default defineComponent({
setup() {
const version = computed(() => usePage().props.value.version)
const name = computed(() => usePage().props.value.name)
return {version, name}
},
data() {
return {
form: this.$inertia.form({
name: '',
password: '',
remember: false
})
}
},
methods: {
submit() {
this.form
.transform(data => ({
...data,
remember: this.form.remember ? 'on' : ''
}))
.post(this.route('login'), {
onFinish: () => this.form.reset('password'),
})
}
},
computed: {
errors() {
return this.$page.props.errors
},
hasErrors() {
return Object.keys(this.errors).length > 0;
},
}
})
</script>
103 changes: 103 additions & 0 deletions tests/Feature/Http/EventsWithAuthControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

declare(strict_types=1);

namespace Tests\Feature\Http;

use App\Domain\ValueObjects\Uuid;
use Tests\DatabaseTestCase;

class EventsWithAuthControllerTest extends DatabaseTestCase
{
protected function setUp(): void
{
parent::setUp();

config()->set('auth.enabled', true);
}

public function testGetListOfEvents()
{
$this->getJson(route('events'), ['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()])
->assertUnauthorized();
}

public function testGetSpecificTypeListOfEventsForUnknownTypeEventShouldReturnNotFound()
{
$this->getJson(route('events.type', 'foo'),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertForbidden();
}

public function testGetSpecificTypeListOfEvents()
{
$event = $this->createEvent('test', []);
$this->getJson(
route('events.type', $event->getType()),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertForbidden();
}

public function testDeleteAllEvents()
{
$this->getJson(
route('events'),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertUnauthorized();
}

public function testDeleteSpecificTypeEvents()
{
$this->getJson(
route('events'),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertUnauthorized();
}

public function testDeleteEventByUuid()
{
$event = $this->createEvent('bar', ['foo1' => 'bar1']);
$this->deleteJson(route('event.delete', $event->getUuid()->toString()))
->assertUnauthorized();
}

public function testGetEventJsonByUuid()
{
$event = $this->createEvent('bar', ['foo1' => 'bar1']);
$this->getJson(route('event.show.json', $event->getUuid()->toString()))
->assertUnauthorized();
}

public function testGetEventJsonShouldReturn404IfNotFound()
{
$this->getJson(route('event.show.json', Uuid::generate()->toString()))
->assertUnauthorized();
}

public function testGetEventByUuid()
{
config()->set('server.foo.http.show', 'Foo/Show');
$event = $this->createEvent('foo', ['foo1' => 'bar1']);
$this->getJson(
route('event.show', [$event->getType(), $event->getUuid()->toString()]),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertUnauthorized();
}

public function testGetEventShouldReturn404IfNotFound()
{
config()->set('server.foo.http.show', 'Foo/Show');
$this->getJson(
route('event.show', ['foo', Uuid::generate()->toString()]),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertUnauthorized();
}

public function testGetEventShouldReturn404IfWrongType()
{
$this->getJson(
route('event.show', ['foo', Uuid::generate()->toString()]),
['X-Inertia' => true, 'X-Inertia-Version' => $this->inertiaVersion()]
)->assertUnauthorized();
}
}

0 comments on commit 9bb74bb

Please sign in to comment.