/**
  * Authenticate an incoming request.
  *
  * @param \Illuminate\Http\Request $request
  * @param \Closure                 $next
  *
  * @return mixed
  */
 public function handle(Request $request, Closure $next)
 {
     $_token = $request->input('access-token');
     $_clientId = $request->input('client-id');
     //  Remove these arguments
     $request->offsetUnset('client-id');
     $request->offsetUnset('access-token');
     //  Just plain ol' bad...
     if (empty($_token) || empty($_clientId)) {
         $this->error('bad request: no token or client-id present');
         return ErrorPacket::create(Response::HTTP_BAD_REQUEST);
     }
     try {
         $_key = AppKey::byClientId($_clientId)->firstOrFail();
         $this->setSigningCredentials($_clientId, $_key->client_secret);
     } catch (\Exception $_ex) {
         $this->error('forbidden: invalid "client-id" [' . $_clientId . ']');
         return ErrorPacket::create(Response::HTTP_FORBIDDEN, 'Invalid "client-id"');
     }
     if (!$this->verifySignature($_token, $_clientId, $_key->client_secret)) {
         $this->error('bad request: signature verification fail');
         return ErrorPacket::create(Response::HTTP_BAD_REQUEST);
     }
     try {
         $_owner = $this->_locateOwner($_key->owner_id, $_key->owner_type_nbr);
     } catch (ModelNotFoundException $_ex) {
         $this->error('unauthorized: invalid "user" assigned to akt#' . $_key->id);
         return ErrorPacket::create(Response::HTTP_UNAUTHORIZED);
     }
     $request->setUserResolver(function () use($_owner) {
         return $_owner;
     });
     //$this->debug('token validated for client "' . $_clientId . '"');
     return parent::handle($request, $next);
 }
 /**
  * Handle a request
  *
  * @param ManifestJob $command
  *
  *
  * @return bool
  * @throws \Exception
  */
 public function handle(ManifestJob $command)
 {
     \Log::debug('[dfe:manifest] begin');
     if ($command->showManifest()) {
         $_manifest = ClusterManifest::createFromFile(base_path() . DIRECTORY_SEPARATOR . ConsoleDefaults::CLUSTER_MANIFEST_FILE);
         $_result = !$_manifest->existed() ? ErrorPacket::create() : SuccessPacket::make($_manifest->toArray());
         //  And then show it...
         if ($_manifest->existed()) {
             \Log::debug('  * Manifest found: ' . print_r($_manifest->all(), true));
         } else {
             \Log::info('  * No manifest file found. Nothing to show.');
         }
     } else {
         try {
             $_key = $command->noKeys() ? false : AppKey::createKey($command->getOwnerId(), $command->getOwnerType());
             if ($_key) {
                 $command->getOutput()->getVerbosity() == OutputInterface::VERBOSITY_VERBOSE && $command->getOutput()->writeln(' - generated client-id and secret: ' . $_key->client_id);
             }
             if ($command->createManifest()) {
                 //  Create a new manifest...
                 $_manifest = ClusterManifest::make(base_path(), ['cluster-id' => config('dfe.cluster-id'), 'default-domain' => config('provisioning.default-domain'), 'signature-method' => config('dfe.signature-method'), 'storage-root' => config('provisioning.storage-root'), 'console-api-url' => config('dfe.security.console-api-url'), 'console-api-key' => config('dfe.security.console-api-key'), 'client-id' => !$_key ? null : $_key->client_id, 'client-secret' => !$_key ? null : $_key->client_secret]);
                 $command->setResult($_result = SuccessPacket::make($_manifest->toArray(), Response::HTTP_CREATED));
             }
         } catch (\Exception $_ex) {
             $command->setResult($_result = ErrorPacket::create(Response::HTTP_BAD_REQUEST));
         }
     }
     \Log::debug('[dfe:manifest] end');
     return $command;
 }
