Example #1
0
 public function token($api, $args)
 {
     $validVersion = $this->isSupportedClientVersion($api, $args);
     if (!$validVersion) {
         throw new SugarApiExceptionClientOutdated();
     }
     $oauth2Server = $this->getOAuth2Server($args);
     try {
         $GLOBALS['logic_hook']->call_custom_logic('Users', 'before_login');
         $authData = $oauth2Server->grantAccessToken($args);
         // if we're here, the login was OK
         if (!empty($GLOBALS['current_user'])) {
             //Update password expired since user's essentially logged in at this point
             require_once 'modules/Users/password_utils.php';
             $GLOBALS['current_user']->call_custom_logic('after_login');
         }
         $cleanupChance = isset($GLOBALS['sugar_config']['token_cleanup_probability']) ? (int) $GLOBALS['sugar_config']['token_cleanup_probability'] : 10;
         if (mt_rand() % $cleanupChance == 0) {
             // cleanup based on probability
             OAuthToken::cleanup();
         }
     } catch (OAuth2ServerException $e) {
         // failed to get token - something went wrong - list as failed login
         $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
         throw $e;
     } catch (SugarApiExceptionNeedLogin $e) {
         $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
         // have API throw login exception wil full data
         $api->needLogin($e);
     }
     $loginStatus = apiCheckLoginStatus();
     if ($loginStatus !== true && $loginStatus['level'] != 'warning') {
         if (($loginStatus['level'] == 'admin_only' || $loginStatus['level'] == 'maintenance') && $GLOBALS['current_user']->isAdmin()) {
             // Let them through
         } else {
             // This is no good, they shouldn't be allowed in.
             $e = new SugarApiExceptionMaintenance($loginStatus['message'], null, null, 0, $loginStatus['level']);
             if (!empty($loginStatus['url'])) {
                 $e->setExtraData("url", $loginStatus['url']);
             }
             $api->needLogin($e);
             return;
         }
     }
     $platform = 'base';
     if (!empty($args['platform'])) {
         $platform = $args['platform'];
     }
     // Adding the setcookie() here instead of calling $api->setHeader() because
     // manually adding a cookie header will break 3rd party apps that use cookies
     setcookie(RestService::DOWNLOAD_COOKIE . '_' . $platform, $authData['download_token'], time() + $authData['refresh_expires_in'], ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), true);
     // For reauth requests we need to send back the session cookie as well to
     // keep the client in sync if there was a session cookie to begin with
     if (isset($_COOKIE[session_name()]) && !empty($args['grant_type']) && $args['grant_type'] == 'refresh_token' && !empty($args['refresh'])) {
         $this->sendSessionCookie();
     }
     return $authData;
 }
