diff --git a/github.php b/github.php index 0e9238a5e2fe978b7bc41cf61a97f6f74e31d6fc..3e50a12f4d54fb725f2ce5b7a21160e68571cbdb 100644 --- a/github.php +++ b/github.php @@ -12,69 +12,93 @@ $tokenURL = 'https://github.com/login/oauth/access_token'; // This is the Github base URL we can use to make authenticated API requests $apiURLBase = 'https://api.github.com/'; -// The full path to this script. Note that for production sites, you should use an https URL. -$baseURL = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF']; +// The URL for this script, used as the redirect URL +$baseURL = 'https://' . $_SERVER['SERVER_NAME'] + . $_SERVER['PHP_SELF']; // Start a session so we have a place to store things between redirects session_start(); +// If there is an access token in the session, the user is logged in +if(!isset($_GET['action'])) { + if(!empty($_SESSION['access_token'])) { + echo '<h3>Logged In</h3>'; + echo '<p><a href="?action=repos">View Repos</a></p>'; + echo '<p><a href="?action=logout">Log Out</a></p>'; + } else { + echo '<h3>Not logged in</h3>'; + echo '<p><a href="?action=login">Log In</a></p>'; + } + die(); +} + // Start the login process by sending the user to Github's authorization page -if(get('action') == 'login') { - // Generate a random hash and store in the session for security - $_SESSION['state'] = hash('sha256', microtime(1).rand().$_SERVER['REMOTE_ADDR']); +if(isset($_GET['action']) && $_GET['action'] == 'login') { unset($_SESSION['access_token']); + // Generate a random hash and store in the session + $_SESSION['state'] = bin2hex(random_bytes(16)); + $params = array( 'client_id' => $githubClientID, 'redirect_uri' => $baseURL, - 'scope' => 'user', + 'scope' => 'user public_repo', 'state' => $_SESSION['state'] ); - // Redirect the user to Github's authorization page header('Location: ' . $authorizeURL . '?' . http_build_query($params)); die(); } -// When Github redirects the user back here, there will be a "code" and "state" +if(isset($_GET['action']) && $_GET['action'] == 'logout') { + unset($_SESSION['access_token']); + header('Location: '.$baseURL); + die(); +} + +// When Github redirects the user back here, there will be a "code" and "state" // parameter in the query string -if(get('code')) { +if(isset($_GET['code'])) { // Verify the state matches our stored state - if(!get('state') || $_SESSION['state'] != get('state')) { + if(!isset($_GET['state']) || $_SESSION['state'] != $_GET['state']) { header('Location: ' . $baseURL . '?error=invalid_state'); die(); } // Exchange the auth code for a token $token = apiRequest($tokenURL, array( + 'grant_type' => 'authorization_code', 'client_id' => $githubClientID, 'client_secret' => $githubClientSecret, 'redirect_uri' => $baseURL, - 'code' => get('code') + 'code' => $_GET['code'] )); - $_SESSION['access_token'] = $token->access_token; + $_SESSION['access_token'] = $token['access_token']; header('Location: ' . $baseURL); die(); } -// If there is an access token in the session the user is logged in -if(session('access_token')) { - // Make an API request to Github to fetch basic profile information - $user = apiRequest($apiURLBase . 'user'); +if(isset($_GET['action']) && $_GET['action'] == 'repos') { + + // Find all repos created by the authenticated user + $repos = apiRequest($apiURLBase.'user/repos?'.http_build_query([ + 'sort' => 'created', + 'direction' => 'desc' + ])); - echo '<h3>Logged In</h3>'; - echo '<h4>' . $user->name . '</h4>'; - echo '<pre>'; - print_r($user); - echo '</pre>'; + echo '<ul>'; + foreach($repos as $repo) { + echo '<li><a href="' . $repo['html_url'] . '">' . $repo['name'] . '</a></li>'; + } + echo '</ul>'; -} else { - echo '<h3>Not logged in</h3>'; - echo '<p><a href="?action=login">Log In</a></p>'; + die(); } +// This helper function will make API requests to GitHub, setting +// the appropriate headers GitHub expects, and decoding the JSON response function apiRequest($url, $post=FALSE, $headers=array()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); @@ -82,21 +106,16 @@ function apiRequest($url, $post=FALSE, $headers=array()) { if($post) curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); - $headers[] = 'Accept: application/json'; + $headers = [ + 'Accept: application/vnd.github.v3+json', + 'User-Agent: https://example-app.com/' + ]; - if(session('access_token')) - $headers[] = 'Authorization: Bearer ' . session('access_token'); + if(isset($_SESSION['access_token'])) + $headers[] = 'Authorization: Bearer ' . $_SESSION['access_token']; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($ch); - return json_decode($response); -} - -function get($key, $default=NULL) { - return array_key_exists($key, $_GET) ? $_GET[$key] : $default; -} - -function session($key, $default=NULL) { - return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default; + return json_decode($response, true); }