From c89f1e6b961b5b0b7c76362e58cd55461897e3f8 Mon Sep 17 00:00:00 2001
From: Aaron Parecki <aaron@parecki.com>
Date: Wed, 18 Apr 2018 16:21:12 -0700
Subject: [PATCH] updates

---
 github.php | 91 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 55 insertions(+), 36 deletions(-)

diff --git a/github.php b/github.php
index 0e9238a..3e50a12 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);
 }
-- 
GitLab