/** * @param $user User * @param $emailServiceId * @param $emailTemplateId * @param bool|true $deleteOnError * * @throws \DreamFactory\Core\Exceptions\InternalServerErrorException */ protected static function sendConfirmation($user, $emailServiceId, $emailTemplateId, $deleteOnError = true) { try { if (empty($emailServiceId)) { throw new InternalServerErrorException('No email service configured for user invite. See system configuration.'); } if (empty($emailTemplateId)) { throw new InternalServerErrorException("No default email template for user invite."); } /** @var EmailService $emailService */ $emailService = ServiceHandler::getServiceById($emailServiceId); $emailTemplate = EmailTemplate::find($emailTemplateId); if (empty($emailTemplate)) { throw new InternalServerErrorException("No data found in default email template for user invite."); } try { $email = $user->email; $code = \Hash::make($email); $user->confirm_code = base64_encode($code); $user->save(); $templateData = $emailTemplate->toArray(); $data = array_merge($templateData, ['to' => $email, 'confirm_code' => $user->confirm_code, 'link' => url(\Config::get('df.confirm_register_url')) . '?code=' . $user->confirm_code, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'name' => $user->name, 'email' => $user->email, 'phone' => $user->phone, 'content_header' => ArrayUtils::get($templateData, 'subject', 'Confirm your DreamFactory account.'), 'instance_name' => \Config::get('df.instance_name')]); } catch (\Exception $e) { throw new InternalServerErrorException("Error creating user confirmation.\n{$e->getMessage()}", $e->getCode()); } $emailService->sendEmail($data, $emailTemplate->body_text, $emailTemplate->body_html); } catch (\Exception $e) { if ($deleteOnError) { $user->delete(); } throw new InternalServerErrorException("Error processing user confirmation.\n{$e->getMessage()}", $e->getCode()); } }
/** * Authenticates valid user. * * @return array * @throws \DreamFactory\Core\Exceptions\BadRequestException * @throws \DreamFactory\Core\Exceptions\UnauthorizedException */ protected function handlePOST() { $serviceName = $this->getPayloadData('service'); if (empty($serviceName)) { $serviceName = $this->request->getParameter('service'); } if (!empty($serviceName)) { $service = ServiceHandler::getService($serviceName); $serviceModel = Service::find($service->getServiceId()); $serviceType = $serviceModel->serviceType()->first(); $serviceGroup = $serviceType->group; if (!in_array($serviceGroup, [ServiceTypeGroups::OAUTH, ServiceTypeGroups::LDAP])) { throw new BadRequestException('Invalid login service provided. Please use an OAuth or AD/Ldap service.'); } if ($serviceGroup === ServiceTypeGroups::LDAP) { $credentials = ['username' => $this->getPayloadData('username'), 'password' => $this->getPayloadData('password')]; return $service->handleLogin($credentials, $this->getPayloadData('remember_me')); } elseif ($serviceGroup === ServiceTypeGroups::OAUTH) { $oauthCallback = $this->request->getParameterAsBool('oauth_callback'); if (!empty($oauthCallback)) { return $service->handleOAuthCallback(); } else { return $service->handleLogin($this->request->getDriver()); } } } else { $credentials = ['email' => $this->getPayloadData('email'), 'password' => $this->getPayloadData('password'), 'is_sys_admin' => false]; return $this->handleLogin($credentials, boolval($this->getPayloadData('remember_me'))); } }
protected function createUser($num) { $user = $this->{'user' . $num}; $payload = json_encode([$user], JSON_UNESCAPED_SLASHES); $this->service = ServiceHandler::getService('system'); $rs = $this->makeRequest(Verbs::POST, 'user', [ApiOptions::FIELDS => '*', ApiOptions::RELATED => 'user_lookup_by_user_id'], $payload); $this->service = ServiceHandler::getService($this->serviceId); $data = $rs->getContent(); return Arr::get($data, static::$wrapper . '.0'); }
public function testUnauthorizedSessionRequest() { $user = $this->user1; $this->makeRequest(Verbs::POST, 'user', [ApiOptions::FIELDS => '*', ApiOptions::RELATED => 'user_lookup_by_user_id'], [$user]); Session::authenticate(['email' => $user['email'], 'password' => $user['password']]); //Using a new instance here. Prev instance is set for user resource. $this->service = ServiceHandler::getService('system'); $this->setExpectedException('\\DreamFactory\\Core\\Exceptions\\UnauthorizedException'); $this->makeRequest(Verbs::GET, static::RESOURCE . '/session'); }
/** * Handles DELETE action * * @return array * @throws NotImplementedException */ protected function handleDELETE() { if (empty($this->resource)) { \Cache::flush(); } else { $service = ServiceHandler::getService($this->resource); if ($service instanceof CachedInterface) { $service->flush(); } else { throw new NotImplementedException('Service does not implement API controlled cache.'); } } return ['success' => true]; }
public function testPOSTRegister() { $u = $this->user1; $password = Arr::get($u, 'password'); $payload = ['first_name' => Arr::get($u, 'first_name'), 'last_name' => Arr::get($u, 'last_name'), 'name' => Arr::get($u, 'name'), 'email' => Arr::get($u, 'email'), 'phone' => Arr::get($u, 'phone'), 'security_question' => Arr::get($u, 'security_question'), 'security_answer' => Arr::get($u, 'security_answer'), 'password' => $password, 'password_confirmation' => Arr::get($u, 'password_confirmation', $password)]; Session::setUserInfoWithJWT(User::find(1)); $r = $this->makeRequest(Verbs::POST, static::RESOURCE, [], $payload); $c = $r->getContent(); $this->assertTrue(Arr::get($c, 'success')); Session::set('role.name', 'test'); Session::set('role.id', 1); $this->service = ServiceHandler::getService('user'); $r = $this->makeRequest(Verbs::POST, 'session', [], ['email' => Arr::get($u, 'email'), 'password' => Arr::get($u, 'password')]); $c = $r->getContent(); $this->assertTrue(!empty(Arr::get($c, 'session_id'))); }
/** * {@inheritdoc} */ protected static function sendPasswordResetEmail(User $user) { $email = $user->email; $userService = Service::getCachedByName('user'); $config = $userService['config']; if (empty($config)) { throw new InternalServerErrorException('Unable to load user service configuration.'); } $emailServiceId = $config['password_email_service_id']; if (!empty($emailServiceId)) { try { /** @var EmailService $emailService */ $emailService = ServiceHandler::getServiceById($emailServiceId); if (empty($emailService)) { throw new ServiceUnavailableException("Bad service identifier '{$emailServiceId}'."); } $data = []; $templateId = $config['password_email_template_id']; if (!empty($templateId)) { $data = $emailService::getTemplateDataById($templateId); } if (empty($data) || !is_array($data)) { throw new ServiceUnavailableException("No data found in default email template for password reset."); } $data['to'] = $email; $data['content_header'] = 'Password Reset'; $data['first_name'] = $user->first_name; $data['last_name'] = $user->last_name; $data['name'] = $user->name; $data['phone'] = $user->phone; $data['email'] = $user->email; $data['link'] = url(\Config::get('df.confirm_reset_url')) . '?code=' . $user->confirm_code; $data['confirm_code'] = $user->confirm_code; $emailService->sendEmail($data, ArrayUtils::get($data, 'body_text'), ArrayUtils::get($data, 'body_html')); return true; } catch (\Exception $ex) { throw new InternalServerErrorException("Error processing password reset.\n{$ex->getMessage()}"); } } return false; }
/** * Execute the console command. * * @return mixed */ public function handle() { try { $data = $this->argument('data'); if (filter_var($data, FILTER_VALIDATE_URL)) { // need to download file $data = FileUtilities::importUrlFileToTemp($data); } if (is_file($data)) { $data = file_get_contents($data); } $format = $this->option('format'); $format = DataFormats::toNumeric($format); $this->comment($format); $service = $this->option('service'); $resource = $this->option('resource'); $result = ServiceHandler::handleRequest(Verbs::POST, $service, $resource, [], $data, $format); $this->info('Import complete!'); } catch (\Exception $e) { $this->error($e->getMessage()); } }
public function testApiKeyUserRole() { $user = ['name' => 'John Doe', 'first_name' => 'John', 'last_name' => 'Doe', 'email' => '*****@*****.**', 'password' => 'test1234', 'security_question' => 'Make of your first car?', 'security_answer' => 'mazda', 'is_active' => true]; $role = ['name' => 'test_role', 'is_active' => true, 'role_service_access_by_role_id' => [['service_id' => 1, 'component' => 'config', 'verb_mask' => 1, 'requestor_mask' => 1]]]; $this->service = ServiceHandler::getService('system'); $rs = $this->makeRequest(Verbs::POST, 'user', [], [$user]); $data = $rs->getContent(); $userId = Arr::get($data, static::$wrapper . '.0.id'); $this->service = ServiceHandler::getService('system'); $rs = $this->makeRequest(Verbs::POST, 'role', [], [$role]); $data = $rs->getContent(); $roleId = Arr::get($data, static::$wrapper . '.0.id'); \DreamFactory\Core\Models\UserAppRole::create(['user_id' => $userId, 'app_id' => 1, 'role_id' => $roleId]); $app = App::find(1); $apiKey = $app->api_key; $myUser = User::find($userId); $token = JWTUtilities::makeJWTByUser($myUser->id, $myUser->email); $this->call(Verbs::GET, '/api/v2/system', [], [], [], ['HTTP_X_DREAMFACTORY_API_KEY' => $apiKey, 'HTTP_X_DREAMFACTORY_SESSION_TOKEN' => $token]); $this->assertFalse(Session::isSysAdmin()); $this->assertEquals($roleId, Session::get('role.id')); $rsa = Session::get('role.services'); $this->assertTrue(!empty($rsa)); }
/** * Handles all service requests * * @param null|string $version * @param string $service * @param null|string $resource * * @return ServiceResponseInterface|null */ public function handleService($version = null, $service, $resource = null) { try { $service = strtolower($service); // fix removal of trailing slashes from resource if (!empty($resource)) { $uri = \Request::getRequestUri(); if (false === strpos($uri, '?') && '/' === substr($uri, strlen($uri) - 1, 1) || '/' === substr($uri, strpos($uri, '?') - 1, 1)) { $resource .= '/'; } } $response = ServiceHandler::processRequest($version, $service, $resource); } catch (\Exception $e) { $response = ResponseFactory::create($e); } if ($response instanceof RedirectResponse) { return $response; } return ResponseFactory::sendResponse($response, null, null, $resource); }
/** * Execute the console command. * * @return mixed */ public function handle() { if (!class_exists('DreamFactory\\Core\\ADLdap\\Services\\ADLdap')) { $this->error('Command unavailable. Please install \'dreamfactory/df-adldap\' package to use this command.'); return; } try { $serviceName = $this->argument('service'); $username = $this->option('username'); $password = $this->option('password'); /** @type ADLdap $service */ $service = ServiceHandler::getService($serviceName); $serviceModel = Service::find($service->getServiceId()); $serviceType = $serviceModel->serviceType()->first(); $serviceGroup = $serviceType->group; if ($serviceGroup !== ServiceTypeGroups::LDAP) { throw new BadRequestException('Invalid service name [' . $serviceName . ']. Please use a valid Active Directory service'); } $this->line('Contacting your Active Directory server...'); $service->authenticateAdminUser($username, $password); $this->line('Fetching Active Directory groups...'); $groups = $service->getDriver()->listGroup(['dn', 'description']); $roles = []; foreach ($groups as $group) { $dfRole = RoleADLdap::whereDn($group['dn'])->first(); if (empty($dfRole)) { $role = ['name' => static::dnToRoleName($group['dn']), 'description' => $group['description'], 'is_active' => true, 'role_adldap_by_role_id' => [['dn' => $group['dn']]]]; $this->info('|--------------------------------------------------------------------'); $this->info('| DN: ' . $group['dn']); $this->info('| Role Name: ' . $role['name']); $this->info('| Description: ' . $role['description']); $this->info('|--------------------------------------------------------------------'); $roles[] = $role; } } $roleCount = count($roles); if ($roleCount > 0) { $this->warn('Total Roles to import: [' . $roleCount . ']'); if ($this->confirm('The above roles will be imported into your DreamFactroy instance based on your Active Directory groups. Do you wish to continue?')) { $this->line('Importing Roles...'); $payload = ResourcesWrapper::wrapResources($roles); ServiceHandler::handleRequest(Verbs::POST, 'system', 'role', ['continue' => true], $payload); $this->info('Successfully imported all Active Directory groups as Roles.'); } else { $this->info('Aborted import process. No Roles were imported'); } } else { if (count($groups) > 0 && $roleCount === 0) { $this->info('All groups found on the Active Directory server are already imported.'); } else { $this->warn('No group was found on Active Directory server.'); } } } catch (RestException $e) { $this->error($e->getMessage()); if ($this->option('verbose')) { $this->error(print_r($e->getContext(), true)); } } catch (\Exception $e) { $this->error($e->getMessage()); } }
/** * @param string $method * @param string $path * @param array $payload * @param array $curlOptions Additional CURL options for external requests * * @return array */ public static function inlineRequest($method, $path, $payload = null, $curlOptions = []) { if (null === $payload || 'null' == $payload) { $payload = []; } if (!empty($curlOptions)) { $options = []; foreach ($curlOptions as $key => $value) { if (!is_numeric($key)) { if (defined($key)) { $options[constant($key)] = $value; } } } $curlOptions = $options; unset($options); } try { if ('https:/' == ($protocol = substr($path, 0, 7)) || 'http://' == $protocol) { $result = static::externalRequest($method, $path, $payload, $curlOptions); } else { $result = null; $params = []; if (false !== ($pos = strpos($path, '?'))) { $paramString = substr($path, $pos + 1); if (!empty($paramString)) { $pArray = explode('&', $paramString); foreach ($pArray as $k => $p) { if (!empty($p)) { $tmp = explode('=', $p); $name = ArrayUtils::get($tmp, 0, $k); $value = ArrayUtils::get($tmp, 1); $params[$name] = urldecode($value); } } } $path = substr($path, 0, $pos); } if (false === ($pos = strpos($path, '/'))) { $serviceName = $path; $resource = null; } else { $serviceName = substr($path, 0, $pos); $resource = substr($path, $pos + 1); // Fix removal of trailing slashes from resource if (!empty($resource)) { if (false === strpos($path, '?') && '/' === substr($path, strlen($path) - 1, 1) || '/' === substr($path, strpos($path, '?') - 1, 1)) { $resource .= '/'; } } } if (empty($serviceName)) { return null; } $format = DataFormats::PHP_ARRAY; if (!is_array($payload)) { $format = DataFormats::TEXT; } Session::checkServicePermission($method, $serviceName, $resource, ServiceRequestorTypes::SCRIPT); $request = new ScriptServiceRequest($method, $params); $request->setContent($payload, $format); // Now set the request object and go... $service = ServiceHandler::getService($serviceName); $result = $service->handleRequest($request, $resource); } } catch (\Exception $ex) { $result = ResponseFactory::create($ex); Log::error('Exception: ' . $ex->getMessage(), ['response' => $result]); } return ResponseFactory::sendScriptResponse($result); }
/** * Deletes hosted app files from storage. * * @param $id * @param $storageServiceId * @param $storageFolder */ protected static function deleteHostedAppStorage($id, $storageServiceId, $storageFolder) { $app = AppModel::whereId($id)->first(); if (empty($app) && !empty($storageServiceId) && !empty($storageFolder)) { /** @type BaseFileService $storageService */ $storageService = ServiceHandler::getServiceById($storageServiceId); if ($storageService->driver()->folderExists(null, $storageFolder)) { $storageService->driver()->deleteFolder(null, $storageFolder, true); } } }
/** * @param $id * * @return mixed */ public static function getServiceById($id) { return ServiceHandler::getServiceById($id); }
/** * Package schemas for export. * * @return bool * @throws \DreamFactory\Core\Exceptions\InternalServerErrorException */ private function packageSchemas() { if (!empty($this->exportSchemas)) { $schemas = []; foreach ($this->exportSchemas as $serviceName => $component) { if (is_array($component)) { $component = implode(',', $component); } if (is_numeric($serviceName)) { /** @type Service $service */ $service = Service::find($serviceName); } else { /** @type Service $service */ $service = Service::whereName($serviceName)->whereDeletable(1)->first(); } if (!empty($service) && !empty($component)) { if ($service->type === 'sql_db') { $schema = ServiceHandler::handleRequest(Verbs::GET, $serviceName, '_schema', ['ids' => $component]); $schemas[] = ['name' => $serviceName, 'table' => $this->resourceWrapped ? $schema[$this->resourceWrapper] : $schema]; } } } if (!empty($schemas) && !$this->zip->addFromString('schema.json', json_encode(['service' => $schemas], JSON_UNESCAPED_SLASHES))) { throw new InternalServerErrorException("Can not include database schema in package file."); } return true; } return false; }
/** * @param $userId * @param bool|false $deleteOnError * * @throws \DreamFactory\Core\Exceptions\BadRequestException * @throws \DreamFactory\Core\Exceptions\InternalServerErrorException * @throws \DreamFactory\Core\Exceptions\NotFoundException * @throws \Exception */ protected static function sendInvite($userId, $deleteOnError = false) { /** @type BaseSystemModel $user */ $user = \DreamFactory\Core\Models\User::find($userId); if (empty($user)) { throw new NotFoundException('User not found with id ' . $userId . '.'); } if ('y' === strtolower($user->confirm_code)) { throw new BadRequestException('User with this identifier has already confirmed this account.'); } try { $userService = Service::getCachedByName('user'); $config = $userService['config']; if (empty($config)) { throw new InternalServerErrorException('Unable to load system configuration.'); } $emailServiceId = $config['invite_email_service_id']; $emailTemplateId = $config['invite_email_template_id']; if (empty($emailServiceId)) { throw new InternalServerErrorException('No email service configured for user invite.'); } if (empty($emailTemplateId)) { throw new InternalServerErrorException("No default email template for user invite."); } /** @var EmailService $emailService */ $emailService = ServiceHandler::getServiceById($emailServiceId); $emailTemplate = EmailTemplate::find($emailTemplateId); if (empty($emailTemplate)) { throw new InternalServerErrorException("No data found in default email template for user invite."); } try { $email = $user->email; $code = \Hash::make($email); $user->confirm_code = base64_encode($code); $user->save(); $templateData = $emailTemplate->toArray(); $data = array_merge($templateData, ['to' => $email, 'confirm_code' => $user->confirm_code, 'link' => url(\Config::get('df.confirm_invite_url')) . '?code=' . $user->confirm_code, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'name' => $user->name, 'email' => $user->email, 'phone' => $user->phone, 'content_header' => ArrayUtils::get($templateData, 'subject', 'You are invited to try DreamFactory.'), 'instance_name' => \Config::get('df.instance_name')]); } catch (\Exception $e) { throw new InternalServerErrorException("Error creating user invite. {$e->getMessage()}", $e->getCode()); } $emailService->sendEmail($data, $emailTemplate->body_text, $emailTemplate->body_html); } catch (\Exception $e) { if ($deleteOnError) { $user->delete(); } throw new InternalServerErrorException("Error processing user invite. {$e->getMessage()}", $e->getCode()); } }