Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub authentication extra #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 56 additions & 3 deletions login-github.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
define('CLIENT_ENABLED', get_option('wpoa_github_api_enabled'));
define('CLIENT_ID', get_option('wpoa_github_api_id'));
define('CLIENT_SECRET', get_option('wpoa_github_api_secret'));
define('RESTRICT_ORGANISATION', get_option('wpoa_github_api_organisation'));
define('REDIRECT_URI', rtrim(site_url(), '/') . '/');
define('SCOPE', 'user'); // PROVIDER SPECIFIC: "user" is the minimum scope required to get the user's id from Github
define('SCOPE', ''); // PROVIDER SPECIFIC: Empty string gives us everything we need and is read only.
define('URL_AUTH', "https://github.com/login/oauth/authorize?");
define('URL_TOKEN', "https://github.com/login/oauth/access_token?");
define('URL_USER', "https://api.github.com/user?");
define('URL_ORGANISATION', "https://api.github.com/orgs/".RESTRICT_ORGANISATION."/members?");
# END OF DEFINE THE OAUTH PROVIDER AND SETTINGS TO USE #

// remember the user's last url so we can redirect them back to there after the login ends:
Expand Down Expand Up @@ -142,6 +144,7 @@ function get_oauth_identity($wpoa) {
'access_token' => $_SESSION['WPOA']['ACCESS_TOKEN'], // PROVIDER SPECIFIC: the access token is passed to Github using this key name
);
$url_params = http_build_query($params);

