/** * How to use Relation::deleteLink() to delete link (a1,b1) from r: * r :: A * B * deleteLink(a1[A], b1[B], false); * deleteLink(b1[B], a1[A], true); * * @param Atom $leftAtom * @param Atom $rightAtom * @param boolean $isFlipped * @param string $source specifies who calls this function (e.g. 'User' or 'ExecEngine') * @return void */ public function deleteLink($leftAtom, $rightAtom, $isFlipped = false, $source = 'User') { $this->logger->debug("Delete link ({$leftAtom->__toString()},{$rightAtom->__toString()}) from relation '{$this->__toString()}{({$isFlipped} ? '~' : '')}'"); // Determine src and tgt atom based on $isFlipped $srcAtom = $isFlipped ? $rightAtom : $leftAtom; $tgtAtom = $isFlipped ? $leftAtom : $rightAtom; // Checks if (!in_array($srcAtom->concept, $this->srcConcept->getSpecializationsIncl())) { throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$this->__toString()}', because source concept does not match relation source or its specializations", 500); } if (!in_array($tgtAtom->concept, $this->tgtConcept->getSpecializationsIncl())) { throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$this->__toString()}', because target concept does not match relation target or its specializations", 500); } // Delete link from relation table $this->db->deleteLink($this, $srcAtom, $tgtAtom); // Flag session var as affected when src or tgt concept of this relation is SESSION if ($srcAtom->concept->isSession() || $tgtAtom->concept->isSession()) { Session::singleton()->setSessionVarAffected(); } }
private function login($email) { if (empty($email)) { throw new Exception("No emailaddress provided to login", 500); } $session = Session::singleton(); $db = Database::singleton(); $conceptUserID = Concept::getConceptByLabel('UserID'); $conceptDomain = Concept::getConceptByLabel('Domain'); $conceptDateTime = Concept::getConceptByLabel('DateTime'); $conceptOrg = Concept::getConceptByLabel('Organization'); $conceptAccount = Concept::getConceptByLabel('Account'); $conceptSession = Concept::getConceptByLabel('SESSION'); // Set sessionUser $atom = new Atom($email, $conceptUserID); $accounts = $atom->ifc('AccountForUserid')->getTgtAtoms(); // create new user if (empty($accounts)) { $newAccount = Concept::getConceptByLabel('Account')->createNewAtom(); // Save email as accUserid $relAccUserid = Relation::getRelation('accUserid', $newAccount->concept, $conceptUserID); $relAccUserid->addLink($newAccount, new Atom($email, $conceptUserID), false, 'OAuthLoginExtension'); // If possible, add account to organization(s) based on domain name $domain = explode('@', $email)[1]; $atom = new Atom($domain, $conceptDomain); $orgs = $atom->ifc('DomainOrgs')->getTgtAtoms(); $relAccOrg = Relation::getRelation('accOrg', $newAccount->concept, $conceptOrg); foreach ($orgs as $org) { $relAccOrg->addLink($newAccount, $org, false, 'OAuthLoginExtension'); } // Account created, add to $accounts list (used lateron) $accounts[] = $newAccount; } if (count($accounts) > 1) { throw new Exception("Multiple users registered with email {$email}", 401); } $relSessionAccount = Relation::getRelation('sessionAccount', $conceptSession, $conceptAccount); $relAccMostRecentLogin = Relation::getRelation('accMostRecentLogin', $conceptAccount, $conceptDateTime); $relAccLoginTimestamps = Relation::getRelation('accLoginTimestamps', $conceptAccount, $conceptDateTime); foreach ($accounts as $account) { // Set sessionAccount $relSessionAccount->addLink($session->sessionAtom, $account, false, 'OAuthLoginExtension'); // Timestamps $ts = new Atom(date(DATE_ISO8601), $conceptDateTime); $relAccMostRecentLogin->addLink($account, $ts, false, 'OAuthLoginExtension'); $relAccLoginTimestamps->addLink($account, $ts, false, 'OAuthLoginExtension'); } $db->closeTransaction('Login successfull', true); }
use Ampersand\Core\Atom; use Ampersand\Core\Concept; use Ampersand\Output\OutputCSV; global $app; $app->get('/admin/installer', function () use($app) { if (Config::get('productionEnv')) { throw new Exception("Database reinstall not allowed in production environment", 403); } $defaultPop = filter_var($app->request->params('defaultPop'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); if (is_null($defaultPop)) { $defaultPop = true; } Database::createDB(); $db = Database::singleton(); $db->reinstallDB($defaultPop); $session = Session::singleton(); $roleIds = $app->request->params('roleIds'); $session->activateRoles($roleIds); $content = Notifications::getAll(); // Return all notifications print json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); }); $app->get('/admin/checks/rules/evaluate/all', function () use($app) { if (Config::get('productionEnv')) { throw new Exception("Database reinstall not allowed in production environment", 403); } foreach (Rule::getAllInvRules() as $rule) { foreach ($rule->getViolations() as $violation) { Notifications::addInvariant($violation); } }
/** * Build links to interfaces to solve the violation * @return array */ public function getLinks() { $session = Session::singleton(); $links = array(); foreach ($session->getInterfacesToReadConcept($this->src->concept) as $interface) { $links[] = "#/{$interface->id}/{$this->src->getJsonRepresentation()}"; } foreach ($session->getInterfacesToReadConcept($this->tgt->concept) as $interface) { $links[] = "#/{$interface->id}/{$this->tgt->getJsonRepresentation()}"; } return array_unique($links); }
/** * * @return Violation[] */ public static function getSignalViolationsFromDB() { $logger = Logger::getLogger('FW'); $session = Session::singleton(); $dbsignalTableName = Config::get('dbsignalTableName', 'mysqlDatabase'); $conjuncts = array(); $conjunctRuleMap = array(); foreach ($session->rulesToMaintain as $rule) { foreach ($rule->conjuncts as $conjunct) { $conjunctRuleMap[$conjunct->id][] = $rule; } $conjuncts = array_merge($conjuncts, $rule->conjuncts); } $conjuncts = array_unique($conjuncts); // remove duplicates $violations = array(); if (count($conjuncts) > 0) { $q = implode(',', array_map(function ($conj) { return "'{$conj->id}'"; }, $conjuncts)); // returns string "<conjId1>,<conjId2>,<etc>" $query = "SELECT * FROM `{$dbsignalTableName}` WHERE `conjId` IN ({$q})"; $result = $session->database->Exe($query); // array(array('conjId' => '<conjId>', 'src' => '<srcAtomId>', 'tgt' => '<tgtAtomId>')) foreach ($result as $row) { foreach ($conjunctRuleMap[$row['conjId']] as $rule) { $violations[] = new Violation($rule, $row['src'], $row['tgt']); } } } else { $logger->debug("No conjuncts to check (it can be that this role does not maintain any rule)"); } return $violations; }
/** * Function to reinstall database structure and load default population * @param boolean $loadDefaultPop specifies whether or not to install the default population * @return void */ public function reinstallDB($installDefaultPop = true) { $queries = file_get_contents(Config::get('pathToGeneratedFiles') . 'mysql-installer.json'); $queries = json_decode($queries, true); $this->logger->info("Start database reinstall"); $this->logger->info("Execute database structure queries"); foreach ($queries['allDBstructQueries'] as $query) { $this->Exe($query); set_time_limit((int) ini_get('max_execution_time')); // reset time limit counter to handle large amounts of create table / index queries. } if ($installDefaultPop) { $this->logger->info("Install default population"); if (Config::get('checkDefaultPopulation', 'transactions')) { $this->startTransaction(); } foreach ($queries['allDefPopQueries'] as $query) { $this->Exe($query); set_time_limit((int) ini_get('max_execution_time')); // reset time limit counter to handle large amounts of default population queries. } } else { $this->logger->info("Skip default population"); } // Ininiate new session Session::reInit(); Hooks::callHooks('postDatabaseReinstallDB', get_defined_vars()); $this->logger->info("Database reinstalled"); // Initial conjunct evaluation Conjunct::evaluateConjuncts(null, true); // Evaluate, cache and store all conjuncts, not only those that are affected (done by closeTransaction() function) $this->closeTransaction('Database successfully reinstalled', true); }
/** * Returns the content of this atom given the parentIfc object * @param array $options * @param array $recursionArr * @param int $depth specifies the number subinterface levels to get the content for * @throws Exception * @return mixed */ public function getContent($options = array(), $recursionArr = array(), $depth = null) { $session = Session::singleton(); // Default options $options['metaData'] = isset($options['metaData']) ? filter_var($options['metaData'], FILTER_VALIDATE_BOOLEAN) : true; $options['navIfc'] = isset($options['navIfc']) ? filter_var($options['navIfc'], FILTER_VALIDATE_BOOLEAN) : true; if (isset($options['depth']) && is_null($depth)) { $depth = $options['depth']; } // initialize depth, if specified in options array $content = array('_id_' => $this->getJsonRepresentation(), '_label_' => $this->getLabel(), '_view_' => $this->getView()); // Meta data if ($options['metaData']) { $content['_path_'] = $this->path; } // Define interface(s) to navigate to for this tgtAtom if ($options['navIfc']) { $ifcs = array(); if ($this->parentIfc->isLinkTo) { if ($session->isAccessibleIfc($this->parentIfc->refInterfaceId)) { $ifcs[] = array('id' => $this->parentIfc->refInterfaceId, 'label' => $this->parentIfc->refInterfaceId, 'url' => $this->url . '/' . $this->parentIfc->refInterfaceId); } } else { $ifcs = array_map(function ($o) { return array('id' => $o->id, 'label' => $o->label, 'url' => $this->url . '/' . $o->id); }, $session->getInterfacesToReadConcept($this->concept)); } $content['_ifcs_'] = $ifcs; } // Get content of subinterfaces if depth is not provided or max depth not yet reached if (is_null($depth) || $depth > 0) { // Decrease depth by 1 if (!is_null($depth)) { $depth--; } // Subinterfaces foreach ($this->parentIfc->subInterfaces as $subinterface) { // Skip subinterface if not given read rights if (!$subinterface->crudR) { continue; } $subcontent = $this->ifc($subinterface->id)->getContent($options, $recursionArr, $depth); $content[$subinterface->id] = $subcontent; // _sortValues_ (if subInterface is uni) if ($subinterface->isUni && $options['metaData']) { if (is_bool($subcontent)) { $sortValue = $subcontent; } elseif ($subinterface->tgtConcept->isObject) { $sortValue = current((array) $subcontent)['_label_']; } else { $sortValue = $subcontent; } // scalar $content['_sortValues_'][$subinterface->id] = $sortValue; } } } return $content; }
public static function getNavBarIfcs($menu) { $session = Session::singleton(); $navBarIfcs = array(); // Add public interfaces $interfaces = InterfaceObject::getPublicInterfaces(); // Add interfaces for active roles foreach ($session->getActiveRoles() as $role) { $interfaces = array_merge($interfaces, $role->interfaces()); } // Filter duplicate interfaces $interfaces = array_unique($interfaces); // Filter interfaces for requested part of navbar $interfaces = array_filter($interfaces, function ($ifc) use($menu) { switch ($menu) { case 'top': if (($ifc->srcConcept->name == 'SESSION' || $ifc->srcConcept->name == 'ONE') && $ifc->crudR) { return true; } else { return false; } case 'new': // crudC, otherwise the atom cannot be created // isIdent (interface expr = I[Concept]), because otherwise a src atom is necesarry, which we don't have wiht +-menu if ($ifc->crudC && $ifc->isIdent) { return true; } else { return false; } default: throw new Exception("Cannot get navbar interfaces. Unknown menu: '{$menu}'", 500); } }); // Create return object $result = array_map(function ($ifc) { return array('id' => $ifc->id, 'label' => $ifc->label, 'link' => '/' . $ifc->id); }, $interfaces); return array_values($result); // reindex array }