Compare commits

...

12 Commits
master ... test

Author SHA1 Message Date
Deon George 62195fb2d2
Missing domain.view 2021-06-16 09:21:16 +10:00
Deon George 22657fee91
Send errors to stderr 2021-06-16 09:09:45 +10:00
Deon George 78a2a24c68
Network 1 doesnt exist yet 2021-06-16 09:07:25 +10:00
Deon George 4bafde1b1b
Admin can be null on users 2021-06-16 09:05:33 +10:00
Deon George 8d14e74870
We are creating not modified 2021-06-16 09:03:58 +10:00
Deon George c2b6cbf741
Fix spelling of domain table 2021-06-16 09:00:09 +10:00
Deon George c47eaf74c8
Add artisan migrate to test script 2021-06-16 08:57:30 +10:00
Deon George 2dd55fdb95 Change image to ext for testing 2021-06-15 23:25:24 +10:00
Deon George 753794f412 Fix POSTGRES password enviroment 2021-06-15 22:26:37 +10:00
Deon George cc63e8183d Added .env, define POSTGRES password 2021-06-15 22:24:58 +10:00
Deon George 4fd4becd82 Create CI testing 2021-06-15 22:19:14 +10:00
Deon George 574088c35e Notes for DBridge - needs work still 2021-06-15 22:15:51 +10:00
15 changed files with 374 additions and 53 deletions

41
.env.testing Normal file
View File

@ -0,0 +1,41 @@
APP_NAME="Clearing Houz"
APP_ENV=testing
APP_KEY=
APP_DEBUG=true
#APP_URL=http://localhost
LOG_CHANNEL=stderr
LOG_LEVEL=info
DB_CONNECTION=pgsql
DB_HOST=database
DB_PORT=5432
DB_DATABASE=postgres
DB_USERNAME=postgres
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=mail.leenooks.vpn
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_AUTO_EMBED_METHOD=base64
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

View File

@ -10,4 +10,5 @@ cache:
- vendor/
include:
- .gitlab-test.yml
- .gitlab-docker-x86_64.yml

40
.gitlab-test.yml Normal file
View File

@ -0,0 +1,40 @@
test:
image: ${CI_REGISTRY}/leenooks/php:8.0-fpm-ext-test
stage: test
# NOTE: This service is dependant on project file configuration, which is not there if the cache was deleted
# resulting in the testing to fail on the first run.
services:
- name: postgres:13-alpine
alias: database
variables:
POSTGRES_PASSWORD: secret
tags:
- php
only:
- test
before_script:
- mv .env.testing .env
# Install Composer and project dependencies.
- mkdir -p /root/.composer
- if [ -n "$GITHUB_TOKEN" ]; then cat $GITHUB_TOKEN |base64 -d > /root/.composer/auth.json ; fi
- composer install
# Generate an application key. Re-cache.
- php artisan key:generate
- php artisan migrate
script:
# run laravel tests
- XDEBUG_MODE=coverage php vendor/bin/phpunit --coverage-text --colors=never
# run frontend tests
# if you have any task for testing frontend
# set it in your package.json script
# comment this out if you don't have a frontend test
# npm test

View File

@ -253,6 +253,8 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
private function emsi_parsedat(string $str): int
{
Log::debug(sprintf('%s: + Start',__METHOD__));
if ($this->DEBUG)
Log::debug(sprintf('%s: - Parsing [%s]',__METHOD__,$str));
$l = 0;
@ -733,17 +735,21 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
$ch &= 0x7f;
/*
* @todo D'Bridge doesnt respond to an EMSI_DAT with EMSI_ACK's suffixed with <CR>
*/
if (($ch == ord(self::CR)) || ($ch == ord(self::NL))) {
if (! $p)
continue;
if (! strncmp($p,self::EMSI_DAT,10)) {
Log::warning(sprintf('%s: - Got unexpected EMSI_DAT - Argus?',__METHOD__));
$this->client->buffer_add(self::EMSI_ACK);
$this->client->buffer_add(self::EMSI_ACK);
$this->client->buffer_flush(1);
Log::warning(sprintf('%s: - Got unexpected EMSI_DAT - Argus/D\'Bridge?',__METHOD__));
$t2 = $this->client->timer_set($this->client->timer_rest($t2) >> 2);
/*
* D'Bridge sends EMSI_DAT immediately after EMSI_INQ, so we'll need to exit here to catch it.
* @todo The interaction with DBridge could be improved, because there are many re-transmits before we correctly handshake.
*/
return self::OK;
} else if (! strncmp($p,self::EMSI_REQ,self::EMSI_SEQ_LEN)) {
Log::notice(sprintf('%s: - Got EMSI_REQ - skipping...',__METHOD__));
@ -857,13 +863,16 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
if (($ch == ord(self::CR)) || ($ch == ord(self::NL))) {
if (strstr($p,self::EMSI_REQ)) {
Log::info(sprintf('%s: - Got EMSI_REQ',__METHOD__));
if ($gotreq++)
return self::OK;
Log::info(sprintf('%s: - Got EMSI_REQ (Send INQ then DAT) [%d]',__METHOD__,$gotreq));
$this->client->buffer_add(self::EMSI_INQ);
$this->client->buffer_flush(5);
/*
* For Dbridge, we need to exit here and immediately send our EMSI_DAT.
*/
return self::OK;
} elseif ($p && strstr($p,self::EMSI_BEG) && strstr($p,self::EMSI_ARGUS1)) {
Log::info(sprintf('%s: - Got Intro [%s]',__METHOD__,$p));
}
@ -918,7 +927,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
$got = 0;
if (strstr($p, self::EMSI_INQ)) {
Log::info(sprintf('%s: - Got EMSI_REQ',__METHOD__));
Log::info(sprintf('%s: - Got EMSI_REQ (Returning)',__METHOD__));
return self::OK;
}

View File

@ -11,4 +11,14 @@ class HomeController extends Controller
return view('domain.view')
->with('o',$o);
}
/**
* System Setup
*
* @note: Protected by Route
*/
public function setup()
{
}
}

View File

@ -2,13 +2,14 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Traits\ScopeActive;
class Domain extends Model
{
use ScopeActive;
use HasFactory,ScopeActive;
/* SCOPES */

View File

@ -5,26 +5,30 @@ namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Models\User;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
Gate::define('admin',function (User $o) {
return $o->admin == TRUE;
});
}
}

View File

@ -37,7 +37,9 @@
"app/helpers.php"
],
"psr-4": {
"App\\": "app/"
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {

View File

@ -0,0 +1,52 @@
<?php
namespace Database\Factories;
use App\Models\Domain;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class DomainFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Domain::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'dnsdomain' => $this->faker->unique()->safeEmail(),
'notes' => $this->faker->text(),
'homepage' => $this->faker->text(),
'active' => FALSE,
'public' => FALSE,
];
}
public function active()
{
return $this->state(function (array $attributes) {
return [
'active' => TRUE,
];
});
}
public function public()
{
return $this->state(function (array $attributes) {
return [
'public' => TRUE,
];
});
}
}

