Example #1
0
 public function addToken($expiresAt, User $user, OAuthClient $client, array $scopes = [], $code = null)
 {
     $collection = $this->getDocumentManager()->getCollection('oAuthTokens');
     $accessTokenDocument = $collection->createDocument();
     $expiresDate = new \DateTime();
     $expiresDate->setTimestamp($expiresAt);
     $accessTokenDocument->setExpiresAt(\API\Util\Date::dateTimeToMongoDate($expiresDate));
     $currentDate = new \DateTime();
     $accessTokenDocument->setCreatedAt(\API\Util\Date::dateTimeToMongoDate($currentDate));
     $accessTokenDocument->addRelation('user', $user);
     $accessTokenDocument->addRelation('client', $client);
     $scopeIds = [];
     foreach ($scopes as $scope) {
         $scopeIds[] = $scope->getId();
     }
     $accessTokenDocument->setScopeIds($scopeIds);
     $accessTokenDocument->setToken(Util\OAuth::generateToken());
     if (null !== $code) {
         $accessTokenDocument->setCode($code);
     }
     $accessTokenDocument->save();
     $this->single = true;
     $this->setAccessTokens([$accessTokenDocument]);
     return $accessTokenDocument;
 }
Example #2
0
 public function setExpiresIn($expiresIn)
 {
     $until = \API\Util\Date::dateFromSeconds($expiresIn);
     $until = \API\Util\Date::dateStringToMongoDate($until);
     $this->setExpiresAt($until);
     return $this;
 }
Example #3
0
 /**
  * Creates a log entry from the given request
  *
  * @param Slim\Http\Request $request The request
  *
  * @return \API\Document\Log The log document
  */
 public function logRequest($request)
 {
     $collection = $this->getDocumentManager()->getCollection('logs');
     $document = $collection->createDocument();
     $document->setIp($request->getIp());
     $document->setMethod($request->getMethod());
     $document->setEndpoint($request->getPathInfo());
     $currentDate = new \DateTime();
     $document->setTimestamp(Util\Date::dateTimeToMongoDate($currentDate));
     $document->save();
     return $document;
 }
Example #4
0
 /**
  * Tries to create a new access token.
  */
 public function accessTokenPost($request)
 {
     $body = $request->getBody();
     $body = json_decode($body, true);
     // Some clients escape the JSON - handle them
     if (is_string($body)) {
         $body = json_decode($body, true);
     }
     if (json_last_error() !== JSON_ERROR_NONE) {
         throw new \Exception('Invalid JSON posted. Cannot continue!', Resource::STATUS_BAD_REQUEST);
     }
     $requestParams = new Set($body);
     if ($requestParams->get('user')['email'] === null) {
         throw new \Exception('Invalid request, user.email property not present!', Resource::STATUS_BAD_REQUEST);
     }
     $currentDate = new \DateTime();
     $defaultParams = new Set(['user' => ['password' => 'password', 'permissions' => ['all']], 'scopes' => ['all'], 'name' => 'Token for ' . $requestParams->get('user')['email'], 'description' => 'Token generated at ' . Util\Date::dateTimeToISO8601($currentDate), 'expiresAt' => null]);
     $params = new Set(array_replace_recursive($defaultParams->all(), $requestParams->all()));
     $scopeDocuments = [];
     $scopes = $params->get('scopes');
     foreach ($scopes as $scope) {
         $scopeDocument = $this->getScopeByName($scope);
         $scopeDocuments[] = $scopeDocument;
     }
     $permissionDocuments = [];
     $permissions = $params->get('user')['permissions'];
     foreach ($permissions as $permission) {
         $permissionDocument = $this->getScopeByName($permission);
         $permissionDocuments[] = $permissionDocument;
     }
     if (is_numeric($params->get('expiresAt'))) {
         $expiresAt = $params->get('expiresAt');
     } else {
         if (null === $params->get('expiresAt')) {
             $expiresAt = null;
         } else {
             $expiresAt = new \DateTime($params->get('expiresAt'));
             $expiresAt = $expiresAt->getTimestamp();
         }
     }
     $userService = new UserService($this->getSlim());
     $user = $userService->addUser($params->get('user')['email'], $params->get('user')['password'], $permissionDocuments);
     $user->save();
     $this->addToken($params->get('name'), $params->get('description'), $expiresAt, $user, $scopeDocuments);
     return $this;
 }
