BurningFlipside /
CommonCode
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Generic OAUTH2 Authenitcation Helper class |
||
| 4 | * |
||
| 5 | * This file describes the OAuth2Authenticator class |
||
| 6 | * |
||
| 7 | * PHP version 5 and 7 |
||
| 8 | * |
||
| 9 | * @author Patrick Boyd / [email protected] |
||
| 10 | * @copyright Copyright (c) 2015, Austin Artistic Reconstruction |
||
| 11 | * @license http://www.apache.org/licenses/ Apache 2.0 License |
||
| 12 | */ |
||
| 13 | |||
| 14 | namespace Flipside\Auth\OAuth2; |
||
| 15 | |||
| 16 | /** Only load the HTTPFul bootstrap if it isn't already loaded*/ |
||
| 17 | if(!class_exists('Httpful\Request')) |
||
| 18 | { |
||
| 19 | require dirname(__FILE__).'/../../vendor/autoload.php'; |
||
| 20 | } |
||
| 21 | |||
| 22 | /** |
||
| 23 | * A helper class to help with common OAUTH2 tasks |
||
| 24 | * |
||
| 25 | * This class helps convert between OAUTH2 and the \Auth\Authenticator methods |
||
| 26 | */ |
||
| 27 | abstract class OAuth2Authenticator extends \Flipside\Auth\Authenticator |
||
| 28 | { |
||
| 29 | /** The URL the OAUTH2 service should redirect to */ |
||
| 30 | protected $redirect_uri; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * Create an instance of the OAuth2Authenticator |
||
| 34 | * |
||
| 35 | * @param array $params Paremeters to use in initializing this Authenticator |
||
| 36 | */ |
||
| 37 | public function __construct($params) |
||
| 38 | { |
||
| 39 | parent::__construct($params); |
||
| 40 | if(!isset($params['redirect_url'])) |
||
| 41 | { |
||
| 42 | $this->redirect_uri = 'https://'.$_SERVER['HTTP_HOST'].'/oauth/callbacks/'.$this->getHostName(); |
||
| 43 | } |
||
| 44 | else |
||
| 45 | { |
||
| 46 | $this->redirect_uri = $params['redirect_url']; |
||
| 47 | } |
||
| 48 | } |
||
| 49 | |||
| 50 | /** |
||
| 51 | * Get a link to the supplemental OAUTH2 endpoint |
||
| 52 | * |
||
| 53 | * @return string A link consiting of an image for use on the login screens |
||
| 54 | */ |
||
| 55 | public function getSupplementLink() |
||
| 56 | { |
||
| 57 | $auth_url = $this->getAuthorizationUrl(); |
||
| 58 | return '<a href="'.filter_var($auth_url, FILTER_SANITIZE_URL).'"><img src="'.$this->getSignInImg().'" style="width: 2em;"/></a>'; |
||
| 59 | } |
||
| 60 | |||
| 61 | /** |
||
| 62 | * Get the webpath for the image used on the login screens |
||
| 63 | * |
||
| 64 | * @return string the webpath for the image |
||
| 65 | */ |
||
| 66 | public function getSignInImg() |
||
| 67 | { |
||
| 68 | return '/img/common/'.$this->getHostName().'_sign_in.png'; |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * Get the URL to initially authorize a user |
||
| 73 | * |
||
| 74 | * @return string The URL to send the user to inordere to authorize the use by this server |
||
| 75 | */ |
||
| 76 | abstract public function getAuthorizationUrl(); |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Get the URL to retreive an access token from |
||
| 80 | * |
||
| 81 | * @return string The URL to obtain the access token from after the user authorizes use |
||
| 82 | */ |
||
| 83 | abstract public function getAccessTokenUrl(); |
||
| 84 | |||
| 85 | /** |
||
| 86 | * Obtain the user given the Access Token |
||
| 87 | * |
||
| 88 | * @param string $token The OAUTH2 access token |
||
| 89 | * |
||
| 90 | * @return \Auth\User The user that is now authenicated |
||
| 91 | */ |
||
| 92 | abstract public function getUserFromToken($token); |
||
| 93 | |||
| 94 | /** |
||
| 95 | * Send the access token to the server to indicate this server can act on behalf of the user |
||
| 96 | * |
||
| 97 | * @param array $params An array containing the code to send |
||
| 98 | * |
||
| 99 | * @return \Httpful\Response The response from the post to the other server |
||
| 100 | */ |
||
| 101 | public function doAuthPost($params) |
||
| 102 | { |
||
| 103 | return \Httpful\Request::post($this->getAccessTokenUrl().'&code='.$params['code'])->send(); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Authenticate the user is valid and can login throught this method |
||
| 108 | * |
||
| 109 | * @param $params The set of parameters obtained from the authentication call |
||
| 110 | * @param $current_user The user from the current system if the user is not authorized to login via this method |
||
| 111 | * |
||
| 112 | * @return integer SUCCESS if the user is now logged in. ALREADY_PRESENT if the authorization was |
||
| 113 | * successful, but the user has not authorized that login method. LOGIN_FAILED for all other errors |
||
| 114 | */ |
||
| 115 | public function authenticate($params, &$current_user) |
||
| 116 | { |
||
| 117 | $resp = $this->doAuthPost($params); |
||
| 118 | if($resp->hasErrors()) |
||
| 119 | { |
||
| 120 | return self::LOGIN_FAILED; |
||
| 121 | } |
||
| 122 | \FlipSession::setVar('OAuthToken', $resp->body); |
||
| 123 | $user = $this->getUserFromToken($resp->body); |
||
|
0 ignored issues
–
show
|
|||
| 124 | if($user === false) |
||
| 125 | { |
||
| 126 | return self::LOGIN_FAILED; |
||
| 127 | } |
||
| 128 | $auth = \AuthProvider::getInstance(); |
||
| 129 | $local_users = $auth->getUsersByFilter(new \Data\Filter('mail eq '.$user->mail)); |
||
| 130 | if($local_users !== false && isset($local_users[0])) |
||
| 131 | { |
||
| 132 | if($local_users[0]->canLoginWith($this->getHostName())) |
||
| 133 | { |
||
| 134 | $auth->impersonateUser($local_users[0]); |
||
| 135 | return self::SUCCESS; |
||
| 136 | } |
||
| 137 | $current_user = $local_users[0]; |
||
| 138 | return self::ALREADY_PRESENT; |
||
| 139 | } |
||
| 140 | $ret = $auth->activatePendingUser($user); |
||
| 141 | if($ret === false) |
||
| 142 | { |
||
| 143 | throw new \Exception('Unable to create user! '.$res); |
||
| 144 | } |
||
| 145 | return self::SUCCESS; |
||
| 146 | } |
||
| 147 | } |
||
| 148 | /* vim: set tabstop=4 shiftwidth=4 expandtab: */ |
||
| 149 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.