Example #2
0
 /**
  * This function executes the current request and outputs the response directly.
  */
 public function execute()
 {
     ob_start();
     $this->response = $this->getResponse();
     try {
         $this->request = $this->getRequest();
         $this->request_headers = $this->request->request_headers;
         if ($this->min_version > $this->request->version || $this->max_version < $this->request->version) {
             throw new SugarApiExceptionIncorrectVersion("Please change your url to reflect version between {$this->min_version} and {$this->max_version}");
         }
         $authenticateUser = $this->authenticateUser();
         $isLoggedIn = $authenticateUser['isLoggedIn'];
         $loginException = $authenticateUser['exception'];
         // Figure out the platform
         if ($isLoggedIn) {
             if (isset($_SESSION['platform'])) {
                 $this->platform = $_SESSION['platform'];
             }
         } else {
             // Since we don't have a session we have to allow the user to specify their platform
             // However, since the results from the same URL will be different with
             // no variation in the oauth_token header we need to only take it as a GET request.
             if (!empty($_GET['platform'])) {
                 $this->platform = basename($_GET['platform']);
             }
         }
         $this->request->setPlatform($this->platform);
         $GLOBALS['logic_hook']->call_custom_logic('', 'before_routing', array("api" => $this, "request" => $this->request));
         $route = $this->findRoute($this->request);
         if ($route == false) {
             throw new SugarApiExceptionNoMethod('Could not find any route that accepted a path like: ' . $this->request->rawPath);
         }
         $this->request->setRoute($route);
         $GLOBALS['logic_hook']->call_custom_logic('', 'after_routing', array("api" => $this, "request" => $this->request));
         // Get it back in case hook changed it
         $route = $this->request->getRoute();
         if (empty($route['keepSession'])) {
             $this->releaseSession();
         }
         // Get the request args early for use in current user api
         $argArray = $this->getRequestArgs($route);
         if (!$isLoggedIn && !empty($route['allowDownloadCookie'])) {
             $isLoggedIn = $this->authenticateUserForDownload();
         }
         // Make sure the system is ready for them
         // This section of code is a portion of the code referred
         // to as Critical Control Software under the End User
         // License Agreement.  Neither the Company nor the Users
         // may modify any portion of the Critical Control Software.
         $systemStatus = apiCheckSystemStatus();
         if ($systemStatus !== true && $systemStatus['level'] != 'warning' && !($systemStatus['level'] == 'maintenance' && isset($this->user) && $this->user->isAdmin()) && empty($route['ignoreSystemStatusError'])) {
             // The system is unhappy and the route isn't flagged to let them through
             $e = new SugarApiExceptionMaintenance($systemStatus['message'], null, null, 0, $systemStatus['level']);
             $e->setExtraData("url", $systemStatus['url']);
             throw $e;
         }
         //END REQUIRED CODE DO NOT MODIFY
         if (!isset($route['noLoginRequired']) || $route['noLoginRequired'] == false) {
             if (!$isLoggedIn) {
                 if (!$loginException) {
                     $this->needLogin();
                 } else {
                     throw $loginException;
                 }
             } else {
                 if (empty($route['ignoreMetaHash'])) {
                     // Check metadata hash state and return an error to force a
                     // resync so that the new metadata gets picked up if it is
                     // out of date
                     if (!$this->isMetadataCurrent()) {
                         // Mismatch in hashes... Return error so the client will
                         // resync its metadata and try again.
                         throw new SugarApiExceptionInvalidHash();
                     }
                 }
             }
         }
         if ($isLoggedIn) {
             // This is needed to load in the app_strings and the app_list_strings and the such
             $this->loadUserEnvironment();
         } else {
             $this->loadGuestEnvironment();
         }
         $headers = array();
         foreach ($this->special_headers as $header) {
             if (isset($this->request_headers[$header])) {
                 $headers[$header] = $this->request_headers[$header];
             }
         }
         if (!empty($headers)) {
             $argArray['_headers'] = $headers;
         }
         $this->request->setArgs($argArray)->setRoute($route);
         $GLOBALS['logic_hook']->call_custom_logic('', 'before_api_call', array("api" => $this, "request" => $this->request));
         // Get it back in case hook changed it
         $route = $this->request->getRoute();
         $argArray = $this->request->getArgs();
         // Trying to fetch correct module while API use search
         $module = $route['className'];
         if (isset($argArray['module'])) {
             $module = $argArray['module'];
         } elseif (isset($argArray['module_list'])) {
             $module = $argArray['module_list'];
         }
         SugarMetric_Manager::getInstance()->setTransactionName('rest_' . $module . '_' . $route['method']);
         $apiClass = $this->loadApiClass($route);
         $apiMethod = $route['method'];
         $this->handleErrorOutput('php_error_before_api');
         $this->response->setContent($apiClass->{$apiMethod}($this, $argArray));
         $this->respond($route, $argArray);
         if (empty($route['rawReply'])) {
             $this->handleErrorOutput('php_error_after_api');
         }
     } catch (Exception $e) {
         $this->handleException($e);
     }
     // last chance for hooks to mess with the response
     $GLOBALS['logic_hook']->call_custom_logic('', "before_respond", $this->response);
     $this->response->send();
 }