Example #5
0
 /**
  * Tries to PUT (replace) an activityState.
  *
  * @return
  */
 public function activityProfilePut($request)
 {
     // Validation has been completed already - everyhing is assumed to be valid (from an external view!)
     $rawBody = $request->getBody();
     // Single
     $params = new Set($request->get());
     $collection = $this->getDocumentManager()->getCollection('activityProfiles');
     $activityProfileDocument = $collection->createDocument();
     // Check for existing state - then replace if applicable
     $cursor = $collection->find();
     $cursor->where('profileId', $params->get('profileId'));
     $cursor->where('activityId', $params->get('activityId'));
     $result = $cursor->findOne();
     // Check If-Match and If-None-Match here
     if (!$request->headers('If-Match') && !$request->headers('If-Match') && $result) {
         throw new \Exception('There was a conflict. Check the current state of the resource and set the "If-Match" header with the current ETag to resolve the conflict.', Resource::STATUS_CONFLICT);
     }
     // If-Match first
     if ($request->headers('If-Match') && $result && $this->trimHeader($request->headers('If-Match')) !== $result->getHash()) {
         throw new \Exception('If-Match header doesn\'t match the current ETag.', Resource::STATUS_PRECONDITION_FAILED);
     }
     // Then If-None-Match
     if ($request->headers('If-None-Match')) {
         if ($this->trimHeader($request->headers('If-None-Match')) === '*' && $result) {
             throw new \Exception('If-None-Match header is *, but a resource already exists.', Resource::STATUS_PRECONDITION_FAILED);
         } elseif ($result && $this->trimHeader($request->headers('If-None-Match')) === $result->getHash()) {
             throw new \Exception('If-None-Match header matches the current ETag.', Resource::STATUS_PRECONDITION_FAILED);
         }
     }
     // ID exists, replace body
     if ($result) {
         $activityProfileDocument = $result;
     }
     $contentType = $request->headers('Content-Type');
     if ($contentType === null) {
         $contentType = 'text/plain';
     }
     $activityProfileDocument->setContent($rawBody);
     // Dates
     $currentDate = new \DateTime();
     $activityProfileDocument->setMongoTimestamp(Util\Date::dateTimeToMongoDate($currentDate));
     $activityProfileDocument->setActivityId($params->get('activityId'));
     $activityProfileDocument->setProfileId($params->get('profileId'));
     $activityProfileDocument->setContentType($contentType);
     $activityProfileDocument->setHash(sha1($rawBody));
     $activityProfileDocument->save();
     // Add to log
     $this->getSlim()->requestLog->addRelation('activityProfiles', $activityProfileDocument)->save();
     $this->single = true;
     $this->activityProfiles = [$activityProfileDocument];
     return $this;
 }
Example #6
0
 /**
  * Tries to PUT a statement with a specified statementId.
  *
  * @return
  */
 public function statementPut($request)
 {
     // Check for multipart request
     if ($request->isMultipart()) {
         $jsonRequest = $request->parts()->get(0);
     } else {
         $jsonRequest = $request;
     }
     // Validation has been completed already - everyhing is assumed to be valid (from an external view!)
     // TODO: Move header validation in json-schema as well
     if ($jsonRequest->getMediaType() !== 'application/json') {
         throw new \Exception('Media type specified in Content-Type header must be \'application/json\'!', Resource::STATUS_BAD_REQUEST);
     }
     // Validation has been completed already - everyhing is assumed to be valid
     $body = $jsonRequest->getBody();
     $body = json_decode($body, true);
     // Some clients escape the JSON - handle them
     if (is_string($body)) {
         $body = json_decode($body, true);
     }
     // Save attachments - this could be in a queue perhaps...
     if ($request->isMultipart()) {
         $fsAdapter = \API\Util\Filesystem::generateAdapter($this->getSlim()->config('filesystem'));
         $attachmentCollection = $this->getDocumentManager()->getCollection('attachments');
         $partCount = $request->parts()->count();
         for ($i = 1; $i < $partCount; $i++) {
             $part = $request->parts()->get($i);
             $attachmentBody = $part->getBody();
             $detectedEncoding = mb_detect_encoding($attachmentBody);
             $contentEncoding = $part->headers('Content-Transfer-Encoding');
             if ($detectedEncoding === 'UTF-8' && ($contentEncoding === null || $contentEncoding === 'binary')) {
                 try {
                     $attachmentBody = iconv('UTF-8', 'ISO-8859-1//IGNORE', $attachmentBody);
                 } catch (\Exception $e) {
                     //Use raw file on failed conversion (do nothing!)
                 }
             }
             $hash = $part->headers('X-Experience-API-Hash');
             $contentType = $part->headers('Content-Type');
             $attachmentDocument = $attachmentCollection->createDocument();
             $attachmentDocument->setSha2($hash);
             $attachmentDocument->setContentType($contentType);
             $attachmentDocument->setTimestamp(new MongoDate());
             $attachmentDocument->save();
             $fsAdapter->put($hash, $attachmentBody);
         }
     }
     $attachmentBase = $this->getSlim()->url->getBaseUrl() . $this->getSlim()->config('filesystem')['exposed_url'];
     // Single
     $params = new Set($request->get());
     $activityCollection = $this->getDocumentManager()->getCollection('activities');
     $collection = $this->getDocumentManager()->getCollection('statements');
     $cursor = $collection->find();
     // Single statement
     $cursor->where('statement.id', $params->get('statementId'));
     $result = $cursor->findOne();
     // ID exists, check if different or conflict
     if ($result) {
         // Same - return 204 No content
         if ($body === $result) {
             $this->match = true;
         } else {
             // Mismatch - return 409 Conflict
             throw new Exception('An existing statement already exists with the same ID and is different from the one provided.', Resource::STATUS_CONFLICT);
         }
     } else {
         // Store new statement
         $statementDocument = $collection->createDocument();
         // Overwrite authority - unless it's a super token and manual authority is set
         if (!($this->getAccessToken()->isSuperToken() && isset($statement['authority'])) || !isset($statement['authority'])) {
             $statement['authority'] = $this->getAccessToken()->generateAuthority();
         }
         // Check statementId
         if (isset($body['id'])) {
             //Check for match
             if ($body['id'] !== $params->get('statementId')) {
                 throw new \Exception('Statement ID query parameter doesn\'t match the given statement property', Resource::STATUS_BAD_REQUEST);
             }
         } else {
             $body['id'] = $params->get('statementId');
         }
         // Set the statement
         $statementDocument->setStatement($body);
         // Dates
         $currentDate = new \DateTime();
         $statementDocument->setStored(Util\Date::dateTimeToISO8601($currentDate));
         $statementDocument->setMongoTimestamp(Util\Date::dateTimeToMongoDate($currentDate));
         $statementDocument->setDefaultTimestamp();
         $statementDocument->fixAttachmentLinks($attachmentBase);
         if ($statementDocument->isReferencing()) {
             // Copy values of referenced statement chain inside current statement for faster query-ing
             // (space-time tradeoff)
             $referencedStatement = $statementDocument->getReferencedStatement();
             $existingReferences = [];
             if (null !== $referencedStatement->getReferences()) {
                 $existingReferences = $referencedStatement->getReferences();
             }
             $statementDocument->setReferences(array_push($existingReferences, $referencedStatement->getStatement()));
         }
         if ($statementDocument->isVoiding()) {
             $referencedStatement = $statementDocument->getReferencedStatement();
             $referencedStatement->setVoided(true);
             $referencedStatement->save();
         }
         if ($this->getAccessToken()->hasPermission('define')) {
             $activities = $statementDocument->extractActivities();
             if (count($activities) > 0) {
                 $activityCollection->insertMultiple($activities);
             }
         }
         $statementDocument->save();
         // Add to log
         $this->getSlim()->requestLog->addRelation('statements', $statementDocument)->save();
         $this->single = true;
         $this->statements = [$statementDocument];
     }
     return $this;
 }
Example #7
0
 /**
  * Tries to PUT (replace) an activityState.
  *
  * @return
  */
 public function activityStatePut($request)
 {
     // Validation has been completed already - everyhing is assumed to be valid (from an external view!)
     $rawBody = $request->getBody();
     // Single
     $params = new Set($request->get());
     $collection = $this->getDocumentManager()->getCollection('activityStates');
     $activityStateDocument = $collection->createDocument();
     // Check for existing state - then replace if applicable
     $cursor = $collection->find();
     $cursor->where('stateId', $params->get('stateId'));
     $cursor->where('activityId', $params->get('activityId'));
     $agent = $params->get('agent');
     $agent = json_decode($agent, true);
     //Fetch the identifier - otherwise we'd have to order the JSON
     if (isset($agent['mbox'])) {
         $uniqueIdentifier = 'mbox';
     } elseif (isset($agent['mbox_sha1sum'])) {
         $uniqueIdentifier = 'mbox_sha1sum';
     } elseif (isset($agent['openid'])) {
         $uniqueIdentifier = 'openid';
     } elseif (isset($agent['account'])) {
         $uniqueIdentifier = 'account';
     } else {
         throw new Exception('Invalid request!', Resource::STATUS_BAD_REQUEST);
     }
     $cursor->where('agent.' . $uniqueIdentifier, $agent[$uniqueIdentifier]);
     if ($params->has('registration')) {
         $cursor->where('registration', $params->get('registration'));
     }
     $result = $cursor->findOne();
     $contentType = $request->headers('Content-Type');
     if ($contentType === null) {
         $contentType = 'text/plain';
     }
     // ID exists, replace
     if ($result) {
         $activityStateDocument = $result;
     }
     $activityStateDocument->setContent($rawBody);
     // Dates
     $currentDate = new \DateTime();
     $activityStateDocument->setMongoTimestamp(Util\Date::dateTimeToMongoDate($currentDate));
     $activityStateDocument->setActivityId($params->get('activityId'));
     $activityStateDocument->setAgent($agent);
     if ($params->has('registration')) {
         $activityStateDocument->setRegistration($params->get('registration'));
     }
     $activityStateDocument->setStateId($params->get('stateId'));
     $activityStateDocument->setContentType($contentType);
     $activityStateDocument->setHash(sha1($rawBody));
     $activityStateDocument->save();
     // Add to log
     $this->getSlim()->requestLog->addRelation('activityStates', $activityStateDocument)->save();
     $this->single = true;
     $this->activityStates = [$activityStateDocument];
     return $this;
 }