Added page authorisation and cug processing

This commit is contained in:
Deon George 2018-12-10 22:59:02 +11:00
parent 86e29a3cee
commit 4d65bb05a1
15 changed files with 792 additions and 107 deletions

View File

@ -2,8 +2,12 @@
namespace App\Classes;
use App\Models\Mode;
use Illuminate\Support\Facades\Log;
use App\User;
use App\Models\CUG;
/**
* Handles all aspects of frame
*
@ -100,12 +104,15 @@ abstract class Frame
/**
* Return a list of alternative versions of this frame.
*
* @todo: Need to adjust to not include access=0 frames unless owner
*/
public function alts()
public function alts(Mode $o)
{
return \App\Models\Frame::where('frame',$this->frame())
->where('index',$this->index())
->where('id','<>',$this->frame->id)
->where('mode_id',$o->id)
->limit(9);
}
@ -133,6 +140,34 @@ abstract class Frame
return $this->frame->frame;
}
/**
* Get the CUG for a frame
*
* Frame CUG are derived from their frame number.
* EG: Frame 642 is a member of 642, or 64, or 6, or 0, whichever matches first.
*
* @return CUG
*/
public function getCUG()
{
$co = NULL;
$frame = $this->frame->frame;
while (! $co)
{
$co = CUG::find($frame);
if (! $co) {
$frame = substr($frame,0,strlen($frame)-1);
if (! $frame)
$frame = 0;
}
}
return $co;
}
/**
* Return the current field configuration
*/
@ -197,6 +232,21 @@ abstract class Frame
return chr(ord($this->frame->index)+1);
}
public function isAccessible():bool
{
return $this->frame->access ? TRUE : FALSE;
}
/**
* Determine if the frame is a particular CUG
* @param int $cug
* @return bool
*/
public function isCUG(int $cug): bool
{
return ($this->getCUG()->id == $cug);
}
/**
* Determine if a field is editable
*
@ -208,6 +258,22 @@ abstract class Frame
return array_get(array_get($this->fieldoptions,$field),'edit',FALSE);
}
/**
* Is this frame Public
*
* @return bool
*/
public function isFramePublic(): bool
{
return $this->frame->closed ? FALSE : TRUE;
}
// @todo To implement
public function isOwner(User $o):bool
{
return FALSE;
}
/**
* Return the Page Number
*/
@ -312,6 +378,8 @@ abstract class Frame
$o->type = 'a';
$o->frame = 999;
$o->index = 'a';
$o->access = 1;
$o->closed = 0;
// Header
$sid = R_RED.'T'.R_BLUE.'E'.R_GREEN.'S'.R_YELLOW.'T';

View File

