scope = array( 'view_processes' => 'View Processes', 'edit_processes' => 'Edit Processes', '*' => '*' ); // $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost" $cnn = array('dsn' => self::$dsn, 'username' => self::$dbUser, 'password' => self::$dbPassword); if (self::$isRBAC) { $config = array(); $cnnrbac = array('dsn' => self::$dsnRBAC, 'username' => self::$dbUserRBAC, 'password' => self::$dbPasswordRBAC); $this->storage = new PmPdo($cnn, $config, $cnnrbac); } else { $this->storage = new PmPdo($cnn); } // Pass a storage object or array of storage objects to the OAuth2 server class $this->server = new \OAuth2\Server($this->storage, array('allow_implicit' => true, 'access_lifetime' => 86400)); $this->server->setConfig('enforce_state', false); // Add the "Authorization Code" grant type (this is where the oauth magic happens) $this->server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->storage)); // Add the "Client Credentials" grant type (it is the simplest of the grant types) $this->server->addGrantType(new \ProcessMaker\Services\OAuth2\PmClientCredentials($this->storage)); // Add the "Refresh token" grant type $this->server->addGrantType(new \OAuth2\GrantType\RefreshToken( $this->storage, array("always_issue_new_refresh_token" => true) )); // create some users in memory //$users = array('bshaffer' => array('password' => 'brent123', 'first_name' => 'Brent', 'last_name' => 'Shaffer')); // create a storage object //$storage = new \OAuth2\Storage\Memory(array('user_credentials' => $users)); // create the grant type $grantType = new \OAuth2\GrantType\UserCredentials($this->storage); // add the grant type to your OAuth server $this->server->addGrantType($grantType); $scope = new \OAuth2\Scope(array('supported_scopes' => array_keys($this->scope))); $this->server->setScopeUtil($scope); } /** * @url POST /:token/expire * */ public function doPostExpireToken($token) { try { $this->storage->expireToken($token); } catch (\Exception $e) { throw new RestException(400, $e->getMessage()); } } /** * @url DELETE /:token * */ public function doDeleteToken($token) { try { $this->storage->deleteToken($token); } catch (\Exception $e) { throw new RestException(400, $e->getMessage()); } } public static function setDatabaseSource($user, $password = '', $dsn = '') { if (is_array($user)) { self::$dbUser = $user['username']; self::$dbPassword = $user['password']; self::$dsn = $user['dsn']; } else { self::$dbUser = $user; self::$dbPassword = $password; self::$dsn = $dsn; } } public static function setDatabaseSourceRBAC($user, $password = '', $dsn = '') { if (is_array($user)) { self::$dbUserRBAC = $user['username']; self::$dbPasswordRBAC = $user['password']; self::$dsnRBAC = $user['dsn']; self::$isRBAC = true; } else { self::$dbUserRBAC = $user; self::$dbPasswordRBAC = $password; self::$dsnRBAC = $dsn; self::$isRBAC = true; } } public static function setWorkspace($workspace) { self::$workspace = $workspace; } public function index() { $http = \G::is_https() ? 'https' : 'http'; $host = $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' ? ':' . $_SERVER['SERVER_PORT'] : ''); $host = $http .'://'. $host; $applicationsLink = sprintf('%s/%s/oauth2/apps', $host, config("system.workspace")); $authorizationLink = sprintf('%s/%s/oauth2/authorize?response_type=code&client_id=[the-client-id]&scope=*', $host, config("system.workspace")); $view = new \Maveriks\Pattern\Mvc\SmartyView(PATH_CORE . "templates/oauth2/index.html"); $view->assign('host', $host); $view->assign('workspace', self::$workspace); $view->render(); } /** * @view oauth2/server/register.php * @format HtmlFormat */ public function register() { static::$server->getResponse(\OAuth2\Request::createFromGlobals()); return array('queryString' => $_SERVER['QUERY_STRING']); } /** * Stage 1: Client sends the user to this page * * User responds by accepting or denying * */ public function authorize() { session_start(); if (! isset($_SESSION['USER_LOGGED'])) { $http = \G::is_https() ? 'https' : 'http'; $host = $http . '://' . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' ? ':' . $_SERVER['SERVER_PORT'] : ''); $redirect = urlencode($host.'/'.self::$workspace.$_SERVER['REQUEST_URI']); $loginLink = sprintf('%s/sys%s/%s/%s/login/login?u=%s', $host, config("system.workspace"), SYS_LANG, SYS_SKIN, $redirect); header('location: ' . $loginLink); die; } $this->scope = array( 'view_processes' => 'View Processes', 'edit_processes' => 'Edit Processes' ); if (! array_key_exists('client_id', $_GET)) { throw new RestException(400, "Invalid request. The 'client_id' parameter is missing!"); } if (! array_key_exists('response_type', $_GET)) { throw new RestException(400, "Invalid request. The 'response_type' parameter is missing!"); } $clientId = $_GET['client_id']; $requestedScope = isset($_GET['scope']) ? $_GET['scope'] : '*'; $requestedScope = empty($requestedScope) ? array() : explode(' ', $requestedScope); $client = $this->storage->getClientDetails($clientId); if (empty($client)) { // throw error, client does not exist. throw new RestException(400, "Error, unknown client. The client with id '".$clientId."' is not registered"); } //echo '
';print_r($client); echo ''; die; $client = array('name' => $client['client_name'], 'desc' => $client['client_description']); $user = array('name' => $_SESSION['USR_FULLNAME']); $view = new \Maveriks\Pattern\Mvc\SmartyView(PATH_CORE . "templates/oauth2/authorize.html"); $view->assign('user', $user); $view->assign('client', $client); $view->assign('postUri', '/' . config("system.workspace") . '/oauth2/authorize?' . $_SERVER['QUERY_STRING']); $view->render(); exit(); } /** * Stage 2: User response is captured here * * Success or failure is communicated back to the Client using the redirect * url provided by the client * * On success authorization code is sent along * * @format JsonFormat,UploadFormat */ public function postAuthorize($authorize = null, $userId = null, $returnResponse = false, $cacheSessionValue = array()) { @session_start(); foreach ($cacheSessionValue as $key => $value) { $_SESSION[$key] = $value; } if (! isset($_SESSION['USER_LOGGED'])) { throw new RestException(400, "Local Authentication Error, user session is not started."); } if (empty($userId)) { $userId = $_SESSION['USER_LOGGED']; } if (empty($authorize)) { $authorize = array_key_exists('cancel', $_REQUEST)? false: true; } $request = \OAuth2\Request::createFromGlobals(); $response = new \OAuth2\Response(); $response = $this->server->handleAuthorizeRequest( $request, $response, (bool)$authorize, $userId ); if ($returnResponse) { return $response; } else { $response->send(); exit(0); } } /** * Stage 3: Client directly calls this api to exchange access token * * It can then use this access token to make calls to protected api * * @format JsonFormat,UploadFormat */ public function postToken($request = null, $returnResponse = false) { \ProcessMaker\Policies\ControlUnderUpdating::verifyUnderUpgrading(); // Handle a request for an OAuth2.0 Access Token and send the response to the client if ($request == null) { $request = \OAuth2\Request::createFromGlobals(); } $response = $this->server->handleTokenRequest($request); //Set/Get token //PmPdo->setAccessToken() $token = $response->getParameters(); if (array_key_exists('access_token', $token) && array_key_exists('refresh_token', $token) ) { if ($request == null) { session_start(); } $data = $this->storage->getAccessToken($token['access_token']); // verify if the client is our local PM Designer client if ($data['client_id'] == self::getPmClientId()) { //error_log('do stuff - is a request from local pm client'); //require_once "classes/model/PmoauthUserAccessTokens.php"; $userToken = new \PmoauthUserAccessTokens(); $userToken->setAccessToken($token['access_token']); $userToken->setRefreshToken($token['refresh_token']); $userToken->setUserId($data['user_id']); $userToken->setSessionId(session_id()); $userToken->setSessionName(session_name()); $userToken->save(); } } if ($returnResponse) { return $response; } else { $response->send(); exit(0); } } /** * Access verification method. * * API access will be denied when this method returns false * * @return boolean true when api access is allowed; false otherwise */ public function __isAllowed() { $request = \OAuth2\Request::createFromGlobals(); $allowed = $this->server->verifyResourceRequest($request); $token = $this->server->getAccessTokenData($request); self::$userId = $token['user_id']; // Session handling to prevent session lose in other places like, home, admin, etc // when user is using the new designer that have not session because it is using only the API if ($allowed && $token['client_id'] == self::getPmClientId()) { $pmAccessToken = new \PmoauthUserAccessTokens(); $session = $pmAccessToken->getSessionData($token['ACCESS_TOKEN']); if ($session !== false && array_key_exists($session->getSessionName(), $_COOKIE)) { // increase the timeout for local php session cookie $config = \Bootstrap::getSystemConfiguration(); if (isset($config['session.gc_maxlifetime'])) { $lifetime = $config['session.gc_maxlifetime']; } else { $lifetime = ini_get('session.gc_maxlifetime'); } if (empty($lifetime)) { $lifetime = 1440; } setcookie($session->getSessionName(), $_COOKIE[$session->getSessionName()], time() + $lifetime, "/", null, false, true); } } //Set User Time Zone $user = \UsersPeer::retrieveByPK(self::$userId); if (!is_null($user)) { $userTimeZone = $user->getUsrTimeZone(); if (trim($userTimeZone) == '') { $arraySystemConfiguration = System::getSystemConfiguration('', '', config("system.workspace")); $userTimeZone = $arraySystemConfiguration['time_zone']; } $_SESSION['USR_TIME_ZONE'] = $userTimeZone; } /*----------------------------------********---------------------------------*/ ChangeLog::getChangeLog() ->setUsrId(is_null($user) ? 0 : $user->getUsrId()) ->setSkin(SYS_SKIN) ->setLanguage(SYS_LANG); if ($token['client_id'] === config('oauthClients.mobile.clientId')) { ChangeLog::getChangeLog() ->setSourceId(ChangeLog::FromMobile); } else { ChangeLog::getChangeLog() ->setSourceId(ChangeLog::FromWeb); } /*----------------------------------********---------------------------------*/ return $allowed; } public static function setPmClientId($clientId) { self::$pmClientId = $clientId; } public static function getPmClientId() { return self::$pmClientId; } public function getServer() { return $this->server; } public static function getUserId() { return self::$userId; } public function getScope() { return array_keys($this->scope); } public function __getWWWAuthenticateString() { return ""; } }