public function addToken($name, $description, $expiresAt, User $user, array $scopes = []) { $collection = $this->getDocumentManager()->getCollection('basicTokens'); $accessTokenDocument = $collection->createDocument(); $accessTokenDocument->setName($name); $accessTokenDocument->setDescription($description); $accessTokenDocument->addRelation('user', $user); $scopeIds = []; foreach ($scopes as $scope) { $scopeIds[] = $scope->getId(); } $accessTokenDocument->setScopeIds($scopeIds); if (isset($expiresAt)) { $expiresDate = new \DateTime(); $expiresDate->setTimestamp($expiresAt); $accessTokenDocument->setExpiresAt(\API\Util\Date::dateTimeToMongoDate($expiresDate)); } //Generate token $accessTokenDocument->setKey(\API\Util\OAuth::generateToken()); $accessTokenDocument->setSecret(\API\Util\OAuth::generateToken()); $currentDate = new \DateTime(); $accessTokenDocument->setCreatedAt(\API\Util\Date::dateTimeToMongoDate($currentDate)); $accessTokenDocument->save(); $this->single = true; $this->setAccessTokens([$accessTokenDocument]); return $accessTokenDocument; }
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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }