- #84 CREST Login (WIP)
- New CREST controller - Database restructuring - improved type-casting for some controller functions - New login process - Fixed some bugs during the setup process (/setup root) - Added CREST request caching by response headers
This commit is contained in:
@@ -2,16 +2,16 @@
|
||||
|
||||
[ENVIRONMENT]
|
||||
; project environment (DEVELOP, PRODUCTION).
|
||||
; This effects: DB connection, Mail-Server connection
|
||||
; This effects: DB connection, Mail-Server, SSO, CREST configurations in this file
|
||||
; configuration below
|
||||
SERVER = DEVELOP
|
||||
|
||||
[ENVIRONMENT.DEVELOP]
|
||||
; base dir (Default: "auto-detect"
|
||||
; base dir (Default: "auto-detect")
|
||||
BASE =
|
||||
; deployment URL e.g. http://localhost
|
||||
; deployment URL (e.g. http://localhost)
|
||||
URL = http://pathfinder.local
|
||||
; Verbosity level of the stack trace
|
||||
; level of debug/error stack trace
|
||||
DEBUG = 3
|
||||
; main db
|
||||
DB_DNS = mysql:host=localhost;port=3306;dbname=
|
||||
@@ -25,11 +25,13 @@ DB_CCP_NAME = eve_parallax_min
|
||||
DB_CCP_USER = root
|
||||
DB_CCP_PASS =
|
||||
|
||||
; CCP SSO settings
|
||||
; CCP SSO settings (OAuth2) - visit: https://developers.eveonline.com/applications
|
||||
CCP_CREST_URL = https://api-sisi.testeveonline.com
|
||||
SSO_CCP_URL = https://sisilogin.testeveonline.com
|
||||
SSO_CCP_CLIENT_ID =
|
||||
SSO_CCP_SECRET_KEY =
|
||||
|
||||
; SMTP settings. see: https://developers.eveonline.com/applications
|
||||
; SMTP settings (optional)
|
||||
SMTP_HOST = localhost
|
||||
SMTP_PORT = 25
|
||||
SMTP_SCHEME = ""
|
||||
@@ -40,10 +42,11 @@ SMTP_FROM = pathfinder@localhost.com
|
||||
SMTP_ERROR = pathfinder@localhost.com
|
||||
|
||||
[ENVIRONMENT.PRODUCTION]
|
||||
; base dir (Default: "auto-detect"
|
||||
BASE = /www/htdocs/www.pathfinder-w.space
|
||||
; deployment URL
|
||||
; deployment URL (e.g. https://www.pathfinder-w.space)
|
||||
URL = https://www.pathfinder-w.space
|
||||
; Verbosity level of the stack trace
|
||||
; level of debug/error stack trace
|
||||
DEBUG = 0
|
||||
; main db
|
||||
DB_DNS = mysql:host=localhost;port=3306;dbname=
|
||||
@@ -58,10 +61,12 @@ DB_CCP_USER =
|
||||
DB_CCP_PASS =
|
||||
|
||||
; CCP SSO settings
|
||||
CCP_CREST_URL = https://crest-tq.eveonline.com
|
||||
SSO_CCP_URL = https://login.eveonline.com
|
||||
SSO_CCP_CLIENT_ID =
|
||||
SSO_CCP_SECRET_KEY =
|
||||
|
||||
; SMTP settings
|
||||
; SMTP settings (optional)
|
||||
SMTP_HOST = localhost
|
||||
SMTP_PORT = 25
|
||||
SMTP_SCHEME = TLS
|
||||
|
||||
@@ -7,20 +7,21 @@
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
use Controller\Api as Api;
|
||||
use Model;
|
||||
|
||||
class AccessController extends Controller {
|
||||
|
||||
/**
|
||||
* event handler
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
function beforeroute(\Base $f3) {
|
||||
parent::beforeroute($f3);
|
||||
|
||||
// Any CMS route of a child class of this one, requires a
|
||||
// valid logged in user!
|
||||
$loginCheck = $this->_checkLogIn();
|
||||
$loginCheck = $this->checkLogIn($f3);
|
||||
|
||||
if( !$loginCheck ){
|
||||
// no user found or LogIn timer expired
|
||||
@@ -30,16 +31,16 @@ class AccessController extends Controller {
|
||||
|
||||
/**
|
||||
* checks weather a user is currently logged in
|
||||
* @param \Base $f3
|
||||
* @return bool
|
||||
*/
|
||||
private function _checkLogIn(){
|
||||
|
||||
private function checkLogIn($f3){
|
||||
$loginCheck = false;
|
||||
|
||||
if($this->f3->get('SESSION.user.time') > 0){
|
||||
if($f3->get(Api\User::SESSION_KEY_CHARACTER_TIME) > 0){
|
||||
// check logIn time
|
||||
$logInTime = new \DateTime();
|
||||
$logInTime->setTimestamp($this->f3->get('SESSION.user.time'));
|
||||
$logInTime->setTimestamp( $f3->get(Api\User::SESSION_KEY_CHARACTER_TIME) );
|
||||
$now = new \DateTime();
|
||||
|
||||
$timeDiff = $now->diff($logInTime);
|
||||
@@ -48,7 +49,7 @@ class AccessController extends Controller {
|
||||
$minutes += $timeDiff->h * 60;
|
||||
$minutes += $timeDiff->i;
|
||||
|
||||
if($minutes <= $this->f3->get('PATHFINDER.TIMER.LOGGED')){
|
||||
if($minutes <= $f3->get('PATHFINDER.TIMER.LOGGED')){
|
||||
$loginCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,27 +7,26 @@
|
||||
*/
|
||||
|
||||
namespace Controller\Api;
|
||||
use Controller;
|
||||
use Model;
|
||||
|
||||
class Connection extends \Controller\AccessController{
|
||||
class Connection extends Controller\AccessController{
|
||||
|
||||
/**
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
|
||||
parent::beforeroute($f3);
|
||||
|
||||
function beforeroute(\Base $f3) {
|
||||
// set header for all routes
|
||||
header('Content-type: application/json');
|
||||
parent::beforeroute($f3);
|
||||
}
|
||||
|
||||
/**
|
||||
* save a new connection or updates an existing (drag/drop) between two systems
|
||||
* if a connection is changed (drag&drop) to another system. -> this function is called for update
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function save($f3){
|
||||
public function save(\Base $f3){
|
||||
$postData = (array)$f3->get('POST');
|
||||
$newConnectionData = [];
|
||||
|
||||
@@ -38,10 +37,15 @@ class Connection extends \Controller\AccessController{
|
||||
$mapData = (array)$postData['mapData'];
|
||||
$connectionData = (array)$postData['connectionData'];
|
||||
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
if($user){
|
||||
// get map model and check map access
|
||||
/**
|
||||
* @var Model\MapModel $map
|
||||
*/
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
$map->getById( (int)$mapData['id'] );
|
||||
|
||||
@@ -90,16 +94,22 @@ class Connection extends \Controller\AccessController{
|
||||
echo json_encode($newConnectionData);
|
||||
}
|
||||
|
||||
public function delete($f3){
|
||||
/**
|
||||
* delete connection
|
||||
* @param \Base $f3
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(\Base $f3){
|
||||
$connectionIds = $f3->get('POST.connectionIds');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
/**
|
||||
* @var Model\ConnectionModel $connection
|
||||
*/
|
||||
$connection = Model\BasicModel::getNew('ConnectionModel');
|
||||
|
||||
foreach($connectionIds as $connectionId){
|
||||
|
||||
$connection->getById($connectionId);
|
||||
$connection->delete($user);
|
||||
$connection->delete( $activeCharacter->getUser() );
|
||||
|
||||
$connection->reset();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
namespace Controller\Api;
|
||||
use Controller;
|
||||
use Model;
|
||||
|
||||
/**
|
||||
@@ -14,25 +15,23 @@ use Model;
|
||||
* Class Map
|
||||
* @package Controller\Api
|
||||
*/
|
||||
class Map extends \Controller\AccessController {
|
||||
class Map extends Controller\AccessController {
|
||||
|
||||
/**
|
||||
* event handler
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
|
||||
function beforeroute(\Base $f3) {
|
||||
// set header for all routes
|
||||
header('Content-type: application/json');
|
||||
|
||||
parent::beforeroute($f3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all required static config data for program initialization
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function init($f3){
|
||||
public function init(\Base $f3){
|
||||
|
||||
// expire time in seconds
|
||||
$expireTimeHead = 60 * 60 * 12;
|
||||
@@ -143,9 +142,9 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* import new map data
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function import($f3){
|
||||
public function import(\Base $f3){
|
||||
$importData = (array)$f3->get('POST');
|
||||
|
||||
$return = (object) [];
|
||||
@@ -155,13 +154,24 @@ class Map extends \Controller\AccessController {
|
||||
isset($importData['typeId']) &&
|
||||
count($importData['mapData']) > 0
|
||||
){
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($user){
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
/**
|
||||
* @var $map Model\MapModel
|
||||
*/
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
|
||||
/**
|
||||
* @var $system Model\SystemModel
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
|
||||
/**
|
||||
* @var $connection Model\ConnectionModel
|
||||
*/
|
||||
$connection = Model\BasicModel::getNew('ConnectionModel');
|
||||
|
||||
foreach($importData['mapData'] as $mapData){
|
||||
@@ -194,8 +204,8 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
$system->setData($systemData);
|
||||
$system->mapId = $map;
|
||||
$system->createdCharacterId = $activeCharacter->characterId;
|
||||
$system->updatedCharacterId = $activeCharacter->characterId;
|
||||
$system->createdCharacterId = $activeCharacter;
|
||||
$system->updatedCharacterId = $activeCharacter;
|
||||
$system->save();
|
||||
|
||||
$tempSystemIdMapping[$oldId] = $system->id;
|
||||
@@ -228,13 +238,11 @@ class Map extends \Controller\AccessController {
|
||||
if($map->isPrivate()){
|
||||
$map->setAccess($user);
|
||||
}elseif($map->isCorporation()){
|
||||
$corporation = $activeCharacter->getCharacter()->getCorporation();
|
||||
if($corporation){
|
||||
if($corporation = $activeCharacter->getCorporation()){
|
||||
$map->setAccess($corporation);
|
||||
}
|
||||
}elseif($map->isAlliance()){
|
||||
$alliance = $activeCharacter->getCharacter()->getAlliance();
|
||||
if($alliance){
|
||||
if($alliance = $activeCharacter->getAlliance()){
|
||||
$map->setAccess($alliance);
|
||||
}
|
||||
}
|
||||
@@ -260,7 +268,7 @@ class Map extends \Controller\AccessController {
|
||||
}
|
||||
}else{
|
||||
// user not found
|
||||
$return->error[] = $this->getUserLoggedOffError();
|
||||
$return->error[] = $this->getLogoutError();
|
||||
}
|
||||
}else{
|
||||
// map data missing
|
||||
@@ -276,19 +284,23 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* save a new map or update an existing map
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function save($f3){
|
||||
public function save(\Base $f3){
|
||||
$formData = (array)$f3->get('POST.formData');
|
||||
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
if( isset($formData['id']) ){
|
||||
$activeCharacter = $this->getCharacter(0);
|
||||
|
||||
$user = $this->_getUser(0);
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
if($user){
|
||||
/**
|
||||
* @var $map Model\MapModel
|
||||
*/
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
$map->getById( (int)$formData['id'] );
|
||||
|
||||
@@ -311,6 +323,9 @@ class Map extends \Controller\AccessController {
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
/**
|
||||
* @var $tempUser Model\UserModel
|
||||
*/
|
||||
$tempUser = Model\BasicModel::getNew('UserModel');
|
||||
|
||||
foreach($accessUsers as $userId){
|
||||
@@ -331,90 +346,86 @@ class Map extends \Controller\AccessController {
|
||||
// just in case he removed himself :)
|
||||
$map->setAccess($user);
|
||||
}elseif($map->isCorporation()){
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
$corporation = $activeCharacter->getCorporation();
|
||||
|
||||
if($activeCharacter){
|
||||
$corporation = $activeCharacter->getCharacter()->getCorporation();
|
||||
if($corporation){
|
||||
// the current user has to have a corporation when
|
||||
// working on corporation maps!
|
||||
|
||||
if($corporation){
|
||||
// the current user has to have a corporation when
|
||||
// working on corporation maps!
|
||||
// share map between corporations -> set access
|
||||
if(isset($formData['mapCorporations'])){
|
||||
// avoid abuse -> respect share limits
|
||||
$accessCorporations = array_slice( $formData['mapCorporations'], 0, $f3->get('PATHFINDER.MAX_SHARED_CORPORATION') );
|
||||
|
||||
// share map between corporations -> set access
|
||||
if(isset($formData['mapCorporations'])){
|
||||
// avoid abuse -> respect share limits
|
||||
$accessCorporations = array_slice( $formData['mapCorporations'], 0, $f3->get('PATHFINDER.MAX_SHARED_CORPORATION') );
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
/**
|
||||
* @var $tempCorporation Model\CorporationModel
|
||||
*/
|
||||
$tempCorporation = Model\BasicModel::getNew('CorporationModel');
|
||||
|
||||
$tempCorporation = Model\BasicModel::getNew('CorporationModel');
|
||||
foreach($accessCorporations as $corporationId){
|
||||
$tempCorporation->getById( (int)$corporationId );
|
||||
|
||||
foreach($accessCorporations as $corporationId){
|
||||
$tempCorporation->getById( (int)$corporationId );
|
||||
|
||||
if(
|
||||
!$tempCorporation->dry() &&
|
||||
$tempCorporation->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempCorporation);
|
||||
}
|
||||
|
||||
$tempCorporation->reset();
|
||||
if(
|
||||
!$tempCorporation->dry() &&
|
||||
$tempCorporation->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempCorporation);
|
||||
}
|
||||
}
|
||||
|
||||
// the corporation of the current user should always have access
|
||||
$map->setAccess($corporation);
|
||||
$tempCorporation->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// the corporation of the current user should always have access
|
||||
$map->setAccess($corporation);
|
||||
}
|
||||
}elseif($map->isAlliance()){
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
$alliance = $activeCharacter->getAlliance();
|
||||
|
||||
if($activeCharacter){
|
||||
$alliance = $activeCharacter->getCharacter()->getAlliance();
|
||||
if($alliance){
|
||||
// the current user has to have a alliance when
|
||||
// working on alliance maps!
|
||||
|
||||
if($alliance){
|
||||
// the current user has to have a alliance when
|
||||
// working on alliance maps!
|
||||
// share map between alliances -> set access
|
||||
if(isset($formData['mapAlliances'])){
|
||||
// avoid abuse -> respect share limits
|
||||
$accessAlliances = array_slice( $formData['mapAlliances'], 0, $f3->get('PATHFINDER.MAX_SHARED_ALLIANCE') );
|
||||
|
||||
// share map between alliances -> set access
|
||||
if(isset($formData['mapAlliances'])){
|
||||
// avoid abuse -> respect share limits
|
||||
$accessAlliances = array_slice( $formData['mapAlliances'], 0, $f3->get('PATHFINDER.MAX_SHARED_ALLIANCE') );
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
/**
|
||||
* @var $tempAlliance Model\AllianceModel
|
||||
*/
|
||||
$tempAlliance = Model\BasicModel::getNew('AllianceModel');
|
||||
|
||||
$tempAlliance = Model\BasicModel::getNew('AllianceModel');
|
||||
foreach($accessAlliances as $allianceId){
|
||||
$tempAlliance->getById( (int)$allianceId );
|
||||
|
||||
foreach($accessAlliances as $allianceId){
|
||||
$tempAlliance->getById( (int)$allianceId );
|
||||
|
||||
if(
|
||||
!$tempAlliance->dry() &&
|
||||
$tempAlliance->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempAlliance);
|
||||
}
|
||||
|
||||
$tempAlliance->reset();
|
||||
if(
|
||||
!$tempAlliance->dry() &&
|
||||
$tempAlliance->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempAlliance);
|
||||
}
|
||||
|
||||
$tempAlliance->reset();
|
||||
}
|
||||
|
||||
// the alliance of the current user should always have access
|
||||
$map->setAccess($alliance);
|
||||
}
|
||||
|
||||
// the alliance of the current user should always have access
|
||||
$map->setAccess($alliance);
|
||||
}
|
||||
}
|
||||
// reload the same map model (refresh)
|
||||
// this makes sure all data is up2date
|
||||
$map->getById( $map->id, 0 );
|
||||
|
||||
|
||||
$return->mapData = $map->getData();
|
||||
|
||||
}else{
|
||||
// map access denied
|
||||
$captchaError = (object) [];
|
||||
@@ -423,7 +434,6 @@ class Map extends \Controller\AccessController {
|
||||
$return->error[] = $captchaError;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
// map id field missing
|
||||
$idError = (object) [];
|
||||
@@ -437,17 +447,19 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* delete a map and all dependencies
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function delete($f3){
|
||||
public function delete(\Base $f3){
|
||||
$mapData = (array)$f3->get('POST.mapData');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
|
||||
if($user){
|
||||
if($activeCharacter){
|
||||
/**
|
||||
* @var $map Model\MapModel
|
||||
*/
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
$map->getById($mapData['id']);
|
||||
$map->delete($user);
|
||||
$map->delete( $activeCharacter->getUser() );
|
||||
}
|
||||
|
||||
echo json_encode([]);
|
||||
@@ -455,34 +467,28 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* update map data
|
||||
* function is called continuously
|
||||
* @param $f3
|
||||
* -> function is called continuously (trigger) by any active client
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function updateData($f3){
|
||||
|
||||
// cache time(s) per user should be equal or less than this function is called
|
||||
// prevent request flooding
|
||||
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_MAP.DELAY') / 1000;
|
||||
public function updateData(\Base $f3){
|
||||
$mapData = (array)$f3->get('POST.mapData');
|
||||
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
if($user){
|
||||
// -> get active character
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
if($activeCharacter){
|
||||
|
||||
$cacheKey = 'user_map_data_' . $activeCharacter->id;
|
||||
|
||||
// if there is any system/connection change data submitted -> save new data
|
||||
if(
|
||||
$f3->exists($cacheKey) === false ||
|
||||
!$f3->exists($cacheKey) ||
|
||||
!empty($mapData)
|
||||
){
|
||||
|
||||
// get current map data ========================================================
|
||||
$maps = $user->getMaps();
|
||||
$maps = $activeCharacter->getUser()->getMaps();
|
||||
|
||||
// loop all submitted map data that should be saved
|
||||
// -> currently there will only be ONE map data change submitted -> single loop
|
||||
@@ -532,7 +538,7 @@ class Map extends \Controller\AccessController {
|
||||
unset($systemData['updated']);
|
||||
$system = $filteredMap->systems->current();
|
||||
$system->setData($systemData);
|
||||
$system->updatedCharacterId = $activeCharacter->characterId;
|
||||
$system->updatedCharacterId = $activeCharacter;
|
||||
$system->save();
|
||||
|
||||
// a system belongs to ONE map -> speed up for multiple maps
|
||||
@@ -561,7 +567,7 @@ class Map extends \Controller\AccessController {
|
||||
unset($connectionData['updated']);
|
||||
$connection = $filteredMap->connections->current();
|
||||
$connection->setData($connectionData);
|
||||
$connection->save($user);
|
||||
$connection->save();
|
||||
|
||||
// a connection belongs to ONE map -> speed up for multiple maps
|
||||
unset($connectionData[$i]);
|
||||
@@ -574,6 +580,11 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
// format map Data for return
|
||||
$return->mapData = self::getFormattedMapData($maps);
|
||||
|
||||
// cache time(s) per user should be equal or less than this function is called
|
||||
// prevent request flooding
|
||||
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_MAP.DELAY') / 1000;
|
||||
|
||||
$f3->set($cacheKey, $return, $responseTTL);
|
||||
}else{
|
||||
// get from cache
|
||||
@@ -582,23 +593,24 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
}else{
|
||||
// user logged off
|
||||
$return->error[] = $this->getUserLoggedOffError();
|
||||
$return->error[] = $this->getLogoutError();
|
||||
}
|
||||
|
||||
echo json_encode( $return );
|
||||
}
|
||||
|
||||
/**
|
||||
* get formatted map data
|
||||
* @param $mapModels
|
||||
* @return Model\MapModel[]
|
||||
* @return array
|
||||
*/
|
||||
public static function getFormattedMapData($mapModels){
|
||||
|
||||
$mapData = [];
|
||||
foreach($mapModels as $mapModel){
|
||||
|
||||
foreach($mapModels as &$mapModel){
|
||||
/**
|
||||
* @var $mapModel Model\MapModel
|
||||
*/
|
||||
$allMapData = $mapModel->getData();
|
||||
|
||||
$mapData[] = [
|
||||
'config' => $allMapData->mapData,
|
||||
'data' => [
|
||||
@@ -613,33 +625,23 @@ class Map extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* update map data api
|
||||
* function is called continuously
|
||||
* @param $f3
|
||||
* -> function is called continuously by any active client
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function updateUserData($f3){
|
||||
|
||||
// cache time(s) should be equal or less than request trigger time
|
||||
// prevent request flooding
|
||||
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_USER_DATA.DELAY') / 1000;
|
||||
|
||||
// if the cache key will be set -> cache request
|
||||
$cacheKey = null;
|
||||
|
||||
public function updateUserData(\Base $f3){
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
|
||||
if($user){
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
if( !empty($f3->get('POST.mapIds')) ){
|
||||
$mapIds = (array)$f3->get('POST.mapIds');
|
||||
// check if data for specific system is requested
|
||||
$systemData = (array)$f3->get('POST.systemData');
|
||||
|
||||
|
||||
// update current location (IGB data)
|
||||
$user->updateCharacterLog(60 * 5);
|
||||
// update current location
|
||||
$activeCharacter->updateLog();
|
||||
|
||||
// if data is requested extend the cache key in order to get new data
|
||||
$requestSystemData = (object) [];
|
||||
@@ -649,12 +651,11 @@ class Map extends \Controller\AccessController {
|
||||
// IMPORTANT for now -> just update a single map (save performance)
|
||||
$mapIds = array_slice($mapIds, 0, 1);
|
||||
|
||||
// the userMasData is cached per map (this must be changed if multiple maps
|
||||
// the userMapData is cached per map (this must be changed if multiple maps
|
||||
// will be allowed in future...
|
||||
$tempId = (int)$mapIds[0];
|
||||
$cacheKey = 'user_data_' . $tempId . '_' . $requestSystemData->systemId;
|
||||
|
||||
if( $f3->exists($cacheKey) === false ){
|
||||
if( !$f3->exists($cacheKey) ){
|
||||
foreach($mapIds as $mapId){
|
||||
$map = $user->getMap($mapId);
|
||||
|
||||
@@ -666,7 +667,7 @@ class Map extends \Controller\AccessController {
|
||||
$system = $map->getSystem( $requestSystemData->systemId );
|
||||
|
||||
if( !is_null($system) ){
|
||||
// data for the current selected system
|
||||
// data for currently selected system
|
||||
$return->system = $system->getData();
|
||||
$return->system->signatures = $system->getSignaturesData();
|
||||
}
|
||||
@@ -674,6 +675,10 @@ class Map extends \Controller\AccessController {
|
||||
}
|
||||
}
|
||||
|
||||
// cache time (seconds) should be equal or less than request trigger time
|
||||
// prevent request flooding
|
||||
$responseTTL = $f3->get('PATHFINDER.TIMER.UPDATE_SERVER_USER_DATA.DELAY') / 1000;
|
||||
|
||||
// cache response
|
||||
$f3->set($cacheKey, $return, $responseTTL);
|
||||
}else{
|
||||
@@ -683,17 +688,14 @@ class Map extends \Controller\AccessController {
|
||||
$return = $f3->get($cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
// get current user data -> this should not be cached because each user has different personal data
|
||||
// even if they have multiple characters using the same map!
|
||||
$return->userData = $user->getData();
|
||||
|
||||
}else{
|
||||
// user logged off
|
||||
$return->error[] = $this->getUserLoggedOffError();
|
||||
$return->error[] = $this->getLogoutError();
|
||||
}
|
||||
|
||||
|
||||
echo json_encode( $return );
|
||||
}
|
||||
|
||||
|
||||
@@ -14,14 +14,12 @@ class Signature extends \Controller\AccessController{
|
||||
|
||||
/**
|
||||
* event handler
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
|
||||
parent::beforeroute($f3);
|
||||
|
||||
function beforeroute(\Base $f3) {
|
||||
// set header for all routes
|
||||
header('Content-type: application/json');
|
||||
parent::beforeroute($f3);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,18 +29,18 @@ class Signature extends \Controller\AccessController{
|
||||
public function getAll($f3){
|
||||
$signatureData = [];
|
||||
$systemIds = $f3->get('POST.systemIds');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
|
||||
/**
|
||||
* @var Model\SystemModel $system
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
|
||||
foreach($systemIds as $systemId){
|
||||
$system->getById($systemId);
|
||||
|
||||
if(!$system->dry()){
|
||||
|
||||
// check access
|
||||
if($system->hasAccess($user)){
|
||||
if( $system->hasAccess($activeCharacter->getUser()) ){
|
||||
$signatureData = $system->getSignaturesData();
|
||||
}
|
||||
}
|
||||
@@ -74,11 +72,14 @@ class Signature extends \Controller\AccessController{
|
||||
}
|
||||
|
||||
if( !is_null($signatureData) ){
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($user){
|
||||
$activeUserCharacter = $user->getActiveUserCharacter();
|
||||
$activeCharacter = $activeUserCharacter->getCharacter();
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
/**
|
||||
* @var Model\SystemModel $system
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
|
||||
// update/add all submitted signatures
|
||||
@@ -173,23 +174,23 @@ class Signature extends \Controller\AccessController{
|
||||
|
||||
/**
|
||||
* delete signatures
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function delete($f3){
|
||||
$signatureIds = $f3->get('POST.signatureIds');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
/**
|
||||
* @var Model\SystemSignatureModel $signature
|
||||
*/
|
||||
$signature = Model\BasicModel::getNew('SystemSignatureModel');
|
||||
|
||||
foreach($signatureIds as $signatureId){
|
||||
$signature->getById($signatureId);
|
||||
|
||||
$signature->delete($user);
|
||||
$signature->delete( $activeCharacter->getUser() );
|
||||
$signature->reset();
|
||||
}
|
||||
|
||||
echo json_encode([]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -63,9 +63,9 @@ class System extends \Controller\AccessController {
|
||||
private $limitQuery = "";
|
||||
|
||||
/**
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
function beforeroute(\Base $f3) {
|
||||
|
||||
parent::beforeroute($f3);
|
||||
|
||||
@@ -92,7 +92,8 @@ class System extends \Controller\AccessController {
|
||||
* get static system Data from CCPs Static DB export
|
||||
* search column for IDs can be (solarSystemID, regionID, constellationID)
|
||||
* @param array $columnIDs
|
||||
* @return null
|
||||
* @param string $column
|
||||
* @return Model\SystemModel[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _getSystemModelByIds($columnIDs = [], $column = 'solarSystemID'){
|
||||
@@ -110,10 +111,12 @@ class System extends \Controller\AccessController {
|
||||
|
||||
// format result
|
||||
$mapper = new Mapper\CcpSystemsMapper($rows);
|
||||
|
||||
$ccpSystemsData = $mapper->getData();
|
||||
|
||||
foreach($ccpSystemsData as $ccpSystemData){
|
||||
/**
|
||||
* @var Model\SystemModel $system
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
$system->setData($ccpSystemData);
|
||||
$systemModels[] = $system;
|
||||
@@ -142,10 +145,10 @@ class System extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* search systems by name
|
||||
* @param $f3
|
||||
* @param $params
|
||||
* @param \Base $f3
|
||||
* @param array $params
|
||||
*/
|
||||
public function search($f3, $params){
|
||||
public function search(\Base $f3, $params){
|
||||
|
||||
$ccpDB = $this->getDB('CCP');
|
||||
|
||||
@@ -172,10 +175,9 @@ class System extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* save a new system to a a map
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function save($f3){
|
||||
|
||||
public function save(\Base $f3){
|
||||
$newSystemData = [];
|
||||
|
||||
$postData = (array)$f3->get('POST');
|
||||
@@ -187,20 +189,21 @@ class System extends \Controller\AccessController {
|
||||
isset($postData['systemData']) &&
|
||||
isset($postData['mapData'])
|
||||
){
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($user){
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
$systemData = (array)$postData['systemData'];
|
||||
$mapData = (array)$postData['mapData'];
|
||||
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
|
||||
if( isset($systemData['id']) ){
|
||||
// update existing system
|
||||
|
||||
/**
|
||||
* @var $system Model\SystemModel
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
$system->getById($systemData['id']);
|
||||
|
||||
if( !$system->dry() ){
|
||||
if( $system->hasAccess($user) ){
|
||||
// system model found
|
||||
@@ -210,9 +213,11 @@ class System extends \Controller\AccessController {
|
||||
}elseif( isset($mapData['id']) ){
|
||||
// save NEW system
|
||||
|
||||
/**
|
||||
* @var $map Model\MapModel
|
||||
*/
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
$map->getById($mapData['id']);
|
||||
|
||||
if( !$map->dry() ){
|
||||
if( $map->hasAccess($user) ){
|
||||
|
||||
@@ -221,7 +226,7 @@ class System extends \Controller\AccessController {
|
||||
// get static system data (CCP DB)
|
||||
$systemModel = array_values( $this->_getSystemModelByIds([$systemData['systemId']]) )[0];
|
||||
|
||||
$systemModel->createdCharacterId = $activeCharacter->characterId;
|
||||
$systemModel->createdCharacterId = $activeCharacter;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -229,50 +234,23 @@ class System extends \Controller\AccessController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !is_null($systemModel) ){
|
||||
// set/update system
|
||||
|
||||
$systemModel->setData($systemData);
|
||||
$systemModel->updatedCharacterId = $activeCharacter->characterId;
|
||||
$systemModel->updatedCharacterId = $activeCharacter;
|
||||
$systemModel->save();
|
||||
|
||||
$newSystemData = $systemModel->getData();
|
||||
}
|
||||
|
||||
echo json_encode($newSystemData);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete systems and all its connections
|
||||
* @param $f3
|
||||
*/
|
||||
public function delete($f3){
|
||||
$systemIds = $f3->get('POST.systemIds');
|
||||
|
||||
$user = $this->_getUser();
|
||||
|
||||
if($user){
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
|
||||
foreach((array)$systemIds as $systemId){
|
||||
|
||||
$system->getById($systemId);
|
||||
$system->delete($user);
|
||||
|
||||
$system->reset();
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* get system log data from CCP API import
|
||||
* system Kills, Jumps,....
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function graphData($f3){
|
||||
public function graphData(\Base $f3){
|
||||
$graphData = [];
|
||||
$systemIds = $f3->get('POST.systemIds');
|
||||
|
||||
@@ -288,7 +266,6 @@ class System extends \Controller\AccessController {
|
||||
];
|
||||
|
||||
foreach($systemIds as $systemId){
|
||||
|
||||
foreach($logTables as $label => $ModelClass){
|
||||
$systemLogModel = Model\BasicModel::getNew($ModelClass);
|
||||
|
||||
@@ -313,7 +290,6 @@ class System extends \Controller\AccessController {
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,25 +298,22 @@ class System extends \Controller\AccessController {
|
||||
|
||||
/**
|
||||
* get system data for all systems within a constellation
|
||||
* @param $f3
|
||||
* @param $params
|
||||
* @param \Base $f3
|
||||
* @param array $params
|
||||
*/
|
||||
public function constellationData($f3, $params){
|
||||
|
||||
public function constellationData(\Base $f3, $params){
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
$return->systemData = [];
|
||||
|
||||
$constellationId = 0;
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$user = $this->_getUser();
|
||||
|
||||
if($user){
|
||||
if($activeCharacter){
|
||||
// check for search parameter
|
||||
if( isset($params['arg1']) ){
|
||||
$constellationId = (int)$params['arg1'];
|
||||
}
|
||||
|
||||
$cacheKey = 'CACHE_CONSTELLATION_SYSTEMS_' . self::formatHiveKey($constellationId);
|
||||
|
||||
if($f3->exists($cacheKey)){
|
||||
@@ -361,7 +334,29 @@ class System extends \Controller\AccessController {
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete systems and all its connections
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function delete(\Base $f3){
|
||||
$systemIds = $f3->get('POST.systemIds');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
/**
|
||||
* @var Model\SystemModel $system
|
||||
*/
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
foreach((array)$systemIds as $systemId){
|
||||
$system->getById($systemId);
|
||||
$system->delete($user);
|
||||
$system->reset();
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,87 +15,76 @@ use DB;
|
||||
|
||||
class User extends Controller\Controller{
|
||||
|
||||
// user specific session keys
|
||||
const SESSION_KEY_USER = 'SESSION.USER';
|
||||
const SESSION_KEY_USER_ID = 'SESSION.USER.ID';
|
||||
const SESSION_KEY_USER_NAME = 'SESSION.USER.NAME';
|
||||
|
||||
// character specific session keys
|
||||
const SESSION_KEY_CHARACTER = 'SESSION.CHARACTER';
|
||||
const SESSION_KEY_CHARACTER_ID = 'SESSION.CHARACTER.ID';
|
||||
const SESSION_KEY_CHARACTER_NAME = 'SESSION.CHARACTER.NAME';
|
||||
const SESSION_KEY_CHARACTER_TIME = 'SESSION.CHARACTER.TIME';
|
||||
|
||||
const SESSION_KEY_CHARACTER_ACCESS_TOKEN = 'SESSION.CHARACTER.ACCESS_TOKEN';
|
||||
const SESSION_KEY_CHARACTER_REFRESH_TOKEN = 'SESSION.CHARACTER.REFRESH_TOKEN';
|
||||
|
||||
// log text
|
||||
const LOG_LOGGED_IN = 'userId: %s, userName: %s, charId: %s, charName: %s';
|
||||
|
||||
/**
|
||||
* valid reasons for captcha images
|
||||
* @var array
|
||||
* @var string array
|
||||
*/
|
||||
private static $captchaReason = ['createAccount', 'deleteAccount'];
|
||||
|
||||
/**
|
||||
* login function
|
||||
* @param $f3
|
||||
* login a valid character
|
||||
* @param Model\CharacterModel $characterModel
|
||||
* @return bool
|
||||
*/
|
||||
public function logIn($f3){
|
||||
$data = $data = $f3->get('POST');
|
||||
protected function loginByCharacter(Model\CharacterModel &$characterModel){
|
||||
$login = false;
|
||||
|
||||
$return = (object) [];
|
||||
|
||||
$user = null;
|
||||
|
||||
if($data['loginData']){
|
||||
$loginData = $data['loginData'];
|
||||
$user = $this->logUserIn( $loginData['userName'], $loginData['userPassword'] );
|
||||
}
|
||||
|
||||
// set "vague" error
|
||||
if(is_null($user)){
|
||||
$return->error = [];
|
||||
$loginError = (object) [];
|
||||
$loginError->type = 'login';
|
||||
$return->error[] = $loginError;
|
||||
}else{
|
||||
// update/check api data
|
||||
$user->updateApiData();
|
||||
|
||||
// route user to map app
|
||||
$return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $f3->alias('map');
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* core function for user login
|
||||
* @param $userName
|
||||
* @param $password
|
||||
* @return Model\UserModel|null
|
||||
*/
|
||||
private function logUserIn($userName, $password){
|
||||
|
||||
// try to verify user
|
||||
$user = $this->_verifyUser($userName, $password);
|
||||
|
||||
if( !is_null($user)){
|
||||
// user is verified -> ready for login
|
||||
|
||||
// set Session login
|
||||
$dateTime = new \DateTime();
|
||||
|
||||
$this->f3->set('SESSION.user', [
|
||||
'time' => $dateTime->getTimestamp(),
|
||||
'name' => $user->name,
|
||||
'id' => $user->id
|
||||
if($user = $characterModel->getUser()){
|
||||
// set user/character data to session -------------------
|
||||
$this->f3->set(self::SESSION_KEY_USER, [
|
||||
'ID' => $user->_id,
|
||||
'NAME' => $user->name
|
||||
]);
|
||||
|
||||
// save user login information
|
||||
$user->touch('lastLogin');
|
||||
$user->save();
|
||||
$dateTime = new \DateTime();
|
||||
$this->f3->set(self::SESSION_KEY_CHARACTER, [
|
||||
'ID' => $characterModel->_id,
|
||||
'NAME' => $characterModel->name,
|
||||
'TIME' => $dateTime->getTimestamp()
|
||||
]);
|
||||
|
||||
// save log
|
||||
$logText = "id: %s, name: %s, ip: %s";
|
||||
// save user login information ---------------------------
|
||||
$characterModel->touch('lastLogin');
|
||||
$characterModel->save();
|
||||
|
||||
// write login log --------------------------------------
|
||||
self::getLogger( $this->f3->get('PATHFINDER.LOGFILES.LOGIN') )->write(
|
||||
sprintf($logText, $user->id, $user->name, $this->f3->get('IP'))
|
||||
sprintf(self::LOG_LOGGED_IN,
|
||||
$user->_id,
|
||||
$user->name,
|
||||
$characterModel->_id,
|
||||
$characterModel->name
|
||||
)
|
||||
);
|
||||
|
||||
$login = true;
|
||||
}
|
||||
|
||||
return $user;
|
||||
return $login;
|
||||
}
|
||||
|
||||
/**
|
||||
* get captcha image and store key to session
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function getCaptcha($f3){
|
||||
public function getCaptcha(\Base $f3){
|
||||
$data = $f3->get('POST');
|
||||
|
||||
$return = (object) [];
|
||||
@@ -136,29 +125,22 @@ class User extends Controller\Controller{
|
||||
|
||||
/**
|
||||
* delete the character log entry for the current active (main) character
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function deleteLog($f3){
|
||||
|
||||
$user = $this->_getUser();
|
||||
if($user){
|
||||
$activeUserCharacter = $user->getActiveUserCharacter();
|
||||
|
||||
if($activeUserCharacter){
|
||||
$character = $activeUserCharacter->getCharacter();
|
||||
|
||||
if($characterLog = $character->getLog()){
|
||||
$characterLog->erase();
|
||||
}
|
||||
public function deleteLog(\Base $f3){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
if($activeCharacter){
|
||||
if($characterLog = $activeCharacter->getLog()){
|
||||
$characterLog->erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* log the current user out + clear character system log data
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function logOut($f3){
|
||||
public function logOut(\Base $f3){
|
||||
$this->deleteLog($f3);
|
||||
parent::logOut($f3);
|
||||
}
|
||||
@@ -166,9 +148,9 @@ class User extends Controller\Controller{
|
||||
/**
|
||||
* save/update "map sharing" configurations for all map types
|
||||
* the user has access to
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function saveSharingConfig($f3){
|
||||
public function saveSharingConfig(\Base $f3){
|
||||
$data = $f3->get('POST');
|
||||
|
||||
$return = (object) [];
|
||||
@@ -177,9 +159,10 @@ class User extends Controller\Controller{
|
||||
$corporationSharing = 0;
|
||||
$allianceSharing = 0;
|
||||
|
||||
$user = $this->_getUser();
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($user){
|
||||
if($activeCharacter){
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
// form values
|
||||
if(isset($data['formData'])){
|
||||
@@ -202,22 +185,17 @@ class User extends Controller\Controller{
|
||||
$user->save();
|
||||
|
||||
// update corp/ally ---------------------------------------------------------------
|
||||
$corporation = $activeCharacter->getCorporation();
|
||||
$alliance = $activeCharacter->getAlliance();
|
||||
|
||||
$activeUserCharacter = $user->getActiveUserCharacter();
|
||||
if(is_object($corporation)){
|
||||
$corporation->shared = $corporationSharing;
|
||||
$corporation->save();
|
||||
}
|
||||
|
||||
if(is_object($activeUserCharacter)){
|
||||
$corporation = $activeUserCharacter->getCharacter()->getCorporation();
|
||||
$alliance = $activeUserCharacter->getCharacter()->getAlliance();
|
||||
|
||||
if(is_object($corporation)){
|
||||
$corporation->shared = $corporationSharing;
|
||||
$corporation->save();
|
||||
}
|
||||
|
||||
if(is_object($alliance)){
|
||||
$alliance->shared = $allianceSharing;
|
||||
$alliance->save();
|
||||
}
|
||||
if(is_object($alliance)){
|
||||
$alliance->shared = $allianceSharing;
|
||||
$alliance->save();
|
||||
}
|
||||
|
||||
$return->userData = $user->getData();
|
||||
@@ -282,9 +260,9 @@ class User extends Controller\Controller{
|
||||
|
||||
/**
|
||||
* save/update user account data
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function saveAccount($f3){
|
||||
public function saveAccount(\Base $f3){
|
||||
$data = $f3->get('POST');
|
||||
|
||||
$return = (object) [];
|
||||
@@ -308,7 +286,8 @@ class User extends Controller\Controller{
|
||||
$settingsData = $data['settingsData'];
|
||||
|
||||
try{
|
||||
$user = $this->_getUser(0);
|
||||
$activeCharacter = $this->getCharacter(0);
|
||||
$user = $activeCharacter->getUser();
|
||||
|
||||
// captcha is send -> check captcha
|
||||
if(
|
||||
@@ -320,7 +299,7 @@ class User extends Controller\Controller{
|
||||
if($settingsData['captcha'] === $captcha){
|
||||
// change/set sensitive user data requires captcha!
|
||||
|
||||
if($user === false){
|
||||
if(is_null($user)){
|
||||
|
||||
// check if registration key invite function is enabled
|
||||
if($f3->get('PATHFINDER.REGISTRATION.INVITE') === 1 ){
|
||||
@@ -332,7 +311,7 @@ class User extends Controller\Controller{
|
||||
}
|
||||
|
||||
// new user registration
|
||||
$user = $mapType = Model\BasicModel::getNew('UserModel');
|
||||
$user = Model\BasicModel::getNew('UserModel');
|
||||
$loginAfterSave = true;
|
||||
|
||||
// set username
|
||||
@@ -429,7 +408,7 @@ class User extends Controller\Controller{
|
||||
}
|
||||
|
||||
// get fresh updated user object (API info may have has changed)
|
||||
$user = $this->_getUser(0);
|
||||
//$user = $this->_getUser(0);
|
||||
}
|
||||
|
||||
// set main character
|
||||
@@ -457,14 +436,13 @@ class User extends Controller\Controller{
|
||||
|
||||
// log user in (in case he is new
|
||||
if($loginAfterSave){
|
||||
$this->logUserIn( $user->name, $settingsData['password'] );
|
||||
$this->logInByData( $user->name, $settingsData['password'] );
|
||||
|
||||
// return reroute path
|
||||
$return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $this->f3->alias('map');
|
||||
}
|
||||
|
||||
// get fresh updated user object
|
||||
$user = $this->_getUser(0);
|
||||
$newUserData = $user->getData();
|
||||
}
|
||||
}catch(Exception\ValidationException $e){
|
||||
@@ -491,10 +469,10 @@ class User extends Controller\Controller{
|
||||
/**
|
||||
* send mail with registration key
|
||||
* -> check INVITE in pathfinder.ini
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendInvite($f3){
|
||||
public function sendInvite(\Base $f3){
|
||||
$data = $f3->get('POST.settingsData');
|
||||
$return = (object) [];
|
||||
|
||||
@@ -593,9 +571,9 @@ class User extends Controller\Controller{
|
||||
|
||||
/**
|
||||
* delete current user account from DB
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function deleteAccount($f3){
|
||||
public function deleteAccount(\Base $f3){
|
||||
$data = $f3->get('POST.formData');
|
||||
$return = (object) [];
|
||||
|
||||
@@ -609,8 +587,8 @@ class User extends Controller\Controller{
|
||||
!empty($data['captcha']) &&
|
||||
$data['captcha'] === $captcha
|
||||
){
|
||||
$user = $this->_getUser(0);
|
||||
|
||||
$activeCharacter = $this->getCharacter(0);
|
||||
$user = $activeCharacter->getUser();
|
||||
$validUser = $this->_verifyUser( $user->name, $data['password']);
|
||||
|
||||
if(
|
||||
|
||||
@@ -7,15 +7,26 @@
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
use Controller\Ccp as Ccp;
|
||||
|
||||
class AppController extends Controller {
|
||||
|
||||
/**
|
||||
* show main login (index) page
|
||||
* @param $f3
|
||||
* event handler after routing
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function init($f3) {
|
||||
public function afterroute(\Base $f3){
|
||||
parent::afterroute($f3);
|
||||
|
||||
// clear all SSO related temp data
|
||||
$f3->clear(Ccp\Sso::SESSION_KEY_SSO);
|
||||
}
|
||||
|
||||
/**
|
||||
* show main login (index) page
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function init(\Base $f3) {
|
||||
// page title
|
||||
$f3->set('pageTitle', 'Login');
|
||||
|
||||
|
||||
604
app/main/controller/ccp/sso.php
Normal file
604
app/main/controller/ccp/sso.php
Normal file
@@ -0,0 +1,604 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 23.01.2016
|
||||
* Time: 17:18
|
||||
*
|
||||
* Handles access to EVE-Online "CREST API" and "SSO" auth functions
|
||||
* - Add your API credentials in "environment.ini"
|
||||
* - Check "PATHFINDER.API" in "pathfinder.ini" for correct API URLs
|
||||
* Hint: \Web::instance()->request automatically caches responses by their response "Cache-Control" header!
|
||||
*/
|
||||
|
||||
namespace Controller\Ccp;
|
||||
use Controller;
|
||||
use Controller\Api as Api;
|
||||
use Data\Mapper as Mapper;
|
||||
use Model;
|
||||
use Lib;
|
||||
|
||||
class Sso extends Api\User{
|
||||
|
||||
/**
|
||||
* @var int timeout (seconds) for API calls
|
||||
*/
|
||||
const CREST_TIMEOUT = 3;
|
||||
|
||||
/**
|
||||
* @var int expire time (seconds) for an valid "accessToken"
|
||||
*/
|
||||
const ACCESS_KEY_EXPIRE_TIME = 20 * 60;
|
||||
|
||||
// SSO specific session keys
|
||||
const SESSION_KEY_SSO = 'SESSION.SSO';
|
||||
const SESSION_KEY_SSO_ERROR = 'SESSION.SSO.ERROR';
|
||||
const SESSION_KEY_SSO_STATE = 'SESSION.SSO.STATE';
|
||||
|
||||
// error messages
|
||||
const ERROR_CCP_SSO_URL = 'Invalid "ENVIRONMENT.[ENVIRONMENT].SSO_CCP_URL" url. %s';
|
||||
const ERROR_CCP_CREST_URL = 'Invalid "ENVIRONMENT.[ENVIRONMENT].CCP_CREST_URL" url. %s';
|
||||
const ERROR_RESOURCE_DEPRECATED = 'Resource: %s has been marked as deprecated. %s';
|
||||
const ERROR_ACCESS_TOKEN = 'Unable to get a valid "access_token. %s';
|
||||
const ERROR_VERIFY_CHARACTER = 'Unable to verify character data. %s';
|
||||
const ERROR_GET_ENDPOINT = 'Unable to get endpoint data. $s';
|
||||
const ERROR_FIND_ENDPOINT = 'Unable to find endpoint: %s';
|
||||
const ERROR_LOGIN_FAILED = 'Failed authentication due to technical problems: %s';
|
||||
|
||||
/**
|
||||
* CREST "Scopes" are used by pathfinder
|
||||
* -> Enable scopes: https://developers.eveonline.com
|
||||
* @var array
|
||||
*/
|
||||
private $requestScopes = [
|
||||
// 'characterFittingsRead',
|
||||
// 'characterFittingsWrite',
|
||||
'characterLocationRead',
|
||||
'characterNavigationWrite'
|
||||
];
|
||||
|
||||
/**
|
||||
* redirect user to CCP SSO page and request authorization
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function requestAuthorization($f3){
|
||||
|
||||
// used for "state" check between request and callback
|
||||
$state = bin2hex(mcrypt_create_iv(12, MCRYPT_DEV_URANDOM));
|
||||
$f3->set(self::SESSION_KEY_SSO_STATE, $state);
|
||||
|
||||
$urlParams = [
|
||||
'response_type' => 'code',
|
||||
'redirect_uri' => Controller\Controller::getEnvironmentData('URL') . $f3->build('/sso/callbackAuthorization'),
|
||||
'client_id' => Controller\Controller::getEnvironmentData('SSO_CCP_CLIENT_ID'),
|
||||
'scope' => implode(' ', $this->requestScopes),
|
||||
'state' => $state
|
||||
];
|
||||
|
||||
$ssoAuthUrl = self::getAuthorizationEndpoint() . '?' . http_build_query($urlParams, '', '&', PHP_QUERY_RFC3986 );
|
||||
|
||||
$f3->status(302);
|
||||
$f3->reroute($ssoAuthUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* callback handler for CCP SSO user Auth
|
||||
* -> see requestAuthorization()
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function callbackAuthorization($f3){
|
||||
$getParams = (array)$f3->get('GET');
|
||||
|
||||
if($f3->exists(self::SESSION_KEY_SSO_STATE)){
|
||||
// check response and validate 'state'
|
||||
if(
|
||||
isset($getParams['code']) &&
|
||||
isset($getParams['state']) &&
|
||||
!empty($getParams['code']) &&
|
||||
!empty($getParams['state']) &&
|
||||
$f3->get(self::SESSION_KEY_SSO_STATE) === $getParams['state']
|
||||
){
|
||||
// clear 'state' for new next request
|
||||
$f3->clear(self::SESSION_KEY_SSO_STATE);
|
||||
|
||||
$accessData = $this->getCrestAccessData($getParams['code']);
|
||||
|
||||
if(
|
||||
isset($accessData->accessToken) &&
|
||||
isset($accessData->refreshToken)
|
||||
){
|
||||
// login succeeded -> get basic character data for current login
|
||||
$verificationCharacterData = $this->verifyCharacterData($accessData->accessToken);
|
||||
|
||||
if( !is_null($verificationCharacterData)){
|
||||
// verification data available. Data is needed for "ownerHash" check
|
||||
|
||||
// get character data from CREST
|
||||
$characterData = $this->getCharacterData($accessData->accessToken);
|
||||
|
||||
if(isset($characterData->character)){
|
||||
// add "ownerHash" and CREST tokens
|
||||
$characterData->character['ownerHash'] = $verificationCharacterData->CharacterOwnerHash;
|
||||
$characterData->character['crestAccessToken'] = $accessData->accessToken;
|
||||
$characterData->character['crestRefreshToken'] = $accessData->refreshToken;
|
||||
|
||||
// add/update static character data
|
||||
$characterModel = $this->updateCharacter($characterData);
|
||||
|
||||
if( !is_null($characterModel) ){
|
||||
// check if character is authorized to log in
|
||||
if($characterModel->isAuthorized()){
|
||||
|
||||
// character is authorized to log in
|
||||
// -> update character log (current location,...)
|
||||
$characterModel = $characterModel->updateLog();
|
||||
|
||||
// check if there is already a user created who owns this char
|
||||
$user = $characterModel->getUser();
|
||||
|
||||
if(is_null($user)){
|
||||
// no user found -> create one and connect to character
|
||||
/**
|
||||
* @var Model\UserModel $user
|
||||
*/
|
||||
$user = Model\BasicModel::getNew('UserModel');
|
||||
$user->name = $characterModel->name;
|
||||
$user->save();
|
||||
|
||||
/**
|
||||
* @var Model\UserCharacterModel $userCharactersModel
|
||||
*/
|
||||
$userCharactersModel = Model\BasicModel::getNew('UserCharacterModel');
|
||||
$userCharactersModel->userId = $user;
|
||||
$userCharactersModel->characterId = $characterModel;
|
||||
$userCharactersModel->save();
|
||||
|
||||
// get updated character model
|
||||
$characterModel = $userCharactersModel->getCharacter();
|
||||
}
|
||||
|
||||
// login by character
|
||||
$loginCheck = $this->loginByCharacter($characterModel);
|
||||
|
||||
if($loginCheck){
|
||||
// route to "map"
|
||||
$f3->reroute('@map');
|
||||
}else{
|
||||
$f3->set(self::SESSION_KEY_SSO_ERROR, sprintf(self::ERROR_LOGIN_FAILED, $characterModel->name));
|
||||
}
|
||||
}else{
|
||||
// character is not authorized to log in
|
||||
$f3->set(self::SESSION_KEY_SSO_ERROR, 'Character "' . $characterModel->name . '" is not authorized to log in.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// on error -> route back to login form
|
||||
$f3->reroute('@login');
|
||||
}
|
||||
|
||||
/**
|
||||
* get a valid "access_token" for oAuth 2.0 verification
|
||||
* -> if $authCode is set -> request NEW "access_token"
|
||||
* -> else check for existing (not expired) "access_token"
|
||||
* -> else try to refresh auth and get fresh "access_token"
|
||||
* @param bool $authCode
|
||||
* @return null|\stdClass
|
||||
*/
|
||||
public function getCrestAccessData($authCode){
|
||||
$accessData = null;
|
||||
|
||||
if( !empty($authCode) ){
|
||||
// Authentication Code is set -> request new "accessToken"
|
||||
$accessData = $this->verifyAuthorizationCode($authCode);
|
||||
}else{
|
||||
// Unable to get Token -> trigger error
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_ACCESS_TOKEN, $authCode));
|
||||
}
|
||||
|
||||
return $accessData;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify authorization code, and get an "access_token" data
|
||||
* @param $authCode
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function verifyAuthorizationCode($authCode){
|
||||
$requestParams = [
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $authCode
|
||||
];
|
||||
|
||||
return $this->requestAccessData($requestParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* get new "access_token" by an existing "refresh_token"
|
||||
* -> if "access_token" is expired, this function gets a fresh one
|
||||
* @param $refreshToken
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function refreshAccessToken($refreshToken){
|
||||
$requestParams = [
|
||||
'grant_type' => 'refresh_token',
|
||||
'refresh_token' => $refreshToken
|
||||
];
|
||||
|
||||
return $this->requestAccessData($requestParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* request an "access_token" AND "refresh_token" data
|
||||
* -> this can either be done by sending a valid "authorization code"
|
||||
* OR by providing a valid "refresh_token"
|
||||
* @param $requestParams
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function requestAccessData($requestParams){
|
||||
$verifyAuthCodeUrl = self::getVerifyAuthorizationCodeEndpoint();
|
||||
$verifyAuthCodeUrlParts = parse_url($verifyAuthCodeUrl);
|
||||
|
||||
$accessData = (object) [];
|
||||
$accessData->accessToken = null;
|
||||
$accessData->refreshToken = null;
|
||||
|
||||
if($verifyAuthCodeUrlParts){
|
||||
$contentType = 'application/x-www-form-urlencoded';
|
||||
$requestOptions = [
|
||||
'timeout' => self::CREST_TIMEOUT,
|
||||
'method' => 'POST',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Basic ' . $this->getAuthorizationHeader(),
|
||||
'Content-Type: ' . $contentType,
|
||||
'Host: ' . $verifyAuthCodeUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
// content (parameters to send with)
|
||||
$requestOptions['content'] = http_build_query($requestParams);
|
||||
|
||||
$apiResponse = Lib\Web::instance()->request($verifyAuthCodeUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$authCodeRequestData = json_decode($apiResponse['body']);
|
||||
|
||||
if(isset($authCodeRequestData->access_token)){
|
||||
// this token is required for endpoints that require Auth
|
||||
$accessData->accessToken = $authCodeRequestData->access_token;
|
||||
}
|
||||
|
||||
if(isset($authCodeRequestData->refresh_token)){
|
||||
// this token is used to refresh/get a new access_token when expires
|
||||
$accessData->refreshToken = $authCodeRequestData->refresh_token;
|
||||
}
|
||||
}else{
|
||||
self::getCrestLogger()->write(
|
||||
sprintf(
|
||||
self::ERROR_ACCESS_TOKEN,
|
||||
print_r($requestParams, true)
|
||||
)
|
||||
);
|
||||
}
|
||||
}else{
|
||||
self::getCrestLogger()->write(
|
||||
sprintf(self::ERROR_CCP_SSO_URL, __METHOD__)
|
||||
);
|
||||
}
|
||||
|
||||
return $accessData;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify character data by "access_token"
|
||||
* -> get some basic information (like character id)
|
||||
* -> if more character information is required, use CREST endpoints request instead
|
||||
* @param $accessToken
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function verifyCharacterData($accessToken){
|
||||
$verifyUserUrl = self::getVerifyUserEndpoint();
|
||||
$verifyUrlParts = parse_url($verifyUserUrl);
|
||||
$characterData = null;
|
||||
|
||||
if($verifyUrlParts){
|
||||
$requestOptions = [
|
||||
'timeout' => self::CREST_TIMEOUT,
|
||||
'method' => 'GET',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Host: ' . $verifyUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
$apiResponse = Lib\Web::instance()->request($verifyUserUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$characterData = json_decode($apiResponse['body']);
|
||||
}else{
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_VERIFY_CHARACTER, __METHOD__));
|
||||
}
|
||||
}else{
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_CCP_SSO_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $characterData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all available Endpoints
|
||||
* @param $accessToken
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function getEndpoints($accessToken){
|
||||
$crestUrl = self::getCrestEndpoint();
|
||||
$contentType = 'application/vnd.ccp.eve.Api-v3+json';
|
||||
$endpoint = $this->getEndpoint($accessToken, $crestUrl, $contentType);
|
||||
|
||||
return $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a specific endpoint by its $resourceUrl
|
||||
* @param $accessToken
|
||||
* @param $resourceUrl
|
||||
* @param string $contentType
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function getEndpoint($accessToken, $resourceUrl, $contentType = ''){
|
||||
$resourceUrlParts = parse_url($resourceUrl);
|
||||
$endpoint = null;
|
||||
|
||||
if($resourceUrlParts){
|
||||
$requestOptions = [
|
||||
'timeout' => self::CREST_TIMEOUT,
|
||||
'method' => 'GET',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Host: login.eveonline.com',
|
||||
'Host: ' . $resourceUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
// if specific contentType is required -> add it to request header
|
||||
// CREST versioning can be done by calling different "Accept:" Headers
|
||||
if( !empty($contentType) ){
|
||||
$requestOptions['header'][] = 'Accept: ' . $contentType;
|
||||
}
|
||||
|
||||
$apiResponse = Lib\Web::instance()->request($resourceUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['headers']){
|
||||
// check headers for error
|
||||
$this->checkResponseHeaders($apiResponse['headers'], $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$endpoint = json_decode($apiResponse['body'], true);
|
||||
}else{
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_GET_ENDPOINT, __METHOD__));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_CCP_CREST_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively walk down the CREST API tree by a given $path array
|
||||
* -> return "leaf" endpoint
|
||||
* @param $accessToken
|
||||
* @param $endpoint
|
||||
* @param array $path
|
||||
* @return null|string
|
||||
*/
|
||||
protected function walkEndpoint($accessToken, $endpoint, $path = []){
|
||||
$targetEndpoint = null;
|
||||
|
||||
if( !empty($path) ){
|
||||
$newNode = array_shift($path);
|
||||
if(isset($endpoint[$newNode])){
|
||||
$currentEndpoint = $endpoint[$newNode];
|
||||
if(isset($currentEndpoint['href'])){
|
||||
$newEndpoint = $this->getEndpoint($accessToken, $currentEndpoint['href']);
|
||||
$targetEndpoint = $this->walkEndpoint($accessToken, $newEndpoint, $path);
|
||||
}else{
|
||||
// leaf found
|
||||
$targetEndpoint = $currentEndpoint;
|
||||
}
|
||||
}else{
|
||||
// endpoint not found
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_FIND_ENDPOINT, $newNode));
|
||||
}
|
||||
}else{
|
||||
$targetEndpoint = $endpoint;
|
||||
}
|
||||
|
||||
return $targetEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* get character data
|
||||
* @param $accessToken
|
||||
* @return array
|
||||
*/
|
||||
protected function getCharacterData($accessToken){
|
||||
$endpoints = $this->getEndpoints($accessToken);
|
||||
$characterData = (object) [];
|
||||
|
||||
$endpoint = $this->walkEndpoint($accessToken, $endpoints, [
|
||||
'decode',
|
||||
'character'
|
||||
]);
|
||||
|
||||
if( !empty($endpoint) ){
|
||||
$characterData->character = (new Mapper\CrestCharacter($endpoint))->getData();
|
||||
if(isset($endpoint['corporation'])){
|
||||
$characterData->corporation = (new Mapper\CrestCorporation($endpoint['corporation']))->getData();
|
||||
}
|
||||
}
|
||||
|
||||
return $characterData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current character location data
|
||||
* -> solarSystem data where character is currently active
|
||||
* @param $accessToken
|
||||
* @return object
|
||||
*/
|
||||
public function getCharacterLocationData($accessToken){
|
||||
$endpoints = $this->getEndpoints($accessToken);
|
||||
$locationData = (object) [];
|
||||
|
||||
$endpoint = $this->walkEndpoint($accessToken, $endpoints, [
|
||||
'decode',
|
||||
'character',
|
||||
'location'
|
||||
]);
|
||||
|
||||
if( !empty($endpoint) ){
|
||||
if(isset($endpoint['solarSystem'])){
|
||||
$locationData->system = (new Mapper\CrestSystem($endpoint['solarSystem']))->getData();
|
||||
}
|
||||
}
|
||||
|
||||
return $locationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* update character
|
||||
* @param $characterData
|
||||
* @return \Model\CharacterModel
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function updateCharacter($characterData){
|
||||
|
||||
$characterModel = null;
|
||||
$corporationModel = null;
|
||||
$allianceModel = null;
|
||||
|
||||
if( isset($characterData->corporation) ){
|
||||
/**
|
||||
* @var Model\CorporationModel $corporationModel
|
||||
*/
|
||||
$corporationModel = Model\BasicModel::getNew('CorporationModel');
|
||||
$corporationModel->getById($characterData->corporation['id'], 0);
|
||||
$corporationModel->copyfrom($characterData->corporation);
|
||||
$corporationModel->save();
|
||||
}
|
||||
|
||||
if( isset($characterData->alliance) ){
|
||||
/**
|
||||
* @var Model\AllianceModel $allianceModel
|
||||
*/
|
||||
$allianceModel = Model\BasicModel::getNew('AllianceModel');
|
||||
$allianceModel->getById($characterData->alliance['id'], 0);
|
||||
$allianceModel->copyfrom($characterData->alliance);
|
||||
$allianceModel->save();
|
||||
}
|
||||
|
||||
if( isset($characterData->character) ){
|
||||
/**
|
||||
* @var Model\CharacterModel $characterModel
|
||||
*/
|
||||
$characterModel = Model\BasicModel::getNew('CharacterModel');
|
||||
$characterModel->getById($characterData->character['id'], 0);
|
||||
$characterModel->copyfrom($characterData->character);
|
||||
$characterModel->corporationId = $corporationModel;
|
||||
$characterModel->allianceId = $allianceModel;
|
||||
$characterModel = $characterModel->save();
|
||||
}
|
||||
|
||||
return $characterModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* check response "Header" data for errors
|
||||
* @param $headers
|
||||
* @param string $requestUrl
|
||||
* @param string $contentType
|
||||
*/
|
||||
protected function checkResponseHeaders($headers, $requestUrl = '', $contentType = ''){
|
||||
$headers = (array)$headers;
|
||||
if(preg_grep ('/^X-Deprecated/i', $headers)){
|
||||
self::getCrestLogger()->write(sprintf(self::ERROR_RESOURCE_DEPRECATED, $requestUrl, $contentType));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get "Authorization:" Header data
|
||||
* -> This header is required for any Auth-required endpoints!
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthorizationHeader(){
|
||||
return base64_encode(
|
||||
Controller\Controller::getEnvironmentData('SSO_CCP_CLIENT_ID') . ':'
|
||||
. Controller\Controller::getEnvironmentData('SSO_CCP_SECRET_KEY')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get CCP CREST url from configuration file
|
||||
* -> throw error if url is broken/missing
|
||||
* @return string
|
||||
*/
|
||||
static function getCrestEndpoint(){
|
||||
$url = '';
|
||||
if( \Audit::instance()->url(self::getEnvironmentData('CCP_CREST_URL')) ){
|
||||
$url = self::getEnvironmentData('CCP_CREST_URL');
|
||||
}else{
|
||||
$error = sprintf(self::ERROR_CCP_CREST_URL, __METHOD__);
|
||||
self::getCrestLogger()->write($error);
|
||||
\Base::instance()->error(502, $error);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* get CCP SSO url from configuration file
|
||||
* -> throw error if url is broken/missing
|
||||
* @return string
|
||||
*/
|
||||
static function getSsoUrlRoot(){
|
||||
$url = '';
|
||||
if( \Audit::instance()->url(self::getEnvironmentData('SSO_CCP_URL')) ){
|
||||
$url = self::getEnvironmentData('SSO_CCP_URL');
|
||||
}else{
|
||||
$error = sprintf(self::ERROR_CCP_SSO_URL, __METHOD__);
|
||||
self::getCrestLogger()->write($error);
|
||||
\Base::instance()->error(502, $error);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
static function getAuthorizationEndpoint(){
|
||||
return self::getSsoUrlRoot() . '/oauth/authorize';
|
||||
}
|
||||
|
||||
static function getVerifyAuthorizationCodeEndpoint(){
|
||||
return self::getSsoUrlRoot() . '/oauth/token';
|
||||
}
|
||||
|
||||
static function getVerifyUserEndpoint(){
|
||||
return self::getSsoUrlRoot() . '/oauth/verify';
|
||||
}
|
||||
|
||||
/**
|
||||
* get logger for CREST logging
|
||||
* @return \Log
|
||||
*/
|
||||
static function getCrestLogger(){
|
||||
return parent::getLogger('crest');
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: exodus4d
|
||||
* Date: 28.03.15
|
||||
* Time: 17:01
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
use Model;
|
||||
|
||||
/**
|
||||
* CCP API controller
|
||||
* Class CcpApiController
|
||||
* @package Controller
|
||||
*/
|
||||
class CcpApiController extends Controller{
|
||||
|
||||
/**
|
||||
* get HTTP request options for API (curl) request
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequestOptions(){
|
||||
$requestOptions = [
|
||||
'timeout' => 8,
|
||||
'method' => 'POST',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'follow_location' => false // otherwise CURLOPT_FOLLOWLOCATION will fail
|
||||
];
|
||||
|
||||
return $requestOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* request character information from CCP API
|
||||
* @param $keyID
|
||||
* @param $vCode
|
||||
* @return bool|\SimpleXMLElement
|
||||
*/
|
||||
public function requestCharacters($keyID, $vCode){
|
||||
|
||||
$apiPath = $this->getF3()->get('PATHFINDER.API.CCP_XML') . '/account/APIKeyInfo.xml.aspx';
|
||||
|
||||
$xml = false;
|
||||
|
||||
// build request URL
|
||||
$options = $this->getRequestOptions();
|
||||
$options['content'] = http_build_query( [
|
||||
'keyID' => $keyID,
|
||||
'vCode' => $vCode
|
||||
]);
|
||||
|
||||
$apiResponse = \Web::instance()->request($apiPath, $options );
|
||||
|
||||
if($apiResponse['body']){
|
||||
$xml = simplexml_load_string($apiResponse['body']);
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* update all character information for a given apiModel
|
||||
* @param $userApiModel
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function updateCharacters($userApiModel){
|
||||
|
||||
$xml = $this->requestCharacters($userApiModel->keyId, $userApiModel->vCode);
|
||||
|
||||
$characterCount = 0;
|
||||
|
||||
// important -> user API model must be up2date
|
||||
// if not -> matched userCharacter cant be found
|
||||
$userApiModel->getById($userApiModel->id, 0);
|
||||
|
||||
if($xml){
|
||||
// request successful
|
||||
$rowApiData = $xml->result->key->rowset;
|
||||
|
||||
if(
|
||||
is_object($rowApiData) &&
|
||||
$rowApiData->children()
|
||||
){
|
||||
$characterModel = Model\BasicModel::getNew('CharacterModel');
|
||||
$corporationModel = Model\BasicModel::getNew('CorporationModel');
|
||||
$allianceModel = Model\BasicModel::getNew('AllianceModel');
|
||||
|
||||
foreach($rowApiData->children() as $characterApiData){
|
||||
// map attributes to array
|
||||
$attributeData = current( $characterApiData->attributes() );
|
||||
|
||||
$newCharacter = true;
|
||||
|
||||
$characterId = (int)$attributeData['characterID'];
|
||||
$characterModel->getById($characterId, 0);
|
||||
|
||||
$corporationModelTemp = null;
|
||||
$allianceModelTemp = null;
|
||||
|
||||
// check if corporation already exists
|
||||
if($attributeData['corporationID'] > 0){
|
||||
$corporationModel->getById($attributeData['corporationID'], 0);
|
||||
if( $corporationModel->dry() ){
|
||||
$corporationModel->id = $attributeData['corporationID'];
|
||||
$corporationModel->name = $attributeData['corporationName'];
|
||||
$corporationModel->save();
|
||||
}
|
||||
$corporationModelTemp = $corporationModel;
|
||||
}
|
||||
|
||||
// check if alliance already exists
|
||||
if($attributeData['allianceID'] > 0){
|
||||
$allianceModel->getById($attributeData['allianceID'], 0);
|
||||
if( $allianceModel->dry() ){
|
||||
$allianceModel->id = $attributeData['allianceID'];
|
||||
$allianceModel->name = $attributeData['allianceName'];
|
||||
$allianceModel->save();
|
||||
}
|
||||
$allianceModelTemp = $allianceModel;
|
||||
}
|
||||
|
||||
if($userApiModel->userCharacters){
|
||||
$userApiModel->userCharacters->rewind();
|
||||
while($userApiModel->userCharacters->valid()){
|
||||
$tempCharacterModel = $userApiModel->userCharacters->current()->getCharacter();
|
||||
|
||||
// character already exists -> update
|
||||
if($tempCharacterModel->id == $characterId){
|
||||
$characterModel = $tempCharacterModel;
|
||||
|
||||
// unset userCharacter -> all leftover models are no longer part of this API
|
||||
// --> delete leftover models at the end
|
||||
$userApiModel->userCharacters->offsetUnset($userApiModel->userCharacters->key());
|
||||
|
||||
$newCharacter = false;
|
||||
break;
|
||||
}else{
|
||||
$userApiModel->userCharacters->next();
|
||||
}
|
||||
}
|
||||
$userApiModel->userCharacters->rewind();
|
||||
}
|
||||
|
||||
$characterModel->id = $characterId;
|
||||
$characterModel->name = $attributeData['characterName'];
|
||||
$characterModel->corporationId = $corporationModelTemp;
|
||||
$characterModel->allianceId = $allianceModelTemp;
|
||||
$characterModel->factionId = $attributeData['factionID'];
|
||||
$characterModel->factionName = $attributeData['factionName'];
|
||||
$characterModel->save();
|
||||
|
||||
if($newCharacter){
|
||||
// new character for this API
|
||||
$userCharactersModel = Model\BasicModel::getNew('UserCharacterModel', 0);
|
||||
$userCharactersModel->userId = $userApiModel->userId;
|
||||
$userCharactersModel->apiId = $userApiModel;
|
||||
$userCharactersModel->characterId = $characterModel;
|
||||
$userCharactersModel->save();
|
||||
}
|
||||
|
||||
$corporationModel->reset();
|
||||
$allianceModel->reset();
|
||||
$characterModel->reset();
|
||||
|
||||
$characterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// delete leftover userCharacters from this API
|
||||
if(count($userApiModel->userCharacters) > 0){
|
||||
while($userApiModel->userCharacters->valid()){
|
||||
$userApiModel->userCharacters->current()->erase();
|
||||
$userApiModel->userCharacters->next();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $characterCount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,503 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 23.01.2016
|
||||
* Time: 17:18
|
||||
*
|
||||
* Handles access to EVE-Online "CREST API" and "SSO" auth functions
|
||||
* - Add your API credentials in "environment.ini"
|
||||
* - Check "PATHFINDER.API" in "pathfinder.ini" for correct API URLs
|
||||
* Hint: \Web::instance()->request automatically caches responses by their response "Cache-Control" header!
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
use Data\Mapper as Mapper;
|
||||
use Model;
|
||||
|
||||
class CcpSsoController extends Controller {
|
||||
|
||||
const SESSION_KEY_ACCESS_TOKEN = 'SESSION.sso.access_token';
|
||||
const SESSION_KEY_REFRESH_TOKEN = 'SESSION.sso.refresh_token';
|
||||
|
||||
const ERROR_CCP_SSO_URL = 'Invalid "PATHFINDER.API.CCP_SSO" url. %s';
|
||||
const ERROR_CCP_CREST_URL = 'Invalid "PATHFINDER.API.CCP_CREST" url. %s';
|
||||
const ERROR_RESOURCE_DEPRECATED = 'Resource: %s has been marked deprecated. %s';
|
||||
const ERROR_ACCESS_TOKEN = 'Unable to get a valid "access_token. %s';
|
||||
const ERROR_VERIFY_CHARACTER = 'Unable to verify character data. %s';
|
||||
const ERROR_GET_ENDPOINTS = 'Unable to get endpoints data. $s';
|
||||
const ERROR_GET_ENDPOINT = 'Unable to get endpoint data. $s';
|
||||
const ERROR_FIND_ENDPOINT = 'Unable to find endpoint: %s';
|
||||
|
||||
/**
|
||||
* "Scopes" that are used by pathfinder
|
||||
* -> Enable scopes: https://developers.eveonline.com
|
||||
* @var array
|
||||
*/
|
||||
private $requestScopes = [
|
||||
'characterLocationRead',
|
||||
'characterNavigationWrite'
|
||||
];
|
||||
|
||||
/**
|
||||
* timeout for API calls
|
||||
* @var int
|
||||
*/
|
||||
private $apiTimeout = 3;
|
||||
|
||||
/**
|
||||
* redirect user to CCP SSO page and request authorization
|
||||
* @param $f3
|
||||
*/
|
||||
public function requestAuthorization($f3){
|
||||
// used for state check between request and callback
|
||||
$state = bin2hex(mcrypt_create_iv(12, MCRYPT_DEV_URANDOM));
|
||||
$f3->set('SESSION.sso.state', $state);
|
||||
|
||||
$urlParams = [
|
||||
'response_type' => 'code',
|
||||
'redirect_uri' => Controller::getEnvironmentData('URL') . $f3->build('/sso/callbackAuthorization'),
|
||||
'client_id' => Controller::getEnvironmentData('SSO_CCP_CLIENT_ID'),
|
||||
'scope' => implode(' ', $this->requestScopes),
|
||||
'state' => $state
|
||||
];
|
||||
|
||||
$ssoAuthUrl = self::getAuthorizationEndpoint() . '?' . http_build_query($urlParams, '', '&', PHP_QUERY_RFC3986 );
|
||||
|
||||
$f3->status(302);
|
||||
$f3->reroute($ssoAuthUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* callback handler for CCP SSO user Auth
|
||||
* -> see requestAuthorization()
|
||||
* @param $f3
|
||||
*/
|
||||
public function callbackAuthorization($f3){
|
||||
$getParams = (array)$f3->get('GET');
|
||||
|
||||
if($f3->exists('SESSION.sso.state')){
|
||||
// check response and validate 'state'
|
||||
if(
|
||||
isset($getParams['code']) &&
|
||||
isset($getParams['state']) &&
|
||||
!empty($getParams['code']) &&
|
||||
!empty($getParams['state']) &&
|
||||
$f3->get('SESSION.sso.state') === $getParams['state']
|
||||
){
|
||||
|
||||
// clear 'state' for new next request
|
||||
$f3->clear('SESSION.sso.state');
|
||||
|
||||
$accessToken = $this->getAccessToken($getParams['code']);
|
||||
if($accessToken){
|
||||
$data = $this->verifyCharacterData($accessToken);
|
||||
|
||||
$characterData = $this->getCharacterData($accessToken);
|
||||
$characterModel = $this->updateCharacter($characterData);
|
||||
|
||||
if( !is_null($characterModel) ){
|
||||
// everything OK -> login succeeded
|
||||
var_dump( $characterModel->cast() );
|
||||
die();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// on error -> route back to login form
|
||||
$this->getF3()->reroute('@login');
|
||||
}
|
||||
|
||||
/**
|
||||
* get a valid "access_token" for oAuth 2.0 verification
|
||||
* -> if $authCode is set -> request NEW "access_token"
|
||||
* -> else check for existing (not expired) "access_token"
|
||||
* -> else try to refresh auth and get fresh "access_token"
|
||||
* @param bool $authCode
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function getAccessToken($authCode = false){
|
||||
$accessToken = false;
|
||||
|
||||
if( !empty($authCode) ){
|
||||
// Authentication Code is set -> request new Access Token -------------------------------------------------
|
||||
|
||||
// clear "old" token (if exist and still valid)
|
||||
$this->getF3()->clear(self::SESSION_KEY_ACCESS_TOKEN);
|
||||
|
||||
$accessToken = $this->verifyAuthorizationCode($authCode);
|
||||
}elseif($this->getF3()->exists(self::SESSION_KEY_ACCESS_TOKEN)){
|
||||
// Access Token exists and not expired --------------------------------------------------------------------
|
||||
$accessToken = $this->getF3()->get(self::SESSION_KEY_ACCESS_TOKEN);
|
||||
}elseif($this->getF3()->exists(self::SESSION_KEY_REFRESH_TOKEN)){
|
||||
// Refresh Token exists -> refresh Access Token -----------------------------------------------------------
|
||||
$accessToken = $this->refreshAccessToken($this->getF3()->get(self::SESSION_KEY_REFRESH_TOKEN));
|
||||
}else{
|
||||
// Unable to get Token -> trigger error -------------------------------------------------------------------
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_ACCESS_TOKEN, $authCode));
|
||||
}
|
||||
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify authorization code, and get an "access_token" data
|
||||
* @param $authCode
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function verifyAuthorizationCode($authCode){
|
||||
$requestParams = [
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $authCode
|
||||
];
|
||||
|
||||
return $this->requestAccessToken($requestParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* get new "access_token" by an existing "refresh_token"
|
||||
* -> if "access_token" is expired, this function gets a fresh one
|
||||
* @param $refreshToken
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function refreshAccessToken($refreshToken){
|
||||
$requestParams = [
|
||||
'grant_type' => 'refresh_token',
|
||||
'refresh_token' => $refreshToken
|
||||
];
|
||||
|
||||
return $this->requestAccessToken($requestParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* request an "access_token" AND "refresh_token" data
|
||||
* -> this can either be done by sending a valid "authorization code"
|
||||
* OR by providing a valid "refresh_token"
|
||||
* @param $requestParams
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function requestAccessToken($requestParams){
|
||||
$verifyAuthCodeUrl = self::getVerifyAuthorizationCodeEndpoint();
|
||||
$verifyAuthCodeUrlParts = parse_url($verifyAuthCodeUrl);
|
||||
$accessToken = false;
|
||||
|
||||
if($verifyAuthCodeUrlParts){
|
||||
$contentType = 'application/x-www-form-urlencoded';
|
||||
$requestOptions = [
|
||||
'timeout' => $this->apiTimeout,
|
||||
'method' => 'POST',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Basic ' . $this->getAuthorizationHeader(),
|
||||
'Content-Type: ' . $contentType,
|
||||
'Host: ' . $verifyAuthCodeUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
// content (parameters to send with)
|
||||
$requestOptions['content'] = http_build_query($requestParams);
|
||||
|
||||
$apiResponse = \Web::instance()->request($verifyAuthCodeUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$authCodeRequestData = json_decode($apiResponse['body']);
|
||||
|
||||
if(property_exists($authCodeRequestData, 'refresh_token')){
|
||||
// this token is used to refresh/get a new access_token when expires
|
||||
$this->getF3()->set(self::SESSION_KEY_REFRESH_TOKEN, $authCodeRequestData->refresh_token);
|
||||
}
|
||||
|
||||
if(property_exists($authCodeRequestData, 'access_token')){
|
||||
// this token is required for endpoints that require Auth
|
||||
$accessToken = $this->getF3()->set(self::SESSION_KEY_ACCESS_TOKEN, $authCodeRequestData->access_token);
|
||||
}
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_ACCESS_TOKEN, print_r($requestParams, true)));
|
||||
}
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_CCP_SSO_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* verify character data by "access_token"
|
||||
* -> get some basic information (like character id)
|
||||
* -> if more character information is required, use CREST endpoints request instead
|
||||
* @param $accessToken
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function verifyCharacterData($accessToken){
|
||||
$verifyUserUrl = self::getVerifyUserEndpoint();
|
||||
$verifyUrlParts = parse_url($verifyUserUrl);
|
||||
$characterData = false;
|
||||
|
||||
if($verifyUrlParts){
|
||||
$requestOptions = [
|
||||
'timeout' => $this->apiTimeout,
|
||||
'method' => 'GET',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Host: ' . $verifyUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
$apiResponse = \Web::instance()->request($verifyUserUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$characterData = json_decode($apiResponse['body']);
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_VERIFY_CHARACTER, __METHOD__));
|
||||
}
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_CCP_SSO_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $characterData;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all available Endpoints
|
||||
* @param $accessToken
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function getEndpoints($accessToken){
|
||||
$crestUrl = self::getCrestEndpoint();
|
||||
$endpointsData = false;
|
||||
$crestUrlParts = parse_url($crestUrl);
|
||||
|
||||
if($crestUrlParts){
|
||||
// represents API version
|
||||
$contentType = 'application/vnd.ccp.eve.Api-v3+json';
|
||||
$requestOptions = [
|
||||
'timeout' => $this->apiTimeout,
|
||||
'method' => 'GET',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Accept: ' . $contentType,
|
||||
'Host: ' . $crestUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
$apiResponse = \Web::instance()->request($crestUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['headers']){
|
||||
// check headers for error
|
||||
$this->checkResponseHeaders($apiResponse['headers'], $crestUrl, $contentType);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$endpointsData = json_decode($apiResponse['body'], true);
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_GET_ENDPOINTS, __METHOD__));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_CCP_CREST_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $endpointsData;
|
||||
}
|
||||
|
||||
private function walkEndpoint($accessToken, $endpoint, $path = []){
|
||||
$targetEndpoint = null;
|
||||
|
||||
|
||||
if( !empty($path) ){
|
||||
$newNode = array_shift($path);
|
||||
|
||||
if(isset($endpoint[$newNode])){
|
||||
$currentEndpoint = $endpoint[$newNode];
|
||||
if(isset($currentEndpoint['href'])){
|
||||
$newEndpoint = $this->getEndpoint($accessToken, $currentEndpoint['href']);
|
||||
$targetEndpoint = $this->walkEndpoint($accessToken, $newEndpoint, $path);
|
||||
|
||||
}else{
|
||||
// TODO leaf
|
||||
$targetEndpoint = ' target:) ';
|
||||
}
|
||||
}else{
|
||||
// endpoint not found
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_FIND_ENDPOINT, $newNode));
|
||||
}
|
||||
}else{
|
||||
$targetEndpoint = $endpoint;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $targetEndpoint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get a specific endpoint by its $resourceUrl
|
||||
* @param $accessToken
|
||||
* @param $resourceUrl
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function getEndpoint($accessToken, $resourceUrl){
|
||||
$resourceUrlParts = parse_url($resourceUrl);
|
||||
$endpoint = null;
|
||||
|
||||
if($resourceUrlParts){
|
||||
$requestOptions = [
|
||||
'timeout' => $this->apiTimeout,
|
||||
'method' => 'GET',
|
||||
'user_agent' => $this->getUserAgent(),
|
||||
'header' => [
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
'Host: login.eveonline.com',
|
||||
'Host: ' . $resourceUrlParts['host']
|
||||
]
|
||||
];
|
||||
|
||||
$apiResponse = \Web::instance()->request($resourceUrl, $requestOptions);
|
||||
|
||||
if($apiResponse['headers']){
|
||||
// check headers for error
|
||||
$this->checkResponseHeaders($apiResponse['headers'], $requestOptions);
|
||||
|
||||
if($apiResponse['body']){
|
||||
$endpoint = json_decode($apiResponse['body'], true);
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_GET_ENDPOINT, __METHOD__));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_CCP_CREST_URL, __METHOD__));
|
||||
}
|
||||
|
||||
return $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* get character data
|
||||
* @param $accessToken
|
||||
* @return array
|
||||
*/
|
||||
private function getCharacterData($accessToken){
|
||||
$endpoints = $this->getEndpoints($accessToken);
|
||||
$characterData = [];
|
||||
|
||||
$endpoint = $this->walkEndpoint($accessToken, $endpoints, [
|
||||
'decode',
|
||||
'character'
|
||||
]);
|
||||
|
||||
if( !empty($endpoint) ){
|
||||
$characterData['character'] = (new Mapper\CrestCharacter($endpoint))->getData();
|
||||
|
||||
if(isset($endpoint['corporation'])){
|
||||
$characterData['corporation'] = (new Mapper\CrestCorporation($endpoint['corporation']))->getData();
|
||||
}
|
||||
}
|
||||
|
||||
return $characterData;
|
||||
}
|
||||
|
||||
/*
|
||||
private function getCharacterLocation($accessToken){
|
||||
$endpoints = $this->getEndpoints($accessToken);
|
||||
$endpoint = $this->walkEndpoint($accessToken, $endpoints, [
|
||||
'decode',
|
||||
'character',
|
||||
'location'
|
||||
]);
|
||||
|
||||
var_dump($endpoint);
|
||||
|
||||
die(' END getCharacterLocation() ');
|
||||
|
||||
|
||||
$characterData = [];
|
||||
return $characterData;
|
||||
} */
|
||||
|
||||
/**
|
||||
* update character
|
||||
* @param $characterData
|
||||
* @return \Model\CharacterModel
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function updateCharacter($characterData){
|
||||
|
||||
$characterModel = null;
|
||||
$corporationModel = null;
|
||||
$allianceModel = null;
|
||||
|
||||
if( !empty($characterData['corporation']) ){
|
||||
$corporationModel = Model\BasicModel::getNew('CorporationModel');
|
||||
$corporationModel->getById($characterData['corporation']['id'], 0);
|
||||
$corporationModel->copyfrom($characterData['corporation']);
|
||||
$corporationModel->save();
|
||||
}
|
||||
|
||||
if( !empty($characterData['alliance']) ){
|
||||
$allianceModel = Model\BasicModel::getNew('AllianceModel');
|
||||
$allianceModel->getById($characterData['alliance']['id'], 0);
|
||||
$allianceModel->copyfrom($characterData['alliance']);
|
||||
$allianceModel->save();
|
||||
}
|
||||
|
||||
if( !empty($characterData['character']) ){
|
||||
$characterModel = Model\BasicModel::getNew('CharacterModel');
|
||||
$characterModel->getById($characterData['character']['id'], 0);
|
||||
$characterModel->copyfrom($characterData['character']);
|
||||
$characterModel->corporationId = $corporationModel;
|
||||
$characterModel->allianceId = $allianceModel;
|
||||
$characterModel->save();
|
||||
}
|
||||
|
||||
return $characterModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* check response "Header" data for errors
|
||||
* @param $headers
|
||||
* @param string $requestUrl
|
||||
* @param string $contentType
|
||||
*/
|
||||
private function checkResponseHeaders($headers, $requestUrl = '', $contentType = ''){
|
||||
$headers = (array)$headers;
|
||||
if(preg_grep ('/^X-Deprecated/i', $headers)){
|
||||
$this->getLogger('error')->write(sprintf(self::ERROR_RESOURCE_DEPRECATED, $requestUrl, $contentType));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get "Authorization:" Header data
|
||||
* -> This header is required for any Auth-required endpoints!
|
||||
* @return string
|
||||
*/
|
||||
private function getAuthorizationHeader(){
|
||||
return base64_encode(
|
||||
Controller::getEnvironmentData('SSO_CCP_CLIENT_ID') . ':'
|
||||
. Controller::getEnvironmentData('SSO_CCP_SECRET_KEY')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static function getAuthorizationEndpoint(){
|
||||
return \Base::instance()->get('PATHFINDER.API.CCP_SSO') . '/oauth/authorize';
|
||||
}
|
||||
|
||||
static function getVerifyAuthorizationCodeEndpoint(){
|
||||
return \Base::instance()->get('PATHFINDER.API.CCP_SSO') . '/oauth/token';
|
||||
}
|
||||
|
||||
static function getVerifyUserEndpoint(){
|
||||
return \Base::instance()->get('PATHFINDER.API.CCP_SSO') . '/oauth/verify';
|
||||
}
|
||||
|
||||
static function getCrestEndpoint(){
|
||||
return \Base::instance()->get('PATHFINDER.API.CCP_CREST');
|
||||
}
|
||||
}
|
||||
@@ -7,50 +7,62 @@
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
use Controller\Api as Api;
|
||||
use Model;
|
||||
use DB;
|
||||
|
||||
class Controller {
|
||||
|
||||
/**
|
||||
* @var \Base
|
||||
*/
|
||||
protected $f3;
|
||||
private $template;
|
||||
|
||||
/**
|
||||
* @param mixed $template
|
||||
* @var string template for render
|
||||
*/
|
||||
public function setTemplate($template){
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* @param string $template
|
||||
*/
|
||||
protected function setTemplate($template){
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplate(){
|
||||
protected function getTemplate(){
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* set global f3 instance
|
||||
* @param null $f3
|
||||
* @return null|static
|
||||
* set $f3 base object
|
||||
* @param \Base $f3
|
||||
*/
|
||||
protected function getF3($f3 = null){
|
||||
if(is_object($f3)){
|
||||
$this->f3 = $f3;
|
||||
}else{
|
||||
$this->f3 = \Base::instance();
|
||||
}
|
||||
protected function setF3(\Base $f3){
|
||||
$this->f3 = $f3;
|
||||
}
|
||||
|
||||
/**
|
||||
* get $f3 base object
|
||||
* @return \Base
|
||||
*/
|
||||
protected function getF3(){
|
||||
if( !($this->f3 instanceof \Base) ){
|
||||
$this->setF3( \Base::instance() );
|
||||
}
|
||||
return $this->f3;
|
||||
}
|
||||
|
||||
/**
|
||||
* event handler for all "views"
|
||||
* some global template variables are set in here
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
$this->getF3($f3);
|
||||
function beforeroute(\Base $f3) {
|
||||
$this->setF3($f3);
|
||||
|
||||
// initiate DB connection
|
||||
DB\Database::instance('PF');
|
||||
@@ -73,8 +85,9 @@ class Controller {
|
||||
/**
|
||||
* event handler after routing
|
||||
* -> render view
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function afterroute($f3){
|
||||
public function afterroute(\Base $f3){
|
||||
if($this->getTemplate()){
|
||||
// Ajax calls don´t need a page render..
|
||||
// this happens on client side
|
||||
@@ -85,7 +98,7 @@ class Controller {
|
||||
/**
|
||||
* set change the DB connection
|
||||
* @param string $database
|
||||
* @return mixed|void
|
||||
* @return DB\SQL
|
||||
*/
|
||||
protected function getDB($database = 'PF'){
|
||||
return DB\Database::instance()->getDB($database);
|
||||
@@ -96,49 +109,47 @@ class Controller {
|
||||
*/
|
||||
protected function initSession(){
|
||||
// init DB Session (not file based)
|
||||
if( $this->getDB('PF') instanceof \DB\SQL){
|
||||
new \DB\SQL\Session($this->getDB('PF'));
|
||||
if( $this->getDB('PF') instanceof DB\SQL){
|
||||
new DB\SQL\Session($this->getDB('PF'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get current user model
|
||||
* get current character model
|
||||
* @param int $ttl
|
||||
* @return bool|null
|
||||
* @return Model\CharacterModel|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _getUser($ttl = 5){
|
||||
$user = false;
|
||||
public function getCharacter($ttl = 5){
|
||||
$character = null;
|
||||
|
||||
if( $this->f3->exists('SESSION.user.id') ){
|
||||
$userId = (int)$this->f3->get('SESSION.user.id');
|
||||
if( $this->getF3()->exists(Api\User::SESSION_KEY_CHARACTER_ID) ){
|
||||
$characterId = (int)$this->getF3()->get(Api\User::SESSION_KEY_CHARACTER_ID);
|
||||
if($characterId){
|
||||
/**
|
||||
* @var $characterModel \Model\CharacterModel
|
||||
*/
|
||||
$characterModel = Model\BasicModel::getNew('CharacterModel');
|
||||
$characterModel->getById($characterId, $ttl);
|
||||
|
||||
if($userId > 0){
|
||||
$userModel = Model\BasicModel::getNew('UserModel', $ttl);
|
||||
$userModel->getById($userId, $ttl);
|
||||
|
||||
if( !$userModel->dry() ){
|
||||
$user = $userModel;
|
||||
if( !$characterModel->dry() ){
|
||||
$character = &$characterModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
return $character;
|
||||
}
|
||||
|
||||
/**
|
||||
* log the current user out
|
||||
* @param $f3
|
||||
* log out current user
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function logOut($f3){
|
||||
|
||||
public function logOut(\Base $f3){
|
||||
// destroy session
|
||||
$f3->clear('SESSION');
|
||||
|
||||
if( !$f3->get('AJAX') ){
|
||||
// redirect to landing page
|
||||
$f3->reroute('@login');
|
||||
}else{
|
||||
if( $f3->get('AJAX') ){
|
||||
$params = $f3->get('POST');
|
||||
$return = (object) [];
|
||||
if(
|
||||
@@ -148,33 +159,36 @@ class Controller {
|
||||
$return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $f3->alias('login');
|
||||
}else{
|
||||
// no reroute -> errors can be shown
|
||||
$return->error[] = $this->getUserLoggedOffError();
|
||||
$return->error[] = $this->getLogoutError();
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
die();
|
||||
}else{
|
||||
// redirect to landing page
|
||||
$f3->reroute('@login');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* verifies weather a given username and password is valid
|
||||
* @param $userName
|
||||
* @param $password
|
||||
* @param string $userName
|
||||
* @param string $password
|
||||
* @return Model\UserModel|null
|
||||
*/
|
||||
protected function _verifyUser($userName, $password) {
|
||||
|
||||
$validUser = null;
|
||||
|
||||
/**
|
||||
* @var $user \Model\UserModel
|
||||
*/
|
||||
$user = Model\BasicModel::getNew('UserModel', 0);
|
||||
|
||||
$user->getByName($userName);
|
||||
|
||||
// check userName is valid
|
||||
if( !$user->dry() ){
|
||||
// check if password is valid
|
||||
$isValid = $user->verify($password);
|
||||
|
||||
if($isValid === true){
|
||||
$validUser = $user;
|
||||
}
|
||||
@@ -185,18 +199,16 @@ class Controller {
|
||||
|
||||
/**
|
||||
* check weather the page is IGB trusted or not
|
||||
* @return mixed
|
||||
* @return boolean
|
||||
*/
|
||||
static function isIGBTrusted(){
|
||||
|
||||
$igbHeaderData = self::getIGBHeaderData();
|
||||
|
||||
return $igbHeaderData->trusted;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all eve IGB specific header data
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
static function getIGBHeaderData(){
|
||||
$data = (object) [];
|
||||
@@ -229,7 +241,6 @@ class Controller {
|
||||
/**
|
||||
* Helper function to return all headers because
|
||||
* getallheaders() is not available under nginx
|
||||
*
|
||||
* @return array (string $key -> string $value)
|
||||
*/
|
||||
static function getRequestHeaders(){
|
||||
@@ -261,7 +272,7 @@ class Controller {
|
||||
/**
|
||||
* get some server information
|
||||
* @param int $ttl cache time (default: 1h)
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
static function getServerData($ttl = 3600){
|
||||
$f3 = \Base::instance();
|
||||
@@ -308,25 +319,21 @@ class Controller {
|
||||
*/
|
||||
static function isIGB(){
|
||||
$isIGB = false;
|
||||
|
||||
$igbHeaderData = self::getIGBHeaderData();
|
||||
|
||||
if(count($igbHeaderData->values) > 0){
|
||||
$isIGB = true;
|
||||
}
|
||||
|
||||
return $isIGB;
|
||||
}
|
||||
|
||||
/**
|
||||
* get error object is a user is not found/logged of
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function getUserLoggedOffError(){
|
||||
protected function getLogoutError(){
|
||||
$userError = (object) [];
|
||||
$userError->type = 'error';
|
||||
$userError->message = 'User not found';
|
||||
|
||||
return $userError;
|
||||
}
|
||||
|
||||
@@ -341,8 +348,8 @@ class Controller {
|
||||
|
||||
/**
|
||||
* get a log controller e.g. "debug"
|
||||
* @param $loggerType
|
||||
* @return mixed
|
||||
* @param string $loggerType
|
||||
* @return \Log
|
||||
*/
|
||||
static function getLogger($loggerType){
|
||||
return LogController::getLogger($loggerType);
|
||||
@@ -351,7 +358,7 @@ class Controller {
|
||||
/**
|
||||
* removes illegal characters from a Hive-key that are not allowed
|
||||
* @param $key
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
static function formatHiveKey($key){
|
||||
$illegalCharacters = ['-', ' '];
|
||||
@@ -360,8 +367,8 @@ class Controller {
|
||||
|
||||
/**
|
||||
* get environment specific configuration data
|
||||
* @param $key
|
||||
* @return mixed|null
|
||||
* @param string $key
|
||||
* @return string|null
|
||||
*/
|
||||
static function getEnvironmentData($key){
|
||||
$f3 = \Base::instance();
|
||||
@@ -378,7 +385,7 @@ class Controller {
|
||||
/**
|
||||
* get current server environment status
|
||||
* -> "DEVELOP" or "PRODUCTION"
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
static function getEnvironment(){
|
||||
$f3 = \Base::instance();
|
||||
@@ -396,7 +403,7 @@ class Controller {
|
||||
/**
|
||||
* get required MySQL variable value
|
||||
* @param $key
|
||||
* @return mixed|null
|
||||
* @return string|null
|
||||
*/
|
||||
static function getRequiredMySqlVariables($key){
|
||||
$f3 = \Base::instance();
|
||||
@@ -413,7 +420,7 @@ class Controller {
|
||||
* get a program URL by alias
|
||||
* -> if no $alias given -> get "default" route (index.php)
|
||||
* @param null $alias
|
||||
* @return bool
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function getRouteUrl($alias = null){
|
||||
$url = false;
|
||||
@@ -452,9 +459,9 @@ class Controller {
|
||||
* onError() callback function
|
||||
* -> on AJAX request -> return JSON with error information
|
||||
* -> on HTTP request -> render error page
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function showError($f3){
|
||||
public function showError(\Base $f3){
|
||||
// set HTTP status
|
||||
$errorCode = $f3->get('ERROR.code');
|
||||
if(!empty($errorCode)){
|
||||
@@ -510,8 +517,10 @@ class Controller {
|
||||
/**
|
||||
* Callback for framework "unload"
|
||||
* check -> config.ini
|
||||
* @param \Base $f3
|
||||
* @return bool
|
||||
*/
|
||||
public function unload($f3){
|
||||
public function unload(\Base $f3){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
namespace Controller;
|
||||
|
||||
class MapController extends \Controller\AccessController {
|
||||
class MapController extends AccessController {
|
||||
|
||||
/**
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function init($f3) {
|
||||
|
||||
// page title
|
||||
|
||||
@@ -36,6 +36,7 @@ class Setup extends Controller {
|
||||
'Model\ConnectionScopeModel',
|
||||
|
||||
'Model\UserMapModel',
|
||||
'Model\CharacterMapModel',
|
||||
'Model\AllianceMapModel',
|
||||
'Model\CorporationMapModel',
|
||||
|
||||
@@ -76,9 +77,9 @@ class Setup extends Controller {
|
||||
/**
|
||||
* event handler for all "views"
|
||||
* some global template variables are set in here
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
function beforeroute($f3) {
|
||||
function beforeroute(\Base $f3) {
|
||||
// page title
|
||||
$f3->set('pageTitle', 'Setup');
|
||||
|
||||
@@ -92,7 +93,7 @@ class Setup extends Controller {
|
||||
$f3->set('pathJs', 'public/js/' . $f3->get('PATHFINDER.VERSION') );
|
||||
}
|
||||
|
||||
public function afterroute($f3) {
|
||||
public function afterroute(\Base $f3) {
|
||||
// js view (file)
|
||||
$f3->set('jsView', 'setup');
|
||||
|
||||
@@ -103,7 +104,7 @@ class Setup extends Controller {
|
||||
/**
|
||||
* main setup route handler
|
||||
* works as dispatcher for setup functions
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
*/
|
||||
public function init($f3){
|
||||
$params = $f3->get('GET');
|
||||
@@ -141,7 +142,7 @@ class Setup extends Controller {
|
||||
|
||||
/**
|
||||
* get server information
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function getServerInformation($f3){
|
||||
@@ -178,7 +179,7 @@ class Setup extends Controller {
|
||||
/**
|
||||
* check all required backend requirements
|
||||
* (Fat Free Framework)
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
* @return array
|
||||
*/
|
||||
protected function checkRequirements($f3){
|
||||
@@ -288,7 +289,7 @@ class Setup extends Controller {
|
||||
|
||||
/**
|
||||
* get database connection information
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
* @param bool|false $exec
|
||||
* @return array
|
||||
*/
|
||||
@@ -413,6 +414,7 @@ class Setup extends Controller {
|
||||
$changedType = false;
|
||||
$changedUnique = false;
|
||||
$changedIndex = false;
|
||||
$addConstraints = [];
|
||||
|
||||
// set (new) column information -------------------------------------------------------
|
||||
$requiredTables[$requiredTableName]['fieldConf'][$columnName]['exists'] = true;
|
||||
@@ -427,17 +429,22 @@ class Setup extends Controller {
|
||||
$constraint = $col->newConstraint($constraintData);
|
||||
|
||||
$foreignKeyExists = $col->constraintExists($constraint);
|
||||
|
||||
// constraint information -> show in template
|
||||
$requiredTables[$requiredTableName]['foreignKeys'][] = [
|
||||
'exists' => $foreignKeyExists,
|
||||
'keyName' => $constraint->getConstraintName()
|
||||
];
|
||||
|
||||
$col->addConstraint($constraint);
|
||||
|
||||
if(!$foreignKeyExists){
|
||||
if($foreignKeyExists){
|
||||
// drop constraint and re-add again at the and, in case something has changed
|
||||
$col->dropConstraint($constraint);
|
||||
}else{
|
||||
$tableStatusCheckCount++;
|
||||
$foreignKeyStatusCheck = false;
|
||||
}
|
||||
|
||||
$addConstraints[] = $constraint;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,11 +459,21 @@ class Setup extends Controller {
|
||||
$tableStatusCheckCount++;
|
||||
}
|
||||
|
||||
// check if column unique changed -----------------------------------------------------
|
||||
// check if column index changed ------------------------------------------------------
|
||||
$indexUpdate = false;
|
||||
$indexKey = (bool)$hasIndex;
|
||||
$indexUnique = (bool)$hasUnique;
|
||||
|
||||
if($currentColIndex != $fieldConf['index']){
|
||||
$changedIndex = true;
|
||||
$columnStatusCheck = false;
|
||||
$tableStatusCheckCount++;
|
||||
|
||||
$indexUpdate = true;
|
||||
$indexKey = (bool) $fieldConf['index'];
|
||||
}
|
||||
|
||||
// check if column unique changed -----------------------------------------------------
|
||||
if($currentColIndexData['unique'] != $fieldConf['unique']){
|
||||
$changedUnique = true;
|
||||
$columnStatusCheck = false;
|
||||
@@ -466,15 +483,6 @@ class Setup extends Controller {
|
||||
$indexUnique =(bool)$fieldConf['unique'];
|
||||
}
|
||||
|
||||
// check if column index changed ------------------------------------------------------
|
||||
if($currentColIndex != $fieldConf['index']){
|
||||
$changedIndex = true;
|
||||
$columnStatusCheck = false;
|
||||
$tableStatusCheckCount++;
|
||||
|
||||
$indexUpdate = true;
|
||||
$indexKey = (bool) $fieldConf['index'];
|
||||
}
|
||||
// build table with changed columns ---------------------------------------------------
|
||||
if(!$columnStatusCheck || !$foreignKeyStatusCheck){
|
||||
|
||||
@@ -495,6 +503,12 @@ class Setup extends Controller {
|
||||
$tableModifier->updateColumn($columnName, $col);
|
||||
}
|
||||
|
||||
// (re-)add constraints !after! index update is done
|
||||
// otherwise index update will fail if there are existing constraints
|
||||
foreach($addConstraints as $constraint){
|
||||
$col->addConstraint($constraint);
|
||||
}
|
||||
|
||||
$buildStatus = $tableModifier->build($exec);
|
||||
|
||||
if(
|
||||
@@ -559,7 +573,7 @@ class Setup extends Controller {
|
||||
}
|
||||
|
||||
/** check MySQL params
|
||||
* @param $f3
|
||||
* @param \Base $f3
|
||||
* @param $db
|
||||
* @return array
|
||||
*/
|
||||
|
||||
18
app/main/data/mapper/crestsystem.php
Normal file
18
app/main/data/mapper/crestsystem.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 07.02.2016
|
||||
* Time: 14:34
|
||||
*/
|
||||
|
||||
namespace Data\Mapper;
|
||||
|
||||
|
||||
class CrestSystem extends AbstractIterator {
|
||||
|
||||
protected static $map = [
|
||||
'id' => 'id',
|
||||
'name' => 'name'
|
||||
];
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class TableModifier extends SQL\TableModifier {
|
||||
public function dropConstraint($constraint){
|
||||
if($constraint->isValid()){
|
||||
$this->queries[] = "ALTER TABLE " . $this->db->quotekey($this->name) . "
|
||||
DROP FOREIGN KEY " . $this->db->quotekey($constraint->getConstraintName());
|
||||
DROP FOREIGN KEY " . $this->db->quotekey($constraint->getConstraintName()) . ";";
|
||||
}else{
|
||||
trigger_error(sprintf(self::TEXT_ConstraintNotValid, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
|
||||
}
|
||||
@@ -93,18 +93,13 @@ class TableModifier extends SQL\TableModifier {
|
||||
public function addConstraint($constraint){
|
||||
|
||||
if($constraint->isValid()){
|
||||
if($this->constraintExists($constraint)){
|
||||
// drop constraint and re-add in case something has changed
|
||||
$this->dropConstraint($constraint);
|
||||
}
|
||||
|
||||
$this->queries[] = "
|
||||
ALTER TABLE " . $this->db->quotekey($this->name) . "
|
||||
ADD CONSTRAINT " . $this->db->quotekey($constraint->getConstraintName()) . "
|
||||
FOREIGN KEY (" . implode(', ', $constraint->getKeys()) . ")
|
||||
REFERENCES " . $this->db->quotekey($constraint->getReferencedTable()) . " (" . implode(', ', $constraint->getReferencedCols()) . ")
|
||||
ON DELETE " . $constraint->getOnDelete() . "
|
||||
ON UPDATE " . $constraint->getOnUpdate();
|
||||
ON UPDATE " . $constraint->getOnUpdate() . ";";
|
||||
}else{
|
||||
trigger_error(sprintf(self::TEXT_ConstraintNotValid, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
|
||||
}
|
||||
@@ -120,7 +115,15 @@ class Column extends SQL\Column {
|
||||
const TEXT_TableNameMissing = 'Table name missing for FOREIGN KEY in `%s`';
|
||||
|
||||
/**
|
||||
* ass constraint to this column
|
||||
* drop constraint from this column
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function dropConstraint(Constraint $constraint){
|
||||
$this->table->dropConstraint($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* add constraint to this column
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function addConstraint(Constraint $constraint){
|
||||
|
||||
112
app/main/lib/web.php
Normal file
112
app/main/lib/web.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 12.03.2016
|
||||
* Time: 12:28
|
||||
*/
|
||||
|
||||
namespace Lib;
|
||||
|
||||
class Web extends \Web {
|
||||
|
||||
/**
|
||||
* end of line
|
||||
* @var string
|
||||
*/
|
||||
private $eol = "\r\n";
|
||||
|
||||
/**
|
||||
* get status code from Header data array
|
||||
* @param array $headers
|
||||
* @return int
|
||||
*/
|
||||
protected function getStatuscodeFromHeaders($headers = []){
|
||||
$statusCode = 0;
|
||||
|
||||
if(
|
||||
preg_match(
|
||||
'/HTTP\/1\.\d (\d{3}?)/',
|
||||
implode($this->eol, $headers),
|
||||
$matches
|
||||
)
|
||||
){
|
||||
$statusCode = (int)$matches[1];
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* get cache time in seconds from Header data array
|
||||
* @param array $headers
|
||||
* @return int
|
||||
*/
|
||||
protected function getCacheTimeFromHeaders($headers = []){
|
||||
$cacheTime = 0;
|
||||
|
||||
if(
|
||||
preg_match(
|
||||
'/Cache-Control:(.*?)max-age=([0-9]+)/',
|
||||
implode($this->eol, $headers),
|
||||
$matches
|
||||
)
|
||||
){
|
||||
$cacheTime = (int)$matches[2];
|
||||
}elseif(
|
||||
preg_match(
|
||||
'/Access-Control-Max-Age: ([0-9]+)/',
|
||||
implode($this->eol, $headers),
|
||||
$matches
|
||||
)
|
||||
){
|
||||
$cacheTime = (int)$matches[1];
|
||||
}
|
||||
return $cacheTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a unique cache kay for a request
|
||||
* @param $url
|
||||
* @param null $options
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey($url, $options = null){
|
||||
$f3 = \Base::instance();
|
||||
|
||||
$headers = isset($options['header']) ? implode($this->eol, (array) $options['header']) : '';
|
||||
|
||||
return $f3->hash(
|
||||
$options['method'] . ' '
|
||||
. $url . ' '
|
||||
. $headers
|
||||
).'.url';
|
||||
}
|
||||
|
||||
/**
|
||||
* perform curl() request
|
||||
* -> caches response by returned HTTP Cache header data
|
||||
* @param string $url
|
||||
* @param array|null $options
|
||||
* @return array|FALSE|mixed
|
||||
*/
|
||||
public function request($url,array $options = null) {
|
||||
$f3 = \Base::instance();
|
||||
|
||||
if( !$f3->exists( $hash = $this->getCacheKey($url, $options) ) ){
|
||||
$result = parent::request($url, $options);
|
||||
$statusCode = $this->getStatuscodeFromHeaders( $result['headers'] );
|
||||
|
||||
if($statusCode == 200){
|
||||
// request succeeded -> check if response should be cached
|
||||
if( $ttl = $this->getCacheTimeFromHeaders( $result['headers'] ) ){
|
||||
$f3->set($hash, $result, $ttl);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$result = $f3->get($hash);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ use Exception;
|
||||
use Controller;
|
||||
use DB;
|
||||
|
||||
class BasicModel extends \DB\Cortex {
|
||||
abstract class BasicModel extends \DB\Cortex {
|
||||
|
||||
/**
|
||||
* Hive key with DB object
|
||||
@@ -81,15 +81,17 @@ class BasicModel extends \DB\Cortex {
|
||||
$self->clearCacheData();
|
||||
});
|
||||
|
||||
// model updated
|
||||
$this->afterupdate( function($self){
|
||||
$self->clearCacheData();
|
||||
});
|
||||
|
||||
// model updated
|
||||
$this->beforeinsert( function($self){
|
||||
$self->beforeInsertEvent($self);
|
||||
});
|
||||
|
||||
$this->aftererase( function($self){
|
||||
$self->aftereraseEvent($self);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +228,7 @@ class BasicModel extends \DB\Cortex {
|
||||
$cacheKey = null;
|
||||
|
||||
// set a model unique cache key if the model is saved
|
||||
if( $this->_id > 0){
|
||||
if( $this->id > 0){
|
||||
// check if there is a given key prefix
|
||||
// -> if not, use the standard key.
|
||||
// this is useful for caching multiple data sets according to one row entry
|
||||
@@ -338,11 +340,20 @@ class BasicModel extends \DB\Cortex {
|
||||
}
|
||||
|
||||
/**
|
||||
* function should be overwritten in child classes with access restriction
|
||||
* @param $accessObject
|
||||
* Event "Hook" function
|
||||
* can be overwritten
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess($accessObject){
|
||||
public function aftereraseEvent($self){
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* function should be overwritten in child classes with access restriction
|
||||
* @param UserModel $user
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess(UserModel $user){
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -357,7 +368,7 @@ class BasicModel extends \DB\Cortex {
|
||||
/**
|
||||
* get cached data from this model
|
||||
* @param string $dataCacheKeyPrefix - optional key prefix
|
||||
* @return mixed|null
|
||||
* @return \stdClass|null
|
||||
*/
|
||||
protected function getCacheData($dataCacheKeyPrefix = ''){
|
||||
|
||||
@@ -427,9 +438,9 @@ class BasicModel extends \DB\Cortex {
|
||||
|
||||
/**
|
||||
* factory for all Models
|
||||
* @param $model
|
||||
* @param string $model
|
||||
* @param int $ttl
|
||||
* @return null
|
||||
* @return BasicModel
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getNew($model, $ttl = 86400){
|
||||
@@ -447,7 +458,7 @@ class BasicModel extends \DB\Cortex {
|
||||
|
||||
/**
|
||||
* get the framework instance (singleton)
|
||||
* @return static
|
||||
* @return \Base
|
||||
*/
|
||||
public static function getF3(){
|
||||
return \Base::instance();
|
||||
@@ -455,7 +466,7 @@ class BasicModel extends \DB\Cortex {
|
||||
|
||||
/**
|
||||
* debug log function
|
||||
* @param $text
|
||||
* @param string $text
|
||||
*/
|
||||
public static function log($text){
|
||||
Controller\LogController::getLogger('debug')->write($text);
|
||||
|
||||
@@ -14,6 +14,14 @@ class CharacterLogModel extends BasicModel {
|
||||
|
||||
protected $table = 'character_log';
|
||||
|
||||
/**
|
||||
* caching for relational data
|
||||
* -> 10s matches REST API - Expire: Header-Data
|
||||
* for "Location" calls
|
||||
* @var int
|
||||
*/
|
||||
protected $rel_ttl = 10;
|
||||
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
@@ -68,6 +76,17 @@ class CharacterLogModel extends BasicModel {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* set log data from object
|
||||
* @param object $logData
|
||||
*/
|
||||
public function setData($logData){
|
||||
if( !empty($logData->system) ){
|
||||
$this->systemId = $logData->system['id'];
|
||||
$this->systemName = $logData->system['name'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get all character log data
|
||||
* @return object
|
||||
|
||||
75
app/main/model/charactermapmodel.php
Normal file
75
app/main/model/charactermapmodel.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus
|
||||
* Date: 07.02.2016
|
||||
* Time: 12:31
|
||||
*/
|
||||
|
||||
namespace Model;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class CharacterMapModel extends BasicModel {
|
||||
|
||||
protected $table = 'character_map';
|
||||
|
||||
protected $fieldConf = [
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
'default' => 1,
|
||||
'index' => true
|
||||
],
|
||||
'characterId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\CharacterModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'character',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
],
|
||||
'mapId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\MapModel',
|
||||
'constraint' => [
|
||||
[
|
||||
'table' => 'map',
|
||||
'on-delete' => 'CASCADE'
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* see parent
|
||||
*/
|
||||
public function clearCacheData(){
|
||||
parent::clearCacheData();
|
||||
|
||||
// clear map cache as well
|
||||
$this->mapId->clearCacheData();
|
||||
}
|
||||
|
||||
/**
|
||||
* overwrites parent
|
||||
* @param null $db
|
||||
* @param null $table
|
||||
* @param null $fields
|
||||
* @return bool
|
||||
*/
|
||||
public static function setup($db=null, $table=null, $fields=null){
|
||||
$status = parent::setup($db,$table,$fields);
|
||||
|
||||
if($status === true){
|
||||
$status = parent::setMultiColumnIndex(['characterId', 'mapId'], true);
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
namespace Model;
|
||||
|
||||
use Controller\Ccp;
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class CharacterModel extends BasicModel {
|
||||
@@ -15,6 +16,10 @@ class CharacterModel extends BasicModel {
|
||||
protected $table = 'character';
|
||||
|
||||
protected $fieldConf = [
|
||||
'lastLogin' => [
|
||||
'type' => Schema::DT_TIMESTAMP,
|
||||
'index' => true
|
||||
],
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
@@ -26,6 +31,22 @@ class CharacterModel extends BasicModel {
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'ownerHash' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'crestAccessToken' => [
|
||||
'type' => Schema::DT_VARCHAR256
|
||||
],
|
||||
'crestAccessTokenUpdated' => [
|
||||
'type' => Schema::DT_TIMESTAMP,
|
||||
'default' => Schema::DF_CURRENT_TIMESTAMP,
|
||||
'index' => true
|
||||
],
|
||||
'crestRefreshToken' => [
|
||||
'type' => Schema::DT_VARCHAR256
|
||||
],
|
||||
'corporationId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
@@ -57,6 +78,9 @@ class CharacterModel extends BasicModel {
|
||||
'nullable' => false,
|
||||
'default' => ''
|
||||
],
|
||||
'userCharacter' => [
|
||||
'has-one' => ['Model\UserCharacterModel', 'characterId']
|
||||
],
|
||||
'characterLog' => [
|
||||
'has-one' => ['Model\CharacterLogModel', 'characterId']
|
||||
]
|
||||
@@ -65,19 +89,17 @@ class CharacterModel extends BasicModel {
|
||||
/**
|
||||
* get character data
|
||||
* @param bool|false $addCharacterLogData
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData($addCharacterLogData = false){
|
||||
|
||||
// check if there is cached data
|
||||
// temporary disabled (performance test)
|
||||
$characterData = null; //$this->getCacheData();
|
||||
$characterData = $this->getCacheData();
|
||||
|
||||
if(is_null($characterData)){
|
||||
// no cached character data found
|
||||
|
||||
$characterData = (object) [];
|
||||
|
||||
$characterData->id = $this->id;
|
||||
$characterData->name = $this->name;
|
||||
|
||||
@@ -106,18 +128,50 @@ class CharacterModel extends BasicModel {
|
||||
return $characterData;
|
||||
}
|
||||
|
||||
/**
|
||||
* set unique "ownerHash" for this character
|
||||
* -> Hash will change when character is transferred (sold)
|
||||
* @param string $ownerHash
|
||||
* @return string
|
||||
*/
|
||||
public function set_ownerHash($ownerHash){
|
||||
if (
|
||||
$this->hasUserCharacter() &&
|
||||
$this->ownerHash !== $ownerHash
|
||||
){
|
||||
$this->userCharacter->erase();
|
||||
}
|
||||
return $ownerHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* set CREST accessToken for current session
|
||||
* -> update "tokenUpdated" column on change
|
||||
* -> this is required for expire checking!
|
||||
* @param string $accessToken
|
||||
* @return string
|
||||
*/
|
||||
public function set_crestAccessToken($accessToken){
|
||||
if($this->crestAccessToken !== $accessToken){
|
||||
$this->touch('crestAccessTokenUpdated');
|
||||
}
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this character has already a user assigned to it
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUserCharacter(){
|
||||
return is_object($this->userCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this character has a corporation
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCorporation(){
|
||||
$hasCorporation = false;
|
||||
|
||||
if($this->corporationId){
|
||||
$hasCorporation = true;
|
||||
}
|
||||
|
||||
return $hasCorporation;
|
||||
return is_object($this->corporationId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,46 +179,177 @@ class CharacterModel extends BasicModel {
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAlliance(){
|
||||
$hasAlliance = false;
|
||||
return is_object($this->allianceId);
|
||||
}
|
||||
|
||||
if($this->allianceId){
|
||||
$hasAlliance = true;
|
||||
/**
|
||||
* @return UserModel|null
|
||||
*/
|
||||
public function getUser(){
|
||||
$user = null;
|
||||
if($this->hasUserCharacter()){
|
||||
/**
|
||||
* @var $user UserModel
|
||||
*/
|
||||
$user = $this->userCharacter->userId;
|
||||
}
|
||||
|
||||
return $hasAlliance;
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the corporation for this user
|
||||
* @return mixed|null
|
||||
* @return \Model\CorporationModel|null
|
||||
*/
|
||||
public function getCorporation(){
|
||||
$corporation = null;
|
||||
|
||||
if($this->hasCorporation()){
|
||||
$corporation = $this->corporationId;
|
||||
}
|
||||
|
||||
return $corporation;
|
||||
return $this->corporationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the alliance of this user
|
||||
* @return mixed|null
|
||||
* @return \Model\AllianceModel|null
|
||||
*/
|
||||
public function getAlliance(){
|
||||
$alliance = null;
|
||||
return $this->allianceId;
|
||||
}
|
||||
|
||||
if($this->hasAlliance()){
|
||||
$alliance = $this->allianceId;
|
||||
/**
|
||||
* get CREST API "access_token" from OAuth
|
||||
* @return bool|string
|
||||
*/
|
||||
private function getAccessToken(){
|
||||
$accessToken = false;
|
||||
|
||||
// check if there is already an "accessToken" for this user
|
||||
// check expire timer for stored "accessToken"
|
||||
if(
|
||||
!empty($this->crestAccessToken) &&
|
||||
!empty($this->crestAccessTokenUpdated)
|
||||
){
|
||||
$timezone = new \DateTimeZone( $this->getF3()->get('TZ') );
|
||||
$tokenTime = \DateTime::createFromFormat(
|
||||
'Y-m-d H:i:s',
|
||||
$this->crestAccessTokenUpdated,
|
||||
$timezone
|
||||
);
|
||||
// add expire time buffer for this "accessToken"
|
||||
// token should be marked as "deprecated" BEFORE it actually expires.
|
||||
$timeBuffer = 2 * 60;
|
||||
$tokenTime->add(new \DateInterval('PT' . (Ccp\Sso::ACCESS_KEY_EXPIRE_TIME - $timeBuffer) . 'S'));
|
||||
|
||||
$now = new \DateTime('now', $timezone);
|
||||
if($tokenTime->getTimestamp() > $now->getTimestamp()){
|
||||
$accessToken = $this->crestAccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
return $alliance;
|
||||
// if no "accessToken" was found -> get a fresh one by an existing "refreshToken"
|
||||
if(
|
||||
!$accessToken &&
|
||||
!empty($this->crestRefreshToken)
|
||||
){
|
||||
// no accessToken found OR token is deprecated
|
||||
$ssoController = new Ccp\Sso();
|
||||
$accessData = $ssoController->refreshAccessToken($this->crestRefreshToken);
|
||||
|
||||
if(
|
||||
isset($accessData->accessToken) &&
|
||||
isset($accessData->refreshToken)
|
||||
){
|
||||
$this->crestAccessToken = $accessData->accessToken;
|
||||
$this->save();
|
||||
|
||||
$accessToken = $this->crestAccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether this character is authorized to log in
|
||||
* -> check corp/ally whitelist config (pathfinder.ini)
|
||||
* @return bool
|
||||
*/
|
||||
public function isAuthorized(){
|
||||
$isAuthorized = false;
|
||||
$f3 = self::getF3();
|
||||
|
||||
$whitelistCorporations = $whitelistAlliance = [];
|
||||
if( !empty($f3->get('PATHFINDER.LOGIN.CORPORATION')) ){
|
||||
$whitelistCorporations = array_map('trim',(array) $f3->get('PATHFINDER.LOGIN.CORPORATION') );
|
||||
}
|
||||
if( !empty($f3->get('PATHFINDER.LOGIN.ALLIANCE')) ){
|
||||
$whitelistAlliance = array_map('trim',(array) $f3->get('PATHFINDER.LOGIN.ALLIANCE') );
|
||||
}
|
||||
|
||||
if(
|
||||
empty($whitelistCorporations) &&
|
||||
empty($whitelistAlliance)
|
||||
){
|
||||
// no corp/ally restrictions set -> any character is allowed to login
|
||||
$isAuthorized = true;
|
||||
}else{
|
||||
// check if character corporation is set in whitelist
|
||||
if(
|
||||
!empty($whitelistCorporations) &&
|
||||
$this->hasCorporation() &&
|
||||
in_array($this->getCorporation()->_id, $whitelistCorporations)
|
||||
){
|
||||
$isAuthorized = true;
|
||||
}
|
||||
|
||||
// check if character alliance is set in whitelist
|
||||
if(
|
||||
!$isAuthorized &&
|
||||
!empty($whitelistAlliance) &&
|
||||
$this->hasAlliance() &&
|
||||
in_array($this->getAlliance()->_id, $whitelistAlliance)
|
||||
){
|
||||
$isAuthorized = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $isAuthorized;
|
||||
}
|
||||
|
||||
/**
|
||||
* update character log (active system, ...)
|
||||
* -> CREST API request for character log data
|
||||
* @return CharacterModel
|
||||
*/
|
||||
public function updateLog(){
|
||||
|
||||
$characterModel = $this;
|
||||
$ssoController = new Ccp\Sso();
|
||||
|
||||
$locationData = $ssoController->getCharacterLocationData($this->getAccessToken());
|
||||
|
||||
if( empty((array)$locationData) ){
|
||||
// character is not in-game
|
||||
if(is_object($this->characterLog)){
|
||||
// delete existing log
|
||||
$this->characterLog->erase();
|
||||
$characterModel = $this->save();
|
||||
}
|
||||
}else{
|
||||
// character is currently in-game
|
||||
if( !$characterLog = $this->getLog() ){
|
||||
// create new log
|
||||
$characterLog = $this->rel('characterLog');
|
||||
$characterLog->characterId = $this;
|
||||
}
|
||||
$characterLog->setData($locationData);
|
||||
$characterLog->save();
|
||||
$this->characterLog = $characterLog;
|
||||
$characterModel = $this->save();
|
||||
}
|
||||
|
||||
return $characterModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the character log entry for this character
|
||||
* @return bool|null
|
||||
* @return bool|CharacterLogModel
|
||||
*/
|
||||
public function getLog(){
|
||||
|
||||
|
||||
@@ -103,11 +103,11 @@ class ConnectionModel extends BasicModel{
|
||||
|
||||
/**
|
||||
* check object for model access
|
||||
* @param $accessObject
|
||||
* @return bool
|
||||
* @param UserModel $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasAccess($accessObject){
|
||||
return $this->mapId->hasAccess($accessObject);
|
||||
public function hasAccess(UserModel $user){
|
||||
return $this->mapId->hasAccess($user);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,13 +127,13 @@ class ConnectionModel extends BasicModel{
|
||||
|
||||
/**
|
||||
* delete a connection
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
*/
|
||||
public function delete($accessObject){
|
||||
public function delete(UserModel $user){
|
||||
|
||||
if(!$this->dry()){
|
||||
// check if editor has access
|
||||
if($this->hasAccess($accessObject)){
|
||||
if($this->hasAccess($user)){
|
||||
$this->erase();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
namespace Model;
|
||||
|
||||
use Controller\Api\User;
|
||||
use DB\SQL\Schema;
|
||||
|
||||
class MapModel extends BasicModel {
|
||||
@@ -117,16 +118,14 @@ class MapModel extends BasicModel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get map data
|
||||
* -> this includes system and connection data as well!
|
||||
* @return array
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
|
||||
// check if there is cached data
|
||||
$mapDataAll = $this->getCacheData();
|
||||
// check if there is cached data
|
||||
$mapDataAll = $this->getCacheData();
|
||||
|
||||
if(is_null($mapDataAll)){
|
||||
// no cached map data found
|
||||
@@ -355,25 +354,34 @@ class MapModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* clear access for a given type of objects
|
||||
* @param $clearKeys
|
||||
* @param array $clearKeys
|
||||
*/
|
||||
public function clearAccess($clearKeys = ['user', 'corporation', 'alliance']){
|
||||
|
||||
foreach($clearKeys as $key){
|
||||
switch($key){
|
||||
case 'user':
|
||||
foreach((array)$this->mapUsers as $obj){
|
||||
$obj->erase();
|
||||
foreach((array)$this->mapUsers as $userMapModel){
|
||||
/**
|
||||
* @var UserMapModel $userMapModel
|
||||
*/
|
||||
$userMapModel->erase();
|
||||
};
|
||||
break;
|
||||
case 'corporation':
|
||||
foreach((array)$this->mapCorporations as $obj){
|
||||
$obj->erase();
|
||||
foreach((array)$this->mapCorporations as $corporationMapModel){
|
||||
/**
|
||||
* @var CorporationMapModel $corporationMapModel
|
||||
*/
|
||||
$corporationMapModel->erase();
|
||||
};
|
||||
break;
|
||||
case 'alliance':
|
||||
foreach((array)$this->mapAlliances as $obj){
|
||||
$obj->erase();
|
||||
foreach((array)$this->mapAlliances as $allianceMapModel){
|
||||
/**
|
||||
* @var AllianceMapModel $allianceMapModel
|
||||
*/
|
||||
$allianceMapModel->erase();
|
||||
};
|
||||
break;
|
||||
}
|
||||
@@ -382,21 +390,16 @@ class MapModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* checks weather a user has access to this map or not
|
||||
* @param $user
|
||||
* @param UserModel $user
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess($user){
|
||||
public function hasAccess(UserModel $user){
|
||||
$hasAccess = false;
|
||||
|
||||
if(
|
||||
!$this->dry() &&
|
||||
$user instanceof UserModel
|
||||
){
|
||||
|
||||
if( !$this->dry() ){
|
||||
// get all maps the user has access to
|
||||
// this includes corporation and alliance maps
|
||||
$maps = $user->getMaps();
|
||||
|
||||
foreach($maps as $map){
|
||||
if($map->id === $this->id){
|
||||
$hasAccess = true;
|
||||
@@ -411,7 +414,7 @@ class MapModel extends BasicModel {
|
||||
/**
|
||||
* get all user models that have access to this map
|
||||
* note: This function is just for "private" maps
|
||||
* @return array
|
||||
* @return UserModel[]
|
||||
*/
|
||||
public function getUsers(){
|
||||
$users = [];
|
||||
@@ -431,7 +434,7 @@ class MapModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get all character models that are currently online "viewing" this map
|
||||
* @return array
|
||||
* @return CharacterModel[]
|
||||
*/
|
||||
private function getCharacters(){
|
||||
$characters = [];
|
||||
@@ -439,24 +442,29 @@ class MapModel extends BasicModel {
|
||||
if($this->isPrivate()){
|
||||
$users = $this->getUsers();
|
||||
|
||||
// add active character for each user
|
||||
foreach($users as $user){
|
||||
// get all active character logs for a user
|
||||
$tempActiveUserCharacters = $user->getActiveUserCharacters();
|
||||
|
||||
foreach($tempActiveUserCharacters as $tempActiveUserCharacter){
|
||||
$characters[] = $tempActiveUserCharacter;
|
||||
}
|
||||
/**
|
||||
* @var UserModel $user
|
||||
*/
|
||||
$characters = array_merge($characters, $user->getActiveCharacters());
|
||||
}
|
||||
}elseif($this->isCorporation()){
|
||||
$corporations = $this->getCorporations();
|
||||
|
||||
foreach($corporations as $corporation){
|
||||
/**
|
||||
* @var CorporationModel $corporation
|
||||
*/
|
||||
$characters = array_merge($characters, $corporation->getCharacters());
|
||||
}
|
||||
}elseif($this->isAlliance()){
|
||||
$alliances = $this->getAlliances();
|
||||
|
||||
foreach($alliances as $alliance){
|
||||
/**
|
||||
* @var AllianceModel $alliance
|
||||
*/
|
||||
$characters = array_merge($characters, $alliance->getCharacters());
|
||||
}
|
||||
}
|
||||
@@ -531,16 +539,15 @@ class MapModel extends BasicModel {
|
||||
return $alliances;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* delete this map and all dependencies
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
*/
|
||||
public function delete($accessObject){
|
||||
public function delete(UserModel $user){
|
||||
|
||||
if(!$this->dry()){
|
||||
// check if editor has access
|
||||
if($this->hasAccess($accessObject)){
|
||||
// check if user has access
|
||||
if($this->hasAccess($user)){
|
||||
// all map related tables will be deleted on cascade
|
||||
|
||||
// delete map
|
||||
|
||||
@@ -313,23 +313,23 @@ class SystemModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* check object for model access
|
||||
* @param $accessObject
|
||||
* @return bool
|
||||
* @param UserModel $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasAccess($accessObject){
|
||||
return $this->mapId->hasAccess($accessObject);
|
||||
public function hasAccess(UserModel $user){
|
||||
return $this->mapId->hasAccess($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a system from a map
|
||||
* hint: signatures and connections will be deleted on cascade
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
*/
|
||||
public function delete($accessObject){
|
||||
public function delete(UserModel $user){
|
||||
|
||||
if(! $this->dry()){
|
||||
// check if user has access
|
||||
if($this->hasAccess($accessObject)){
|
||||
if($this->hasAccess($user)){
|
||||
$this->erase();
|
||||
}
|
||||
}
|
||||
@@ -367,14 +367,14 @@ class SystemModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get Signature by id and check for access
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
* @param $id
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getSignatureById($accessObject, $id){
|
||||
public function getSignatureById(UserModel $user, $id){
|
||||
$signature = null;
|
||||
|
||||
if($this->hasAccess($accessObject)){
|
||||
if($this->hasAccess($user)){
|
||||
$this->filter('signatures', ['active = ? AND id = ?', 1, $id]);
|
||||
if($this->signatures){
|
||||
$signature = reset( $this->signatures );
|
||||
@@ -386,14 +386,14 @@ class SystemModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get a signature by its "unique" 3-digit name
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
* @param $name
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getSignatureByName($accessObject, $name){
|
||||
public function getSignatureByName(UserModel $user, $name){
|
||||
$signature = null;
|
||||
|
||||
if($this->hasAccess($accessObject)){
|
||||
if($this->hasAccess($user)){
|
||||
$this->filter('signatures', ['active = ? AND name = ?', 1, $name]);
|
||||
if($this->signatures){
|
||||
$signature = reset( $this->signatures );
|
||||
|
||||
@@ -151,18 +151,21 @@ class SystemSignatureModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* check object for model access
|
||||
* @param $accessObject
|
||||
* @param UserModel $user
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess($accessObject){
|
||||
return $this->systemId->hasAccess($accessObject);
|
||||
public function hasAccess(UserModel $user){
|
||||
return $this->systemId->hasAccess($user);
|
||||
}
|
||||
|
||||
public function delete($accessObject){
|
||||
|
||||
/**
|
||||
* delete signature
|
||||
* @param UserModel $user
|
||||
*/
|
||||
public function delete(UserModel $user){
|
||||
if(!$this->dry()){
|
||||
// check if editor has access
|
||||
if($this->hasAccess($accessObject)){
|
||||
if($this->hasAccess($user)){
|
||||
$this->erase();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,15 +60,6 @@ class UserApiModel extends BasicModel {
|
||||
return $apiData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function updateCharacters(){
|
||||
$apiController = new Controller\CcpApiController();
|
||||
|
||||
return $apiController->updateCharacters($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all characters for this API
|
||||
* @return array|mixed
|
||||
|
||||
@@ -46,6 +46,7 @@ class UserCharacterModel extends BasicModel {
|
||||
'characterId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'index' => true,
|
||||
'unique' => true,
|
||||
'belongs-to-one' => 'Model\CharacterModel',
|
||||
'constraint' => [
|
||||
[
|
||||
@@ -79,34 +80,22 @@ class UserCharacterModel extends BasicModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* get all character data
|
||||
* @param $addCharacterLogData
|
||||
* @return array
|
||||
* event "Hook"
|
||||
* -> remove user if there are no other characters bound to this user
|
||||
* @param $self
|
||||
* @return bool
|
||||
*/
|
||||
public function getData($addCharacterLogData = false){
|
||||
|
||||
// get characterModel
|
||||
$characterModel = $this->getCharacter();
|
||||
|
||||
// get static character data
|
||||
$characterData = $characterModel->getData($addCharacterLogData);
|
||||
|
||||
// add user specific character data
|
||||
$characterData->isMain = $this->isMain;
|
||||
|
||||
// check for corporation
|
||||
if( is_object( $characterModel->corporationId ) ){
|
||||
$characterData->corporation = $characterModel->corporationId->getData();
|
||||
public function aftereraseEvent($self){
|
||||
if(
|
||||
is_object($self->userId) &&
|
||||
is_null($self->userId->userCharacters)
|
||||
){
|
||||
$self->userId->erase();
|
||||
}
|
||||
|
||||
// check for alliance
|
||||
if( is_object( $characterModel->allianceId ) ){
|
||||
$characterData->alliance = $characterModel->allianceId->getData();
|
||||
}
|
||||
|
||||
return $characterData;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check if this character is Main character or not
|
||||
* @return bool
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Model;
|
||||
|
||||
use DB\SQL\Schema;
|
||||
use Controller;
|
||||
use Controller\Api;
|
||||
use Exception;
|
||||
|
||||
class UserModel extends BasicModel {
|
||||
@@ -17,10 +18,6 @@ class UserModel extends BasicModel {
|
||||
protected $table = 'user';
|
||||
|
||||
protected $fieldConf = [
|
||||
'lastLogin' => [
|
||||
'type' => Schema::DT_TIMESTAMP,
|
||||
'index' => true
|
||||
],
|
||||
'active' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
@@ -31,15 +28,12 @@ class UserModel extends BasicModel {
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => '',
|
||||
'index' => true,
|
||||
'unique' => true
|
||||
'index' => true
|
||||
],
|
||||
'email' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
'nullable' => false,
|
||||
'default' => '',
|
||||
'index' => true,
|
||||
'unique' => true
|
||||
'default' => ''
|
||||
],
|
||||
'password' => [
|
||||
'type' => Schema::DT_VARCHAR128,
|
||||
@@ -69,11 +63,6 @@ class UserModel extends BasicModel {
|
||||
'max' => 25
|
||||
]
|
||||
],
|
||||
'email' => [
|
||||
'length' => [
|
||||
'min' => 5
|
||||
]
|
||||
],
|
||||
'password' => [
|
||||
'length' => [
|
||||
'min' => 6
|
||||
@@ -83,9 +72,9 @@ class UserModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get all data for this user
|
||||
* ! caution ! this function returns sensitive data!
|
||||
* -> ! caution ! this function returns sensitive data! (e.g. email,..)
|
||||
* -> user getSimpleData() for faster performance and public user data
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getData(){
|
||||
|
||||
@@ -98,24 +87,19 @@ class UserModel extends BasicModel {
|
||||
// user shared info
|
||||
$userData->shared = $this->shared;
|
||||
|
||||
// api data
|
||||
$APIs = $this->getAPIs();
|
||||
foreach($APIs as $api){
|
||||
$userData->api[] = $api->getData();
|
||||
}
|
||||
|
||||
// all chars
|
||||
$userData->characters = [];
|
||||
$userCharacters = $this->getUserCharacters();
|
||||
foreach($userCharacters as $userCharacter){
|
||||
$userData->characters[] = $userCharacter->getData();
|
||||
$characters = $this->getCharacters();
|
||||
foreach($characters as $character){
|
||||
/**
|
||||
* @var $character CharacterModel
|
||||
*/
|
||||
$userData->characters[] = $character->getData();
|
||||
}
|
||||
|
||||
// set active character with log data
|
||||
$activeUserCharacter = $this->getActiveUserCharacter();
|
||||
if($activeUserCharacter){
|
||||
$userData->character = $activeUserCharacter->getData(true);
|
||||
}
|
||||
$activeCharacter = $this->getActiveCharacter();
|
||||
$userData->character = $activeCharacter->getData(true);
|
||||
|
||||
return $userData;
|
||||
}
|
||||
@@ -123,7 +107,7 @@ class UserModel extends BasicModel {
|
||||
/**
|
||||
* get public user data
|
||||
* - check out getData() for all user data
|
||||
* @return object
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getSimpleData(){
|
||||
$userData = (object) [];
|
||||
@@ -135,11 +119,15 @@ class UserModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* validate and set a email address for this user
|
||||
* @param $email
|
||||
* @return mixed
|
||||
* -> empty email is allowed!
|
||||
* @param string $email
|
||||
* @return string
|
||||
*/
|
||||
public function set_email($email){
|
||||
if (\Audit::instance()->email($email) == false) {
|
||||
if (
|
||||
!empty($email) &&
|
||||
\Audit::instance()->email($email) == false
|
||||
) {
|
||||
// no valid email address
|
||||
$this->throwValidationError('email');
|
||||
}
|
||||
@@ -148,8 +136,8 @@ class UserModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* set a password hash for this user
|
||||
* @param $password
|
||||
* @return FALSE|string
|
||||
* @param string $password
|
||||
* @return string
|
||||
*/
|
||||
public function set_password($password){
|
||||
if(strlen($password) < 6){
|
||||
@@ -208,10 +196,9 @@ class UserModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get all accessible map models for this user
|
||||
* @return array
|
||||
* @return MapModel[]
|
||||
*/
|
||||
public function getMaps(){
|
||||
$f3 = self::getF3();
|
||||
|
||||
$this->filter(
|
||||
'userMaps',
|
||||
@@ -222,34 +209,29 @@ class UserModel extends BasicModel {
|
||||
$maps = [];
|
||||
if($this->userMaps){
|
||||
$mapCountPrivate = 0;
|
||||
foreach($this->userMaps as $userMap){
|
||||
foreach($this->userMaps as &$userMap){
|
||||
if(
|
||||
$userMap->mapId->isActive() &&
|
||||
$mapCountPrivate < $f3->get('PATHFINDER.MAX_MAPS_PRIVATE')
|
||||
$mapCountPrivate < self::getF3()->get('PATHFINDER.MAX_MAPS_PRIVATE')
|
||||
){
|
||||
$maps[] = $userMap->mapId;
|
||||
$maps[] = &$userMap->mapId;
|
||||
$mapCountPrivate++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$activeUserCharacter = $this->getActiveUserCharacter();
|
||||
// get current active character
|
||||
$controller = new Controller\Controller();
|
||||
$activeCharacter = $controller->getCharacter();
|
||||
$corporation = $activeCharacter->getCorporation();
|
||||
$alliance = $activeCharacter->getAlliance();
|
||||
|
||||
if($activeUserCharacter){
|
||||
$character = $activeUserCharacter->getCharacter();
|
||||
$corporation = $character->getCorporation();
|
||||
$alliance = $character->getAlliance();
|
||||
if($alliance){
|
||||
$maps = array_merge($maps, $alliance->getMaps());
|
||||
}
|
||||
|
||||
if($alliance){
|
||||
$allianceMaps = $alliance->getMaps();
|
||||
$maps = array_merge($maps, $allianceMaps);
|
||||
}
|
||||
|
||||
if($corporation){
|
||||
$corporationMaps = $corporation->getMaps();
|
||||
$maps = array_merge($maps, $corporationMaps);
|
||||
|
||||
}
|
||||
if($corporation){
|
||||
$maps = array_merge($maps, $corporation->getMaps());
|
||||
}
|
||||
|
||||
return $maps;
|
||||
@@ -257,13 +239,16 @@ class UserModel extends BasicModel {
|
||||
|
||||
/**
|
||||
* get mapModel by id and check if user has access
|
||||
* @param $mapId
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
* @param int $mapId
|
||||
* @return MapModel|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getMap($mapId){
|
||||
public function getMap(int $mapId){
|
||||
/**
|
||||
* @var $map MapModel
|
||||
*/
|
||||
$map = self::getNew('MapModel');
|
||||
$map->getById( (int)$mapId );
|
||||
$map->getById( $mapId );
|
||||
|
||||
$returnMap = null;
|
||||
if($map->hasAccess($this)){
|
||||
@@ -324,35 +309,14 @@ class UserModel extends BasicModel {
|
||||
/**
|
||||
* get all userCharacters models for a user
|
||||
* characters will be checked/updated on login by CCP API call
|
||||
* @return array|mixed
|
||||
* @return UserCharacterModel[]
|
||||
*/
|
||||
public function getUserCharacters(){
|
||||
$this->filter('userCharacters', ['active = ?', 1]);
|
||||
|
||||
$this->filter('apis', ['active = ?', 1]);
|
||||
|
||||
// if a user has multiple API keys saved for ONE character,
|
||||
// skip double characters!
|
||||
$userCharacters = [];
|
||||
|
||||
if($this->apis){
|
||||
$this->apis->rewind();
|
||||
while($this->apis->valid()){
|
||||
|
||||
$this->apis->current()->filter('userCharacters', ['active = ?', 1]);
|
||||
|
||||
if($this->apis->current()->userCharacters){
|
||||
$this->apis->current()->userCharacters->rewind();
|
||||
while($this->apis->current()->userCharacters->valid()){
|
||||
|
||||
$tempCharacterId = $this->apis->current()->userCharacters->current()->characterId->get('id');
|
||||
if( !isset($userCharacters[ $tempCharacterId ]) ){
|
||||
$userCharacters[ $tempCharacterId ] = $this->apis->current()->userCharacters->current();
|
||||
}
|
||||
$this->apis->current()->userCharacters->next();
|
||||
}
|
||||
}
|
||||
$this->apis->next();
|
||||
}
|
||||
if($this->userCharacters){
|
||||
$userCharacters = $this->userCharacters;
|
||||
}
|
||||
|
||||
return $userCharacters;
|
||||
@@ -377,82 +341,72 @@ class UserModel extends BasicModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the active user character for this user
|
||||
* either there is an active Character (IGB) or the character labeled as "main"
|
||||
* @return null
|
||||
* get the current active character for this user
|
||||
* -> EITHER - the current active one for the current user
|
||||
* -> OR - get the first active one
|
||||
* @return null|CharacterModel
|
||||
*/
|
||||
public function getActiveUserCharacter(){
|
||||
$activeUserCharacter = null;
|
||||
public function getActiveCharacter(){
|
||||
$activeCharacter = null;
|
||||
$controller = new Controller\Controller();
|
||||
$currentActiveCharacter = $controller->getCharacter();
|
||||
|
||||
$headerData = Controller\CcpApiController::getIGBHeaderData();
|
||||
|
||||
// check if IGB Data is available
|
||||
if( !empty($headerData->values) ){
|
||||
// search for the active character by IGB Header Data
|
||||
|
||||
$this->filter('userCharacters',
|
||||
[
|
||||
'active = :active AND characterId = :characterId',
|
||||
':active' => 1,
|
||||
':characterId' => intval($headerData->values['charid'])
|
||||
],
|
||||
['limit' => 1]
|
||||
);
|
||||
|
||||
if($this->userCharacters){
|
||||
// check if userCharacter has active log
|
||||
$userCharacter = current($this->userCharacters);
|
||||
|
||||
if( $userCharacter->getCharacter()->getLog() ){
|
||||
$activeUserCharacter = $userCharacter;
|
||||
}
|
||||
if(
|
||||
!is_null($currentActiveCharacter) &&
|
||||
$currentActiveCharacter->getUser()->_id === $this->id
|
||||
){
|
||||
$activeCharacter = &$currentActiveCharacter;
|
||||
}else{
|
||||
// set "first" found as active for this user
|
||||
if($activeCharacters = $this->getActiveCharacters()){
|
||||
$activeCharacter = &$activeCharacters[0];
|
||||
}
|
||||
}
|
||||
|
||||
// if no active character is found
|
||||
// e.g. not online in IGB
|
||||
// -> get main Character
|
||||
if(is_null($activeUserCharacter)){
|
||||
$activeUserCharacter = $this->getMainUserCharacter();
|
||||
}
|
||||
|
||||
return $activeUserCharacter;
|
||||
return $activeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all active user characters (with log entry)
|
||||
* hint: a user can have multiple active characters
|
||||
* @return array
|
||||
* get all characters for this user
|
||||
* @return CharacterModel[]
|
||||
*/
|
||||
public function getActiveUserCharacters(){
|
||||
public function getCharacters(){
|
||||
$userCharacters = $this->getUserCharacters();
|
||||
$characters = [];
|
||||
foreach($userCharacters as $userCharacter){
|
||||
/**
|
||||
* @var $userCharacter UserCharacterModel
|
||||
*/
|
||||
if( $currentCharacter = $userCharacter->getCharacter() ){
|
||||
// check if userCharacter has a valid character
|
||||
// -> this should never fail!
|
||||
$characters[] = $currentCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
return $characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all active characters (with log entry)
|
||||
* hint: a user can have multiple active characters
|
||||
* @return CharacterModel[]
|
||||
*/
|
||||
public function getActiveCharacters(){
|
||||
$userCharacters = $this->getUserCharacters();
|
||||
|
||||
$activeUserCharacters = [];
|
||||
$activeCharacters = [];
|
||||
foreach($userCharacters as $userCharacter){
|
||||
$characterLog = $userCharacter->getCharacter()->getLog();
|
||||
|
||||
if($characterLog){
|
||||
$activeUserCharacters[] = $userCharacter;
|
||||
/**
|
||||
* @var $userCharacter UserCharacterModel
|
||||
*/
|
||||
$characterModel = $userCharacter->getCharacter();
|
||||
if($characterLog = $characterModel->getLog()){
|
||||
$activeCharacters[] = $characterModel;
|
||||
}
|
||||
}
|
||||
|
||||
return $activeUserCharacters;
|
||||
}
|
||||
|
||||
/**
|
||||
* update/check API information.
|
||||
* request API information from CCP
|
||||
*/
|
||||
public function updateApiData(){
|
||||
$this->filter('apis', ['active = ?', 1]);
|
||||
|
||||
if($this->apis){
|
||||
$this->apis->rewind();
|
||||
while($this->apis->valid()){
|
||||
$this->apis->current()->updateCharacters();
|
||||
$this->apis->next();
|
||||
}
|
||||
}
|
||||
return $activeCharacters;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,8 +414,10 @@ class UserModel extends BasicModel {
|
||||
* @param int $ttl cache time in seconds
|
||||
* @throws \Exception
|
||||
*/
|
||||
/*
|
||||
public function updateCharacterLog($ttl = 0){
|
||||
$headerData = Controller\CcpApiController::getIGBHeaderData();
|
||||
|
||||
$headerData = Controller\Controller::getIGBHeaderData();
|
||||
|
||||
// check if IGB Data is available
|
||||
if( !empty($headerData->values) ){
|
||||
@@ -551,6 +507,7 @@ class UserModel extends BasicModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@@ -34,6 +34,11 @@ INVITE = 0
|
||||
; the limit of registration keys. Increase it to hand out more keys
|
||||
INVITE_LIMIT = 50
|
||||
|
||||
[PATHFINDER.LOGIN]
|
||||
|
||||
CORPORATION = 1000166
|
||||
ALLIANCE =
|
||||
|
||||
; View ============================================================================================
|
||||
[PATHFINDER.VIEW]
|
||||
; static page templates
|
||||
@@ -102,11 +107,6 @@ DELETE_ACCOUNT = delete_account
|
||||
|
||||
; API =============================================================================================
|
||||
[PATHFINDER.API]
|
||||
; CCP SSO OAuth 2.0
|
||||
CCP_SSO = https://login.eveonline.com
|
||||
; CCP CREST API
|
||||
CCP_CREST = https://crest-tq.eveonline.com
|
||||
; CCP_CREST = https://api-sisi.testeveonline.com
|
||||
; CCP XML APIv2
|
||||
CCP_XML = https://api.eveonline.com
|
||||
; GitHub Developer API
|
||||
|
||||
@@ -7,7 +7,7 @@ GET @setup: /setup = Controller\Setup->in
|
||||
; login (index) page
|
||||
GET @login: / = Controller\AppController->init, 0
|
||||
; CCP SSO redirect
|
||||
GET @sso: /sso/@action = Controller\CcpSsoController->@action, 0
|
||||
GET @sso: /sso/@action = Controller\Ccp\Sso->@action, 0
|
||||
|
||||
; map page
|
||||
GET @map: /map = Controller\MapController->init, 0
|
||||
|
||||
@@ -642,7 +642,7 @@ define([
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(usersData);
|
||||
|
||||
var userDataTable = userTable.dataTable( {
|
||||
pageLength: 20,
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
public/img/landing/eve_sso_login_buttons_large_black.png
Normal file
BIN
public/img/landing/eve_sso_login_buttons_large_black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
public/img/landing/eve_sso_login_buttons_large_black_hover.png
Normal file
BIN
public/img/landing/eve_sso_login_buttons_large_black_hover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 174 KiB |
@@ -642,7 +642,7 @@ define([
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(usersData);
|
||||
|
||||
var userDataTable = userTable.dataTable( {
|
||||
pageLength: 20,
|
||||
|
||||
@@ -75,31 +75,21 @@
|
||||
<h2><span class="text-primary">Please</span> log in</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="pf-login-form" class="" role="form" method="post" action="#">
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-3 col-sm-offset-3">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="userName" id="userName" placeholder="Username" autocomplete="off" tabindex="1" data-error="Username required" autofocus required>
|
||||
<div class="help-block with-errors text-left"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div class="form-group">
|
||||
<input type="password" class="form-control" name="userPassword" id="userPassword" placeholder="Password" autocomplete="off" tabindex="2" data-error="Password required" required>
|
||||
<div class="help-block with-errors text-left"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* login message container *}
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div id="pf-login-message-container" class="col-sm-8 col-sm-offset-2"></div>
|
||||
<check if="{{ @SESSION.SSO.ERROR }}">
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<div class="alert alert-danger" >
|
||||
<span class="txt-color txt-color-danger">Access denied</span>
|
||||
<small>{{ @SESSION.SSO.ERROR }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</check>
|
||||
|
||||
{* check for setup mode *}
|
||||
<check if="{{ array_key_exists('/setup', @ROUTES) && @PATHFINDER.SHOW_SETUP_WARNING }}">
|
||||
@@ -130,23 +120,20 @@
|
||||
</div>
|
||||
</check>
|
||||
|
||||
{* signUp/logIn buttons *}
|
||||
<div class="row text-center">
|
||||
<div class="col-xs-12 col-sm-6 col-sm-offset-3">
|
||||
<div class="col-xs-6 col-sm-4 col-sm-offset-2" data-placement="left" title="{{@registrationStatusTitle}}">
|
||||
<button type="button" class="pf-register-button btn-block btn btn-primary {{@registrationStatusButton}}" tabindex="-1"><i class="fa fa-fw fa-user-plus"></i> Sign up</button>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4">
|
||||
<button type="submit" class="pf-login-button btn-block btn btn-success" tabindex="3"><i class="fa fa-fw fa-sign-in"></i> Log in</button>
|
||||
{* SSO login *}
|
||||
<div class="container-fluid">
|
||||
<div class="row text-center">
|
||||
<div class="col-xs-12">
|
||||
<a class="pf-sso-login-button {{@registrationStatusButton}}" href="{{ 'sso','action=requestAuthorization' | alias }}" type="button" tabindex="3" title="{{@registrationStatusTitle}}"> </a><br>
|
||||
<a class="font-lg" target="_blank" href="http://community.eveonline.com/news/dev-blogs/eve-online-sso-and-what-you-need-to-know">What is this?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<a href="{{ 'sso','action=requestAuthorization' | alias }}">SSO login</a>
|
||||
|
||||
{* features/ gallery *}
|
||||
<section id="pf-landing-gallery">
|
||||
|
||||
|
||||
@@ -314,9 +314,45 @@
|
||||
// login ----------------------------------------------------------------------
|
||||
#pf-landing-login{
|
||||
padding-top: 40px;
|
||||
padding-bottom: 30px;
|
||||
|
||||
.row{
|
||||
margin-bottom: 0px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.pf-sso-login-button{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 270px;
|
||||
height: 45px;
|
||||
border: none;
|
||||
margin-bottom: 10px;
|
||||
background-color: transparent;
|
||||
background-image: url("#{$base-url}/landing/eve_sso_login_buttons_large_black_hover.png");
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
@include transition(box-shadow 0.12s ease-out);
|
||||
will-change: box-shadow;
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 270px;
|
||||
height: 45px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-image: url("#{$base-url}/landing/eve_sso_login_buttons_large_black.png");
|
||||
@include transition(opacity 0.12s ease-in-out);
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
|
||||
|
||||
&:after{
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user