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,13 +262,11 @@ 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.
// There were no (more) editable fields.
} else {
$action = ACTION_SUBMITRF;
}
@@ -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'));
} else {
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO, date('j f Y', strtotime($v['varient_date']))));
break;
}
// If this is a login frame and the user is already a member.
} else {
if (! $fo->isOwner($user))
{
if (! $fo->isAccessible())
{
$this->sendBaseline($client,ERR_PAGE);
$mode = $action = FALSE;
break;
}
if (! $user->isMemberCUG($fo->getCUG()))
{
$this->sendBaseline($client, ERR_PRIVATE);
$mode = $action = FALSE;
break;
}
}
//$varient = array_merge($varient, array_intersect_key($r, $varient));
$msg = "TIMEWARP";
dump(['line'=>__LINE__,'write'=>'TIMEWARP MESSAGE']);
}
*/
} 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;
@@ -678,13 +749,15 @@ abstract class Server {
switch ($fo->type()) {
default:
// Standard Frame
// Standard Frame
case 'i':
$client->send($output);
$mode = $action = false;
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);
}
}