// perform the http request:
switch (strtolower(HTTP_UTIL)) {
case 'curl':
Expand All @@ -154,6 +157,18 @@ function get_oauth_identity($wpoa) {
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
$result_obj = json_decode($result, true);

// Find organisation members
if(strlen(RESTRICT_ORGANISATION) > 0){
$m_url = URL_ORGANISATION . $url_params; // TODO: we probably want to send this using a curl_setopt...
$m_curl = curl_init();
curl_setopt($m_curl, CURLOPT_URL, $m_url);
curl_setopt($m_curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($m_curl, CURLOPT_RETURNTRANSFER, 1);
$members = curl_exec($m_curl);
$members_obj = json_decode($members, true);
}

break;
case 'stream-context':
$url = rtrim(URL_USER, "?");
Expand All @@ -164,23 +179,61 @@ function get_oauth_identity($wpoa) {
'header' => "Authorization: token " . $_SESSION['WPOA']['ACCESS_TOKEN'],
)
);
$context = $context = stream_context_create($opts);
$context = stream_context_create($opts);
$result = @file_get_contents($url, false, $context);
if ($result === false) {
$wpoa->wpoa_end_login("Sorry, we couldn't log you in. Could not retrieve user identity via stream context. Please notify the admin or try again later.");
}
$result_obj = json_decode($result, true);

// Find organisation members
if(strlen(RESTRICT_ORGANISATION) > 0){
$m_url = rtrim(URL_ORGANISATION, "?");
$members = @file_get_contents($m_url, false, $context);
if ($members === false) {
$wpoa->wpoa_end_login("Sorry, we couldn't find the GitHub organisation members list. Please notify the admin or try again later.");
}
$members_obj = json_decode($result, true);
}

break;
}

// GitHub organisation membership check
if(strlen(RESTRICT_ORGANISATION) > 0){
$has_membership = false;
foreach($members_obj as $member){
if(isset($member['id']) && $member['id'] == $result_obj['id']){
$has_membership = true;
}
}
if(!$has_membership){
$wpoa->wpoa_end_login("Sorry, you need to be a member of the <a href='https://github.com/".RESTRICT_ORGANISATION."' target='_blank'>".RESTRICT_ORGANISATION."</a> GitHub organisation to log into this site.");
}
}

// Check that we have the user ID
if(!isset($result_obj['id']) or strlen($result_obj['id']) == 0){
$wpoa->wpoa_end_login("Error - could not find the user ID from GitHub.");
}

// parse and return the user's oauth identity:
$oauth_identity = array();
$oauth_identity['provider'] = $_SESSION['WPOA']['PROVIDER'];
$oauth_identity['id'] = $result_obj['id']; // PROVIDER SPECIFIC: this is how Github returns the user's unique id
//$oauth_identity['email'] = $result_obj['email']; //PROVIDER SPECIFIC: this is how Github returns the email address

// Bonus data from GitHub
$oauth_identity['oa_login'] = $result_obj['login'];
$oauth_identity['oa_email'] = $result_obj['email'];
$oauth_identity['oa_nicename'] = $result_obj['name'];
$oauth_identity['oa_desc'] = $result_obj['bio'];
$oauth_identity['oa_url'] = $result_obj['blog'];

if (!$oauth_identity['id']) {
$wpoa->wpoa_end_login("Sorry, we couldn't log you in. User identity was not found. Please notify the admin or try again later.");
}
return $oauth_identity;
}
# END OF AUTHENTICATION FLOW HELPER FUNCTIONS #
?>
?>
111 changes: 110 additions & 1 deletion register.php
Original file line number Diff line number Diff line change
@@ -1 +1,110 @@
<?php// TODO: very important that we sanitize all $_POST variables here before using them!// TODO: this doesn't call wpoa_end_login() which might result in the LAST_URL not being cleared...global $wpdb;// initiate the user session:session_start();// prevent users from registering if the option is turned off in the dashboard:if (!get_option("users_can_register")) { $_SESSION["WPOA"]["RESULT"] = "Sorry, user registration is disabled at this time. Your account could not be registered. Please notify the admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;}// registration was initiated from an oauth provider, set the username and password automatically.if ($_SESSION["WPOA"]["USER_ID"] != "") { $username = uniqid('', true); $password = wp_generate_password();}// registration was initiated from the standard sign up form, set the username and password that was requested by the user.if ( $_SESSION["WPOA"]["USER_ID"] == "" ) { // this registration was initiated from the standard Registration page, create account and login the user automatically $username = $_POST['identity']; $password = $_POST['password'];}// now attempt to generate the user and get the user id:$user_id = wp_create_user( $username, $password, $username ); // we use wp_create_user instead of wp_insert_user so we can handle the error when the user being registered already exists// check if the user was actually created:if (is_wp_error($user_id)) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = $user_id->get_error_message(); header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;}// now try to update the username to something more permanent and recognizable:$username = "user" . $user_id;$update_username_result = $wpdb->update($wpdb->users, array('user_login' => $username, 'user_nicename' => $username, 'display_name' => $username), array('ID' => $user_id));$update_nickname_result = update_user_meta($user_id, 'nickname', $username);// apply the custom default user role:$role = get_option('wpoa_new_user_role');$update_role_result = wp_update_user(array('ID' => $user_id, 'role' => $role));// proceed if no errors were detected:if ($update_username_result == false || $update_nickname_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not rename the username during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;}elseif ($update_role_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not assign default user role during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;}else { // registration was successful, the user account was created, proceed to login the user automatically... // associate the wordpress user account with the now-authenticated third party account: $this->wpoa_link_account($user_id); // attempt to login the new user (this could be error prone): $creds = array(); $creds['user_login'] = $username; $creds['user_password'] = $password; $creds['remember'] = true; $user = wp_signon( $creds, false ); // send a notification e-mail to the admin and the new user (we can also build our own email if necessary): if (!get_option('wpoa_suppress_welcome_email')) { //wp_mail($username, "New User Registration", "Thank you for registering!\r\nYour username: " . $username . "\r\nYour password: " . $password, $headers); wp_new_user_notification( $user_id, $password ); } // finally redirect the user back to the page they were on and notify them of successful registration: $_SESSION["WPOA"]["RESULT"] = "You have been registered successfully!"; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;}?>
<?php

// TODO: very important that we sanitize all $_POST variables here before using them!
// TODO: this doesn't call wpoa_end_login() which might result in the LAST_URL not being cleared...

global $wpdb;

// initiate the user session:
session_start();

// prevent users from registering if the option is turned off in the dashboard:
if (!get_option("users_can_register")) {
$_SESSION["WPOA"]["RESULT"] = "Sorry, user registration is disabled at this time. Your account could not be registered. Please notify the admin or try again later.";
header("Location: " . $_SESSION["WPOA"]["LAST_URL"]);
exit;
}