Пример #3
0
 /** @inheritdoc */
 public static function boot()
 {
     parent::boot();
     //  Ensure user is active upon creation
     static::creating(function (ServiceUser $model) {
         $model->active_ind = true;
     });
     static::created(function (ServiceUser $model) {
         AppKey::createKeyForEntity($model, OwnerTypes::SERVICE_USER);
     });
 }
Пример #4
0
 /**
  * Create a new user instance after a valid registration.
  *
  * @param  array $data
  *
  * @return User
  */
 public function create(array $data)
 {
     return \DB::transaction(function () use($data) {
         $_user = User::create(['first_name_text' => $data['first_name_text'], 'last_name_text' => $data['last_name_text'], 'email_addr_text' => $data['email_addr_text'], 'nickname_text' => $data['nickname_text'], 'password_text' => bcrypt($data['password_text'])]);
         $_appKey = AppKey::create(array('key_class_text' => AppKeyClasses::USER, 'owner_id' => $_user->id, 'owner_type_nbr' => OwnerTypes::USER, 'server_secret' => config('dfe.security.console-api-key')));
         //  Update the user with the key info and activate
         $_user->api_token_text = $_appKey->client_id;
         $_user->active_ind = 1;
         $_user->save();
         return $_user;
     });
 }
 /**
  * Validates a client key pair and generates a signature for verification.
  *
  * @param string $clientId
  * @param string $clientSecret
  *
  * @return $this
  */
 protected function setSigningCredentials($clientId, $clientSecret)
 {
     $_key = AppKey::byClientId($clientId)->first();
     if (empty($_key) || $clientSecret != $_key->client_secret) {
         throw new \InvalidArgumentException('Invalid credentials.');
     }
     //  Looks good
     $this->vsClientId = $_key->client_id;
     $this->vsClientSecret = $_key->client_secret;
     $this->vsSignature = $this->generateSignature();
     return $this;
 }
 /**
  * Handle a request
  *
  * @param RegisterJob $command
  *
  * @return mixed
  * @throws \Exception
  */
 public function handle(RegisterJob $command)
 {
     $_key = config('dfe.security.console-api-key');
     try {
         $_owner = $command->getOwnerInfo();
         //  Generate the key
         $_key = AppKey::createKey($_owner->id, $_owner->type, ['server_secret' => $_key]);
         $this->debug('[dfe:register] Successfully created app key "' . $_key->client_id . '"');
         $_result = SuccessPacket::make($_key->toArray(), Response::HTTP_CREATED);
     } catch (\Exception $_ex) {
         $this->error('[dfe:register] Exception while creating key: ' . $_ex->getMessage());
         $_result = ErrorPacket::create(Response::HTTP_BAD_REQUEST, $_ex);
     }
     $command->publishResult($command->getJobId(), $_result);
     return $_result;
 }
Пример #7
0
 /**
  * Handle the command
  *
  * @return mixed
  */
 public function fire()
 {
     parent::fire();
     $_command = new RegisterJob($this->argument('owner-id'), strtolower($this->argument('owner-type')));
     \Queue::push($_command);
     $_result = $_command->getResult();
     if (empty($_result) || null === ($_id = IfSet::getDeep($_result, 'success', 'id'))) {
         $this->error('Results not found for request. Please try again.');
         return 1;
     }
     try {
         /** @type AppKey $_key */
         $_key = AppKey::findOrFail($_id);
     } catch (ModelNotFoundException $_ex) {
         $this->error('The key has been misplaced. Please try again.');
         return 2;
     }
     $this->writeln('<info>Key pair id "' . $_id . '" created. Please keep secure.</info>');
     $this->writeln('    <comment>client_id</comment>: <info>' . $_key->client_id . '</info>');
     $this->writeln('<comment>client_secret</comment>: <info>' . $_key->client_secret . '</info>');
     return 0;
 }
