Files
dev-chiefworks 47f4fad75c Added Other AP
2022-04-26 11:30:34 -04:00

309 lines
11 KiB
PHP

<?php
class OAuth2 {
public function getAllTokens($db, $member_id) {
$result = array();
$total = 0;
$q = "SELECT * FROM oauth2_tokens WHERE member_id=${member_id} ORDER BY id DESC";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
$total = pg_num_rows($r);
while($f=pg_fetch_assoc($r)) {
list($decrypted,$googleKMS) = self::decrypt($f["refresh_token_encrypted"]);
$f["refresh_token"] = $decrypted;
list($decrypted,$googleKMS) = self::decrypt($f["access_token_encrypted"], $googleKMS);
$f["access_token"] = $decrypted;
$result[] = $f;
}
}
return array($total, $result);
}
public function getLatestToken($db, $member_id, $oauth_provider_id) {
$result = array();
$total = 0;
$q = "SELECT * FROM oauth2_tokens WHERE member_id=${member_id} AND oauth_provider_id=${oauth_provider_id} ORDER BY id DESC LIMIT 1";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
list($decrypted,$googleKMS) = self::decrypt($f["refresh_token_encrypted"]);
$f["refresh_token"] = $decrypted;
list($decrypted,$googleKMS) = self::decrypt($f["access_token_encrypted"], $googleKMS);
$f["access_token"] = $decrypted;
$result = $f;
}
return $result;
}
public function getTokenById($db, $id) {
$result = array();
$q = "SELECT * FROM oauth2_tokens WHERE id=${id}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
list($decrypted,$googleKMS) = self::decrypt($f["refresh_token_encrypted"]);
$f["refresh_token"] = $decrypted;
list($decrypted,$googleKMS) = self::decrypt($f["access_token_encrypted"], $googleKMS);
$f["access_token"] = $decrypted;
$result = $f;
}
return $result;
}
private function encrypt($plainText, $googleKMS=NULL) {
global $savvyext;
$cipherText = NULL;
try {
if ($googleKMS==NULL) {
$projectId = $savvyext->cfgReadChar('google.kms_project_id');
$authFile = $savvyext->cfgReadChar('google.kms_auth_file');
$keyRingId = $savvyext->cfgReadChar('google.kms_keyring_id');
$keyId = $savvyext->cfgReadChar('google.kms_key_id');
/*error_log("projectId=$projectId");
error_log("authFile=$authFile");
error_log("keyRingId=$keyRingId");
error_log("keyId=$keyId");*/
$googleKMS = new GoogleKMS(
$projectId,
$authFile,
$keyRingId,
$keyId
);
}
$cipherText = bin2hex($googleKMS->encrypt($plainText));
} catch (Exception $e) {
error_log($e->getMessage());
}
return [$cipherText, $googleKMS];
}
private function decrypt($cipherText, $googleKMS=NULL) {
global $savvyext;
$plainText = NULL;
try {
if ($googleKMS==NULL) {
$projectId = $savvyext->cfgReadChar('google.kms_project_id');
$authFile = $savvyext->cfgReadChar('google.kms_auth_file');
$keyRingId = $savvyext->cfgReadChar('google.kms_keyring_id');
$keyId = $savvyext->cfgReadChar('google.kms_key_id');
$googleKMS = new GoogleKMS(
$projectId,
$authFile,
$keyRingId,
$keyId
);
}
$plainText = $googleKMS->decrypt(hex2bin($cipherText));
} catch (Exception $e) {
error_log($e->getMessage());
}
return [$plainText, $googleKMS];
}
public function saveToken($db, $oauth2_provider_id, $member_id, $refresh_token, $access_token, $email, $name, $user_id="") {
$result = array();
$db_oauth2_provider_id = (int)$oauth2_provider_id;
$db_member_id = (int)$member_id;
// TODO: clear
$db_refresh_token = substr(pg_escape_string($refresh_token),0,500);
// TODO: clear
$db_access_token = substr(pg_escape_string($access_token),0,500);
list($refresh_token_encrypted,$googleKMS) = self::encrypt($refresh_token);
$db_refresh_token_encrypted = pg_escape_string($refresh_token_encrypted);
list($access_token_encrypted,$googleKMS) = self::encrypt($access_token, $googleKMS);
$db_access_token_encrypted = pg_escape_string($access_token_encrypted);
if ($refresh_token_encrypted==NULL || $access_token_encrypted==NULL) {
return NULL;
}
$db_email = pg_escape_string($email);
$db_name = pg_escape_string($name);
$db_user_id = pg_escape_string($user_id);
$q = "INSERT INTO oauth2_tokens (oauth2_provider_id, member_id, refresh_token, access_token, ";
$q.= "email, name, expires_in, refresh_token_encrypted, access_token_encrypted, user_id) VALUES (";
$q.= "${db_oauth2_provider_id},${db_member_id},'${db_refresh_token}','${db_access_token}',";
$q.= "'${db_email}','${db_name}',now() + interval '3600','${db_refresh_token_encrypted}',";
$q.= "'${db_access_token_encrypted}','${db_user_id}'";
$q.= ") RETURNING id";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_row($r)) {
OAuth2::updateMemberEmailStatus($db, $db_member_id, 1);
return OAuth2::getTokenById($db, $f[0]);
}
return NULL;
}
public function getMemberByEmail($db, $email) {
$result = array();
$db_email = pg_escape_string(strtolower($email));
$q = "SELECT * FROM members WHERE lower(email)='${db_email}' OR lower(username)='${db_email}'";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
$result = $f;
}
return $result;
}
public static function getMemberEmailByUserId($db, $oauth2_provider_id, $user_id) {
$db_oauth2_provider_id = (int)$oauth2_provider_id;
$db_user_id = pg_escape_string($user_id);
$q = "SELECT email FROM oauth2_tokens WHERE oauth2_provider_id=${db_oauth2_provider_id} ";
$q.= " AND user_id='${db_user_id}' AND (email<>'' OR email IS NOT NULL) ORDER BY created DESC LIMIT 1";
// error_log($q);
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_row($r)) {
return $f[0];
}
return NULL;
}
public function remove($db, $member_id) {
$res = NULL;
$err = NULL;
$mid = (int)$member_id;
try {
$q = "SELECT md5(username) AS username,md5(firstname) AS firstname,md5(lastname) AS lastname,md5(email) AS email,md5(phone) AS phone,password FROM members WHERE id=${mid}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
$nmid = 0;
$vals = []; $keys = [];
foreach ($f as $key=>$val) {
$keys[] = $key;
$vals[] = $val;
}
$q = "INSERT INTO members (id,".implode(",",$keys).") VALUES(-${mid},'".implode("','",$vals)."') RETURNING id";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
$nmid = $f['id'];
} else {
$q = "SELECT * FROM members WHERE id=-${mid}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
$nmid = $f['id'];
} else {
throw new Exception("Failed to hash member data");
}
}
if ($nmid<0) {
$needs_delete = false;
$q = "SELECT * FROM trackedemail_item WHERE member_id=${mid}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
$needs_delete = true;
}
if ($needs_delete) {
// TODO: clear e-mail data...
//$q = "UPDATE trackedemail_item SET member_id=-${mid},subject=NULL,message=NULL,message_from=NULL,hash=NULL,oauth2_pull_job_id=NULL,message_date=NULL WHERE member_id=${mid}";
// DEBUG: testing
$q = "UPDATE trackedemail_item SET member_id=-${mid} WHERE member_id=${mid}";
$r = pg_query($db, $q);
if ($r && pg_affected_rows($r)) {
$res["mails_deleted"] = pg_affected_rows($r);
$res["message"] = "E-mails deleted";
} else {
throw new Exception("Failed to delete messages!");
}
} else {
$res["mails_deleted"] = 0;
$res["message"] = "No e-mails found to delete";
}
// TODO: delete...
$r = null;
// Delete OAuth2 pull job threads
$q = "delete from oauth2_pull_job_threads where oauth2_token_id in (select id from oauth2_tokens where member_id=${mid})";
//$r = pg_query($db, $q);
$res["pull_threads_deleted"] = (int)pg_affected_rows($r);
// Delete OAuth2 pull jobs
$q = "delete from oauth2_pull_jobs where oauth2_token_id in (select id from oauth2_tokens where member_id=${mid})";
//$r = pg_query($db, $q);
$res["pull_jobs_deleted"] = (int)pg_affected_rows($r);
// Delete OAuth2 tokens
$q = "delete from oauth2_tokens where member_id=${mid}";
//$r = pg_query($db, $q);
$res["oauth2_tokens_deleted"] = (int)pg_affected_rows($r);
} else {
throw new Exception("Failed to hash member's data");
}
} else {
throw new Exception("Failed to load member record");
}
} catch (Exception $e) {
$err = $e->getMessage();
if (pg_last_error()!="") {
$err.= ": ".pg_last_error();
}
}
return [$res, $err];
}
function updateMemberEmailStatus($db, $member_id, $status=0){
try {
$q = "UPDATE members SET email_connected=${status} WHERE id=${member_id}";
error_log('update email connected: '.$q);
$r = pg_query($db, $q);
} catch (Exception $e) {
$err = $e->getMessage();
if (pg_last_error()!="") {
$err.= ": ".pg_last_error();
error_log('update email connected error: '.$err);
}
}
}
function removeTokens($db, $member_id){
$res = NULL;
$err = NULL;
$mid = (int)$member_id;
try {
$q = "SELECT member_id FROM oauth2_tokens WHERE member_id=${mid}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
OAuth2::updateMemberEmailStatus($db, $mid, 0);
$q = "UPDATE oauth2_pull_job_threads SET started=NOW(), completed=NOW() WHERE oauth2_token_id IN (SELECT id FROM oauth2_tokens WHERE member_id=${mid})";
error_log('update oauth2_pull_job_threads: '.$q);
$r = pg_query($db, $q);
$q = "UPDATE oauth2_pull_jobs SET started=NOW(), completed=NOW() WHERE oauth2_token_id IN (SELECT id FROM oauth2_tokens WHERE member_id=${mid})";
error_log('update oauth2_pull_jobs: '.$q);
$r = pg_query($db, $q);
$q = "UPDATE oauth2_tokens SET expires_in=now()-interval '4 hours' WHERE member_id=${mid}";
error_log('update oauth2_tokens: '.$q);
$r = pg_query($db, $q);
$res["message"] = "Email is disconnected";
$res["oauth2_tokens_deleted"] = (int)pg_affected_rows($r);
} else {
throw new Exception("Failed to load tokens");
}
} catch (Exception $e) {
$err = $e->getMessage();
if (pg_last_error()!="") {
$err.= ": ".pg_last_error();
}
}
error_log('removeTokens: '.json_encode([$res, $err]));
return [$res, $err];
}
function saveMembersSurvey($db, $surveyData,$out) {
if (empty($out["added"])) {//only save first time
$member_id = $out['member_id'];
foreach($surveyData as $group_key=>$survey){
$answers = isset($survey['answers'])?$survey['answers']:[];
foreach($answers as $answer_key => $value){
if($value==true){
$q = "INSERT INTO members_onboarding_survey ( member_id, answers_key, answers,status, added) VALUES (" . $member_id . ",'" . $answer_key . "','" . $value . "', 1, now())";
$res1 = pg_query($db, $q);
if ($res1 and pg_num_rows($res1) > 0) {
//logger
}
}
}
}
}
}
}
// vi:ts=2