Added page authorisation and cug processing
This commit is contained in:
@@ -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';
|
||||
|
@@ -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
21
app/Models/CUG.php
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
43
app/User.php
Normal 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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user