Пример #8
0
    /**
     * Handle the command
     *
     * @return mixed
     */
    public function fire()
    {
        parent::fire();
        $this->config = config('commands.setup');
        //  1. Make sure it's a clean install
        if (0 != ServiceUser::count()) {
            if ($this->option('force')) {
                $this->writeln('system has users. <comment>--force</comment> override in place.');
                $this->_backupServiceUsers();
            } else {
                $this->writeln('system has users. use --force to override.', 'error');
                return 1;
            }
        }
        //  1.5 Generate an API secret and stick it in config for AppKey
        \Config::set('dfe.security.console-api-key', $_apiSecret = $this->option('api-secret') ?: $this->_generateApiSecret());
        //  2. Create initial admin user
        try {
            //  Delete all users
            /** @noinspection PhpUndefinedMethodInspection */
            DB::table('service_user_t')->delete();
            //  Add our new user
            $_user = ServiceUser::create(['first_name_text' => 'System', 'last_name_text' => 'Administrator', 'nickname_text' => 'Admin', 'email_addr_text' => $this->argument('admin-email'), 'password_text' => \Hash::make($this->option('admin-password')), 'active_ind' => 1]);
            if (empty($_user)) {
                throw new \Exception('Invalid response from user::create');
            }
            $this->writeln('user <comment>' . $this->argument('admin-email') . '</comment> created.', 'info');
            //  Register
            if (false === License::registerAdmin($_user)) {
                $this->writeln('Error while registering installation');
            }
        } catch (\Exception $_ex) {
            $this->writeln('Error while creating admin user: '******'error');
            return 1;
        }
        //  2. Check permissions and required directories
        $_paths = config('commands.setup.required-directories', []);
        foreach ($_paths as $_path) {
            if (!Disk::ensurePath($_path)) {
                $this->writeln('Unable to create directory: ' . $_path, 'error');
            }
        }
        //  3. Create console and dashboard API key sets
        $_consoleKey = AppKey::createKey(0, OwnerTypes::CONSOLE, ['server_secret' => $_apiSecret]);
        $_dashboardKey = AppKey::createKey(0, OwnerTypes::DASHBOARD, ['server_secret' => $_apiSecret]);
        //  4. Generate .dfe.cluster.json file
        ClusterManifest::make(base_path('database/dfe'), ['cluster-id' => config('dfe.cluster-id'), 'default-domain' => config('provisioning.default-domain'), 'signature-method' => config('dfe.signature-method'), 'storage-root' => config('provisioning.storage-root'), 'console-api-url' => config('dfe.security.console-api-url'), 'console-api-key' => $_apiSecret, 'client-id' => $_dashboardKey->client_id, 'client-secret' => $_dashboardKey->client_secret]);
        //  5.  Make a console environment
        $config = <<<INI
DFE_CONSOLE_API_KEY={$_apiSecret}
DFE_CONSOLE_API_CLIENT_ID={$_consoleKey->client_id}
DFE_CONSOLE_API_CLIENT_SECRET={$_consoleKey->client_secret}
INI;
        $this->_writeFile('console.env', $config);
        //  6.  Make a dashboard config file...
        $config = <<<INI
DFE_CONSOLE_API_KEY={$_apiSecret}
DFE_CONSOLE_API_CLIENT_ID={$_dashboardKey->client_id}
DFE_CONSOLE_API_CLIENT_SECRET={$_dashboardKey->client_secret}
INI;
        return $this->_writeFile('dashboard.env', $config);
    }
 /**
  *
  * @param int $ownerId
  * @param int $ownerType
  *
  * @return AppKey
  */
 protected static function findAppKey($ownerId, $ownerType)
 {
     return AppKey::mine($ownerId, $ownerType);
 }