@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
use Sock\{SocketClient,SocketException};
use App\User;
use App\Classes\Frame as FrameClass;
use App\Models\Frame as FrameModel;
use App\Models\Mode;
@ -20,6 +21,50 @@ abstract class Server {
{
$this->mo = $o;
define('MODE_BL',1); // Typing a * command on the baseline
define('MODE_FIELD',2); // typing into an imput field
define('MODE_WARPTO',3); // awaiting selection of a timewarp
define('MODE_COMPLETE',4); // Entry of data is complete ..
define('MODE_SUBMITRF',5); // asking if should send or not.
define('MODE_RFSENT',6);
define('MODE_RFERROR',7);
define('MODE_RFNOTSENT',8);
define('ACTION_RELOAD',1);
define('ACTION_GOTO',2);
define('ACTION_BACKUP',3);
define('ACTION_NEXT',4);
define('ACTION_INFO',5);
define('ACTION_TERMINATE',6);
define('ACTION_SUBMITRF',7); // Offer to submit a response frame
define('ACTION_STAR',8);
define('FRAMETYPE_INFO','i');
define('FRAMETYPE_ACTION','a');
define('FRAMETYPE_LOGIN','l');
// Keyboard presses
define('KEY_LEFT',chr(136));
define('KEY_RIGHT',chr(137));
define('KEY_DOWN',chr(138));
define('KEY_UP',chr(139));
define('TCP_IAC',chr(255));
define('TCP_DONT',chr(254));
define('TCP_DO',chr(253));
define('TCP_WONT',chr(252));
define('TCP_WILL',chr(251));
define('TCP_SB',chr(250));
define('TCP_AYT',chr(246));
define('TCP_SE',chr(240));
define('TCP_BINARY',chr(0));
define('TCP_OPT_ECHO',chr(1));
define('TCP_OPT_SUP_GOAHEAD',chr(3));
define('TCP_OPT_TERMTYPE',chr(24));
define('TCP_OPT_WINDOWSIZE',chr(31));
define('TCP_OPT_LINEMODE',chr(34));
define('MSG_SENDORNOT', GREEN.'KEY 1 TO SEND, 2 NOT TO SEND');
define('MSG_SENT', GREEN.'MESSAGE SENT - KEY _ TO CONTINUE');
define('MSG_NOTSENT', GREEN.'MESSAGE NOT SENT - KEY _ TO CONTINUE');
@ -29,6 +74,7 @@ abstract class Server {
define('ERR_PRIVATE', WHITE.'PRIVATE PAGE'.GREEN.'- FOR EXPLANATION *37_..');
define('ERR_ROUTE', WHITE.'MISTAKE?'.GREEN.'TRY AGAIN OR TELL US ON *08');
define('ERR_PAGE',ERR_ROUTE);
define('ERR_USER_ALREADYMEMBER', RED.'ALREADY MEMBER OF CUG');
define('MSG_TIMEWARP_ON', WHITE.'TIMEWARP ON'.GREEN.'VIEW INFO WITH *02');
define('MSG_TIMEWARP_OFF', WHITE.'TIMEWARP OFF'.GREEN.'VIEWING DATE IS FIXED');
@ -82,6 +128,7 @@ abstract class Server {
$action = ACTION_GOTO; // Initial action.
$cmd = ''; // Current *command being typed in
$mode = FALSE; // Current mode.
$user = User::find(1); // The logged in user
$current = []; // Attributes about the current page
// field/fieldnum indexes are for fields on the active page
@ -199,6 +246,8 @@ abstract class Server {
$action = FALSE;
switch ($fo->type()) {
// Login frame.
case 'l':
// Response frame.
case 'a':
switch ($read) {
@ -213,11 +262,9 @@ abstract class Server {
if ($current['fieldnum'] !== FALSE) {
$current['field'] = $fo->getField($current['fieldnum']);
$fielddata[$current['fieldnum']] = '';
$client->send($this->outputPosition($current['field']->x,$current['field']->y).CON);
$mode = MODE_FIELD;
$fielddate[$current['fieldnum']] = '';
// There were no (more) editable fields.
} else {
@ -286,6 +333,9 @@ abstract class Server {
// Record Data Entry
default:
if (ord($read) > 31 && $current['fieldpos'] < $current['field']->length) {
if (! array_get($fielddata,$current['fieldnum']))
$fielddata[$current['fieldnum']] = '';
$fielddata[$current['fieldnum']]{$current['fieldpos']} = $read;
$current['fieldpos']++;
$client->send($read);
@ -309,7 +359,7 @@ abstract class Server {
switch ($read) {
// @todo Input received, process it.
case '1':
// dump(['line'=>__LINE__,'s' => $service, 'f' => $fielddata]);
// dump(['line'=>__LINE__,'f' => $fielddata]);
// @todo if send successful or not
if (TRUE) {
$this->sendBaseline($client,MSG_SENT);
@ -621,32 +671,53 @@ abstract class Server {
break;
}
// validate if we have access top it
/* if (isset($m['access']) && $m['access'] == 'n') {
$this->sendBaseline($client,ERR_PAGE);
$mode = $action = false;
break;
}
if (isset($m['cug']) && is_numeric($m['cug']) && $m['cug'] && !in_array($m['cug'],$usercugs)) {
$this->sendBaseline($client,ERR_PRIVATE);
$mode = $action = false;
break;
}
*/
// Is there a user logged in
if ($user)
{
if ($fo->isFramePublic() AND $fo->isAccessible())
{
if ($fo->type() == FRAMETYPE_LOGIN AND $user->isMemberCUG($fo->getCUG()))
{
$this->sendBaseline($client,ERR_USER_ALREADYMEMBER);
$mode = $action = FALSE;
// we have access...
//if ($r['varient_id'] != $varient['varient_id']) {
/* if ($timewarpalt) {
if (empty($v['varient_date'])) {
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO, 'unknown date'));
break;
}
// If this is a login frame and the user is already a member.
} else {
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO, date('j f Y', strtotime($v['varient_date']))));
if (! $fo->isOwner($user))
{
if (! $fo->isAccessible())
{
$this->sendBaseline($client,ERR_PAGE);
$mode = $action = FALSE;
break;
}
//$varient = array_merge($varient, array_intersect_key($r, $varient));
$msg = "TIMEWARP";
dump(['line'=>__LINE__,'write'=>'TIMEWARP MESSAGE']);
if (! $user->isMemberCUG($fo->getCUG()))
{
$this->sendBaseline($client, ERR_PRIVATE);
$mode = $action = FALSE;
break;
}
*/
}
}
} else {
// Is this a public frame in CUG 0?
if (! $fo->isCUG(0) OR ! $fo->isFramePublic())
{
$this->sendBaseline($client,ERR_PAGE);
$mode = $action = FALSE;
break;
}
}
$current['page'] = $fo->page(TRUE);
$current['fieldpos'] = 0;
@ -685,6 +756,8 @@ abstract class Server {
break;
// Login Frame.
case 'l':
// Active Frame. Prestel uses this for a Response Frame.
case 'a':
$client->send($output);

21
app/Models/CUG.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CUG extends Model
{
protected $table = 'cugs';
public function isMember(CUG $o)
{
while ($o)
{
if (! $this->parent_id OR $o->id == $this->parent_id)
return TRUE;
$o = $this::findOrFail($o->parent_id);
}
}
}

View File

@ -7,6 +7,11 @@ use Illuminate\Database\Eloquent\Model;
class Frame extends Model
{
public function cug()
{
return $this->belongsTo(CUG::class);
}
protected static function boot() {
parent::boot();

43
app/User.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Models\CUG;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
];
public function cugs()
{
return $this->belongsToMany(Models\CUG::class,'cug_users','user_id','cug_id');
}
public function isMemberCUG(CUG $o)
{
// @todo This doesnt include parent CUGs
return $this->cugs->contains($o);
}
}

View File

@ -9,6 +9,7 @@
"license": "MIT",
"require": {
"php": "^7.1.3",
"doctrine/dbal": "^2.9",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.7.*",
"laravel/tinker": "^1.0",
@ -39,9 +40,6 @@
"psr-4": {
"App\\": "app/"
},
"files": [
"config/constants.php"
],
"classmap": [
"database/seeds",
"database/factories"

235
composer.lock generated
View File

@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "2bcfe8e78cb84d91841e72dec65770f9",
"content-hash": "ff208b67c5f938a92c08bec4d362e0b4",
"packages": [
{
"name": "dnoegel/php-xdg-base-dir",
@ -39,6 +39,237 @@
"description": "implementation of xdg base directory specification for php",
"time": "2014-10-24T07:27:01+00:00"
},
{
"name": "doctrine/cache",
"version": "v1.8.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57",
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57",
"shasum": ""
},
"require": {
"php": "~7.1"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"doctrine/coding-standard": "^4.0",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^7.0",
"predis/predis": "~1.0"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2018-08-21T18:01:43+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.9.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "21fdabe2fc01e004e1966f200d900554876bc63c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/21fdabe2fc01e004e1966f200d900554876bc63c",
"reference": "21fdabe2fc01e004e1966f200d900554876bc63c",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.0",
"doctrine/event-manager": "^1.0",
"ext-pdo": "*",
"php": "^7.1"
},
"require-dev": {
"doctrine/coding-standard": "^5.0",
"jetbrains/phpstorm-stubs": "^2018.1.2",
"phpstan/phpstan": "^0.10.1",
"phpunit/phpunit": "^7.4",
"symfony/console": "^2.0.5|^3.0|^4.0",
"symfony/phpunit-bridge": "^3.4.5|^4.0.5"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.9.x-dev",
"dev-develop": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
"keywords": [
"abstraction",
"database",
"dbal",
"mysql",
"persistence",
"pgsql",
"php",
"queryobject"
],
"time": "2018-12-04T04:39:48+00:00"
},
{
"name": "doctrine/event-manager",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/event-manager.git",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"conflict": {
"doctrine/common": "<2.9@dev"
},
"require-dev": {
"doctrine/coding-standard": "^4.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "lib/Doctrine/Common"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com"
}
],
"description": "Doctrine Event Manager component",
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
"event",
"eventdispatcher",
"eventmanager"
],
"time": "2018-06-11T11:59:03+00:00"
},
{
"name": "doctrine/inflector",
"version": "v1.3.0",

View File

@ -1,41 +0,0 @@
<?php
define('MODE_BL',1); // Typing a * command on the baseline
define('MODE_FIELD',2); // typing into an imput field
define('MODE_WARPTO',3); // awaiting selection of a timewarp
define('MODE_COMPLETE',4); // Entry of data is complete ..
define('MODE_SUBMITRF',5); // asking if should send or not.
define('MODE_RFSENT',6);
define('MODE_RFERROR',7);
define('MODE_RFNOTSENT',8);
define('ACTION_RELOAD',1);
define('ACTION_GOTO',2);
define('ACTION_BACKUP',3);
define('ACTION_NEXT',4);
define('ACTION_INFO',5);
define('ACTION_TERMINATE',6);
define('ACTION_SUBMITRF',7); // Offer to submit a response frame
define('ACTION_STAR',8);
// Keyboard presses
define('KEY_LEFT',chr(136));
define('KEY_RIGHT',chr(137));
define('KEY_DOWN',chr(138));
define('KEY_UP',chr(139));
define('TCP_IAC',chr(255));
define('TCP_DONT',chr(254));
define('TCP_DO',chr(253));
define('TCP_WONT',chr(252));
define('TCP_WILL',chr(251));
define('TCP_SB',chr(250));
define('TCP_AYT',chr(246));
define('TCP_SE',chr(240));
define('TCP_BINARY',chr(0));
define('TCP_OPT_ECHO',chr(1));
define('TCP_OPT_SUP_GOAHEAD',chr(3));
define('TCP_OPT_TERMTYPE',chr(24));
define('TCP_OPT_WINDOWSIZE',chr(31));
define('TCP_OPT_LINEMODE',chr(34));

92
config/logging.php Normal file
View File

@ -0,0 +1,92 @@
<?php
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];

View File

@ -0,0 +1,44 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFramemeta extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->down();
Schema::create('framemeta', function (Blueprint $table) {
$table->integer('frame_id')->primary();
$table->string('r0');
$table->string('r1');
$table->string('r2');
$table->string('r3');
$table->string('r4');
$table->string('r5');
$table->string('r6');
$table->string('r7');
$table->string('r8');
$table->string('r9');
$table->foreign('frame_id')->references('id')->on('frames');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('framemeta');
}
}

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUser extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->down();
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('login',8)->unique();
$table->string('password');
$table->string('name');
$table->string('email')->unique();
$table->string('location');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserCug extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->down();
Schema::create('cug_users', function (Blueprint $table) {
$table->integer('cug_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('cug_id')->references('id')->on('cugs');
$table->unique(['user_id','cug_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cug_users');
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCugOwners extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->down();
Schema::create('cug_owners', function (Blueprint $table) {
$table->integer('cug_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('cug_id')->references('id')->on('cugs');
$table->unique(['user_id','cug_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cug_owners');
}
}

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class FrameAddAccess extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('frames', function (Blueprint $table) {
$table->renameColumn('public','closed');
$table->boolean('access')->default(FALSE);
$table->dropForeign(['cug_id']);
$table->dropColumn('cug_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('frames', function (Blueprint $table) {
$table->dropColumn('access');
$table->renameColumn('closed','public');
$table->integer('cug_id')->default(0);
$table->foreign('cug_id')->references('id')->on('cugs');
});
}
}