View File

@ -1,24 +1,42 @@
<?php
use Faker\Generator as Faker;
namespace Database\Factories;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
public function admin()
{
return $this->state(function (array $attributes) {
return [
'admin' => true,
];
});
}
}

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAdminToUsers extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('admin')->nullable();
});
Schema::create('domain_user', function (Blueprint $table) {
$table->integer('domain_id');
$table->foreign('domain_id')->references('id')->on('domains');
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('admin');
});
Schema::dropIfExists('domain_user');
}
}

View File

@ -0,0 +1,9 @@
@extends('layouts.app')
@section('htmlheader_title')
{{ $o->name }}
@endsection
@section('content')
<h1>{{ $o->name }} <small class="push-right">Last Update: {{ $o->updated_at }}</small></h1>
<p>{!! \Illuminate\Mail\Markdown::parse($o->homepage) !!}</p>
@endsection

View File

@ -42,8 +42,10 @@ Route::middleware(['verified'])->group(function () {
Route::get('ftn/zone',[ZoneController::class,'home']);
Route::match(['get','post'],'ftn/zone/addedit/{o?}',[ZoneController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/network/{name}',[HomeController::class,'network']);
});
Route::get('network/{o}',[HomeController::class,'network']);
Route::get('network/{o}',[HomeController::class,'network']);
Route::middleware(['auth','can:admin'])->group(function () {
Route::get('setup',[HomeController::class,'setup']);
});

View File

@ -14,7 +14,7 @@ class ExampleTest extends TestCase
*/
public function testBasicTest()
{
$response = $this->get('/');
$response = $this->get('/about');
$response->assertStatus(200);
}

View File

@ -0,0 +1,90 @@
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Auth;
use Tests\TestCase;
use App\Models\User;
use App\Models\Domain;
class SiteAdminTest extends TestCase
{
use DatabaseTransactions;
/**
* Testing a unauthenticated visitor to the site.
*/
public function test_guestuser()
{
$this->get('about')
->assertOk();
$this->get('ftn/domain')
->assertRedirect('login');
$this->get('ftn/node')
->assertRedirect('login');
$this->get('ftn/zone')
->assertRedirect('login');
$this->get('network/1')
->assertNotFound();
Domain::factory()->create([
'id'=>1,
'name'=>'test',
]);
$this->get('network/1')
->assertOK();
}
/**
* Verify user who has registered by not verified their email
*/
public function test_unverified_user()
{
$user = User::factory()->make([
'name'=>'Site Visitor',
'email_verified_at'=>NULL,
]);
// Use model in tests...
$this->actingAs($user);
$this->get('ftn/domain')
->assertRedirect('email/verify');
$this->get('ftn/node')
->assertRedirect('email/verify');
$this->get('ftn/zone')
->assertRedirect('email/verify');
Auth::logout();
}
public function test_site_admin()
{
// Site Visitor
$this->get('setup')
->assertRedirect('login');
// Valid User
$user = User::factory()->make([
'name'=>'Site User',
]);
$this->actingAs($user);
$this->get('setup')
->assertForbidden();
// Admin User
$user = User::factory()->admin()->make([
'name'=>'Site User',
]);
$this->actingAs($user);
$this->get('setup')
->assertOK();
}
}