Пример #10
0
 /**
  * @param Instance $instance
  * @param bool     $object If true, the Metadata object is returned instead of the array
  *
  * @return array|\DreamFactory\Enterprise\Common\Support\Metadata
  */
 public static function makeMetadata(Instance $instance, $object = false)
 {
     if (null === ($_key = AppKey::mine($instance->id, OwnerTypes::INSTANCE))) {
         //  Create an instance key
         $_key = AppKey::create(['key_class_text' => AppKeyClasses::INSTANCE, 'owner_id' => $instance->id, 'owner_type_nbr' => OwnerTypes::INSTANCE, 'server_secret' => config('dfe.security.console-api-key')]);
         if (null === $_key) {
             throw new \RuntimeException('Instance is unlicensed.');
         }
     }
     $_cluster = static::_lookupCluster($instance->cluster_id);
     $_md = new Metadata(array_merge(static::$metadataTemplate, ['storage-map' => InstanceStorage::buildStorageMap($instance->user->storage_id_text), 'env' => static::buildEnvironmentMetadata($instance, $_cluster, $_key), 'db' => static::buildDatabaseMetadata($instance), 'paths' => static::buildPathMetadata($instance), 'audit' => static::buildAuditMetadata($instance), 'limits' => static::buildLimitsMetadata($instance)]), $instance->instance_name_text . '.json', $instance->getOwnerPrivateStorageMount());
     return $object ? $_md : $_md->toArray();
 }
 /**
  * @param ProvisionServiceRequest $request
  *
  * @return array
  * @throws ProvisioningException
  */
 protected function provisionInstance($request)
 {
     $_storagePath = null;
     //	Pull the request apart
     $_instance = $request->getInstance();
     $_name = $this->sanitizeInstanceName($_instance->instance_name_text);
     $this->info('[provisioning] instance "' . $_name . '" begin');
     $_storageProvisioner = $request->getStorageProvisioner();
     $this->setPrivatePath($_privatePath = $_storageProvisioner->getPrivatePath());
     $this->setOwnerPrivatePath($_ownerPrivatePath = $_storageProvisioner->getOwnerPrivatePath());
     //	1. Provision the database
     if (false === ($_dbConfig = Provision::getDatabaseProvisioner($_instance->guest_location_nbr)->provision($request))) {
         throw new ProvisioningException('[provisioning] error during database provisioning.');
     }
     //  2. Generate an app key for the instance
     AppKey::create(['key_class_text' => AppKeyClasses::INSTANCE, 'owner_id' => $_instance->id, 'owner_type_nbr' => OwnerTypes::INSTANCE, 'server_secret' => config('dfe.security.console-api-key')]);
     //  3. Update the instance with new provision info
     try {
         $_instance->fill(['guest_location_nbr' => GuestLocations::DFE_CLUSTER, 'instance_id_text' => $_name, 'instance_name_text' => $_name, 'db_host_text' => $_dbConfig['host'], 'db_port_nbr' => $_dbConfig['port'], 'db_name_text' => $_dbConfig['database'], 'db_user_text' => $_dbConfig['username'], 'db_password_text' => $_dbConfig['password'], 'ready_state_nbr' => InstanceStates::ADMIN_REQUIRED, 'state_nbr' => ProvisionStates::PROVISIONED, 'platform_state_nbr' => OperationalStates::NOT_ACTIVATED, 'start_date' => $_instance->freshTimestamp(), 'end_date' => null, 'terminate_date' => null, 'provision_ind' => true, 'deprovision_ind' => false]);
         //  Create the guest row...
         $_host = $this->getFullyQualifiedDomainName($_name);
         /** @noinspection PhpUndefinedMethodInspection */
         DB::transaction(function () use($_instance, $_host) {
             /** Add guest data if there is a guest record */
             $_instance->guest && $_instance->guest->fill(['base_image_text' => config('provisioning.base-image', ConsoleDefaults::DFE_CLUSTER_BASE_IMAGE), 'vendor_state_nbr' => ProvisionStates::PROVISIONED, 'vendor_state_text' => 'running', 'public_host_text' => $_host])->save();
             //  Save the instance
             $_instance->save();
         });
     } catch (\Exception $_ex) {
         throw new \RuntimeException('[provisioning:instance] error updating instance data: ' . $_ex->getMessage());
     }
     //  Fire off a "provisioned" event...
     \Event::fire('dfe.provisioned', [$this, $request, $_instance->getMetadata()]);
     $this->info('[provisioning:instance] instance "' . $_name . '" provisioned');
     return $_instance->getMetadata();
 }