// registration was initiated from an oauth provider, set the username and password automatically.
if ($_SESSION["WPOA"]["USER_ID"] != "") {

// Try to use same username as the provider
if(isset($_SESSION['WPOA']['OA_USERNAME']) && strlen($_SESSION['WPOA']['OA_USERNAME']) > 0){
$username = $_SESSION['WPOA']['OA_USERNAME'];
} else {
$username = uniqid('', true);
}
$password = wp_generate_password();
}

// registration was initiated from the standard sign up form, set the username and password that was requested by the user.
if ( $_SESSION["WPOA"]["USER_ID"] == "" ) {
// this registration was initiated from the standard Registration page, create account and login the user automatically
$username = $_POST['identity'];
$password = $_POST['password'];
}

// Try to register with the OA e-mail address if we have it
// NB: Not a security risk. This e-mail address can't be used to log in.
if(isset($_SESSION['WPOA']['OA_EMAIL']) && strlen($_SESSION['WPOA']['OA_EMAIL']) > 0){
$email = $_SESSION['WPOA']['OA_EMAIL'];
} else {
$email = $username; // not sure why we do this, but was previous behaviour so leaving it here.
}

// now attempt to generate the user and get the user id:
$user_id = wp_create_user( $username, $password, $email ); // we use wp_create_user instead of wp_insert_user so we can handle the error when the user being registered already exists

// check if the user was actually created:
if (is_wp_error($user_id)) {
// there was an error during registration, redirect and notify the user:
$_SESSION["WPOA"]["RESULT"] = $user_id->get_error_message();
header("Location: " . $_SESSION["WPOA"]["LAST_URL"]);
exit;
}

// now try to update the username to something more permanent and recognizable:
if(isset($_SESSION['WPOA']['OA_NICENAME']) && strlen($_SESSION['WPOA']['OA_NICENAME']) > 0){
$nicename = $_SESSION['WPOA']['OA_NICENAME'];
} else {
$nicename = $username;
}
$update_username_result = $wpdb->update($wpdb->users, array('user_login' => $username, 'user_nicename' => $nicename, 'display_name' => $nicename), array('ID' => $user_id));
$update_nickname_result = update_user_meta($user_id, 'nickname', $nicename);

// Update new user with other OA metadata if we have it
if(isset($_SESSION['WPOA']['GH_BIO']) && strlen($_SESSION['WPOA']['OA_DESC']) > 0){
update_user_meta( $user_id, 'description', $_SESSION['WPOA']['OA_DESC']);
}
if(isset($_SESSION['WPOA']['OA_URL']) && strlen($_SESSION['WPOA']['OA_URL']) > 0){
$update_username_result = $wpdb->update($wpdb->users, array('user_url' => $_SESSION['WPOA']['OA_URL']), array('ID' => $user_id));
}




// apply the custom default user role:
$role = get_option('wpoa_new_user_role');
$update_role_result = wp_update_user(array('ID' => $user_id, 'role' => $role));

// proceed if no errors were detected:
if ($update_username_result == false || $update_nickname_result == false) {
// there was an error during registration, redirect and notify the user:
$_SESSION["WPOA"]["RESULT"] = "Could not rename the username during registration. Please contact an admin or try again later.";
header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;
}
elseif ($update_role_result == false) {
// there was an error during registration, redirect and notify the user:
$_SESSION["WPOA"]["RESULT"] = "Could not assign default user role during registration. Please contact an admin or try again later.";
header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit;
}
else {
// registration was successful, the user account was created, proceed to login the user automatically...
// associate the wordpress user account with the now-authenticated third party account:
$this->wpoa_link_account($user_id);
// attempt to login the new user (this could be error prone):
$creds = array();
$creds['user_login'] = $username;
$creds['user_password'] = $password;
$creds['remember'] = true;
$user = wp_signon( $creds, false );
// send a notification e-mail to the admin and the new user (we can also build our own email if necessary):
if (!get_option('wpoa_suppress_welcome_email')) {
//wp_mail($username, "New User Registration", "Thank you for registering!\r\nYour username: " . $username . "\r\nYour password: " . $password, $headers);
wp_new_user_notification( $user_id, $password );
}
// finally redirect the user back to the page they were on and notify them of successful registration:
$_SESSION["WPOA"]["RESULT"] = "You have been registered successfully!";
$this->wpoa_end_login("You have been registered successfully!");
}
?>
Loading