Пример #12
0
 /**
  * Standardized user creation method
  *
  * @param \Illuminate\Http\Request $request
  * @param bool                     $validate If false, no validation is done.
  *
  * @return \DreamFactory\Enterprise\Common\Packets\ErrorPacket|\DreamFactory\Enterprise\Common\Packets\SuccessPacket
  */
 public static function register(Request $request, $validate = true)
 {
     $_email = $request->input('email', $request->input('email_addr_text'));
     $_first = $request->input('firstname', $request->input('first_name_text'));
     $_last = $request->input('lastname', $request->input('last_name_text'));
     $_password = $request->input('password', $request->input('password_text'));
     $_nickname = $request->input('nickname', $request->input('nickname_text', $_first));
     $_company = $request->input('company', $request->input('company_name_text'));
     $_phone = $request->input('phone', $request->input('phone_text'));
     if ($validate) {
         if (empty($_email) || empty($_password) || empty($_first) || empty($_last)) {
             /** @noinspection PhpUndefinedMethodInspection */
             Log::error('missing required fields from partner post', ['payload' => $request->input()]);
             throw new \InvalidArgumentException('Missing required fields');
         }
         if (false === filter_var($_email, FILTER_VALIDATE_EMAIL)) {
             /** @noinspection PhpUndefinedMethodInspection */
             Log::error('invalid email address "' . $_email . '"', ['payload' => $request->input()]);
             throw new \InvalidArgumentException('Email address invalid');
         }
     }
     //  See if we know this cat...
     if (null !== ($_user = User::byEmail($_email)->first())) {
         //  Existing user found, don't add to database...
         $_values = $_user->toArray();
         unset($_values['password_text'], $_values['external_password_text']);
         /** @noinspection PhpUndefinedMethodInspection */
         Log::info('existing user attempting registration through api', ['user' => $_values]);
         return $_user;
     }
     //  Create a user account
     try {
         /** @type User $_user */
         /** @noinspection PhpUndefinedMethodInspection */
         $_user = DB::transaction(function () use($request, $_first, $_last, $_email, $_password, $_nickname, $_phone, $_company) {
             /** @noinspection PhpUndefinedMethodInspection */
             $_user = User::create(['first_name_text' => $_first, 'last_name_text' => $_last, 'email_addr_text' => $_email, 'nickname_text' => $_nickname, 'password_text' => Hash::make($_password), 'phone_text' => $_phone, 'company_name_text' => $_company]);
             if (null === ($_appKey = AppKey::mine($_user->id, OwnerTypes::USER))) {
                 $_appKey = AppKey::create(['key_class_text' => AppKeyClasses::USER, 'owner_id' => $_user->id, 'owner_type_nbr' => OwnerTypes::USER, 'server_secret' => config('dfe.security.console-api-key')]);
             }
             //  Update the user with the key info and activate
             $_user->api_token_text = $_appKey->client_id;
             $_user->active_ind = 1;
             $_user->save();
             return $_user;
         });
         $_values = $_user->toArray();
         unset($_values['password_text'], $_values['external_password_text']);
         /** @noinspection PhpUndefinedMethodInspection */
         Log::info('new user registered', ['user' => $_values]);
         return $validate ? SuccessPacket::create($_user, Response::HTTP_CREATED) : $_user;
     } catch (\Exception $_ex) {
         if (false !== ($_pos = stripos($_message = $_ex->getMessage(), ' (sql: '))) {
             $_message = substr($_message, 0, $_pos);
         }
         /** @noinspection PhpUndefinedMethodInspection */
         Log::error('database error creating user from ops-resource post: ' . $_message);
         return $validate ? ErrorPacket::create(null, Response::HTTP_INTERNAL_SERVER_ERROR, $_message) : null;
     }
 }