Added Other AP

This commit is contained in:
dev-chiefworks
2022-04-26 11:30:34 -04:00
parent 5e006a6a21
commit 47f4fad75c
251 changed files with 29298 additions and 4 deletions
+27
View File
@@ -0,0 +1,27 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /SAVVY/oauth2/
#RewriteBase /
#Checks to
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
#Header add Access-Control-Allow-Origin "*"
#Header add Access-Control-Expose-Headers "Access-Control-Allow-Origin"
#Header add Access-Control-Allow-Headers "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"
#Header add Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
#Header add Content-type "application/json"
+308
View File
@@ -0,0 +1,308 @@
<?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
+172
View File
@@ -0,0 +1,172 @@
<?php
class PullApi extends Api
{
public $apiName = 'pull';
/*
curl -H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/pull/?member_id=22&oauth2_token_id=153
*/
public function indexAction()
{
$member_id = $this->requestParams["member_id"] ?? 0;
$oauth2_token_id = $this->requestParams["oauth2_token_id"] ?? 0;
if ($oauth2_token_id<1 || $member_id<1) {
return $this->response(
array(
"error" => "Invalid request"
), 500);
}
list ($html, $result) = PullApi::callPullService($member_id, $oauth2_token_id);
if (is_array($result)) {
if (isset($result["id"])) {
return $this->response($result, 200);
} else if (isset($result["message"])) {
return $this->response(
array(
'error' => $result["message"]
), 500);
}
}
return $this->response(
array(
'error' => 'Failed to call service'
), 500);
}
public function callPullService($member_id, $oauth2_token_id) {
global $savvyext;
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
$data = http_build_query(
array(
'member_id' => $member_id,
'oauth2_token_id' => $oauth2_token_id
)
);
$url = $oauth2_url."pull?" . $data;
$opts = array(
'http' => array(
'header' =>
"Accept: application/json\r\n" .
"Authorization: Server-Token ${httpAuthToken}\r\n"
),
"ssl" => array(
"verify_peer"=>false,
"verify_peer_name"=>false,
)
);
$context = stream_context_create($opts);
$body = file_get_contents($url, false, $context);
return array($body, json_decode($body,true));
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/pull/?member_id=22&oauth2_token_id=153
* @return string
*/
public function viewAction()
{
//id must be the first parameter after /trips/x
/*
$id = array_shift($this->requestUri);
if($id && (int)$id>0){
$db = new Db();
$tripOptions = Trips::getOptionsById($db->getConnect(), (int)$id);
if(is_array($tripOptions) && count($tripOptions)>0){
return $this->response(
array(
'id' => $id,
'count' => count($tripOptions),
'options' => $tripOptions
), 200);
}
}*/
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
/**
* Method POST
* Create new record
* http://DOMAIN/pull + request parameters name, email
* @return string
*/
/*
curl -d '{"oauth2_provider_id":1, "member_id":7, "refresh_token":"refresh", "access_token":"access", "email":"acidumirae@gmail.com", "name":"Anatolii Okhotnikov"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/pull
curl -d '{"encrypted_payload": "ba16ece8fc1131ab0ecd5f0136d60d2508e982bc289b117e54b2f8f86c6e56c512ad9644b0e1655a27e8e1cd60cb39a5c3c47ae1adb83bbb65e6ab71dc4fc31233b936340b2572a0e6372de56358342d1a8e414c15e38b404c1a37e5b71f21a45ad9bf487e2830d699454ed4fddc9e8f5296771abc3c3eca5768f5184dbf056d0e50d6f0fbd5a0ad"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/pull
*/
public function createAction()
{
$message = "Invalid request";
$oauth2_provider_id = $this->requestParams["oauth2_provider_id"] ?? 0;
$member_id = $this->requestParams["member_id"] ?? 0;
$refresh_token = $this->requestParams["refresh_token"] ?? "";
$access_token = $this->requestParams["access_token"] ?? "";
$email = $this->requestParams["email"] ?? 0;
$name = $this->requestParams["name"] ?? "";
/* $refresh_token!="" && */
if ($refresh_token!="" && $oauth2_provider_id>0 && $member_id>0 && $access_token!="" && $name!=""
&& filter_var($email, FILTER_VALIDATE_EMAIL)) {
$db = new Db();
$token = OAuth2::saveToken(
$db->getConnect(),
$oauth2_provider_id,
$member_id,
$refresh_token,
$access_token,
$email,
$name);
if ($token && $token["id"]>0) {
list($html, $result) = PullApi::callPullService($member_id, $token["id"]);
if (is_array($result)) {
if (isset($result["id"])) {
$result["token"] = $token;
return $this->response($result, 200);
} else if (isset($result["message"])) {
$message = $result["message"];
} else if (isset($result["error"])) {
$message = $result["error"];
} else {
$message = $html;
}
} else {
$message = "Failed to call pull service";
}
} else {
$message = "Failed to save OAuth2 token";
}
}
return $this->response(
array(
"error" => $message
), 500);
}
public function updateAction()
{
return $this->response(
array(
"error" => "Update error"
), 400);
}
public function deleteAction()
{
return $this->response(
array(
"error" => "Delete error"
), 500);
}
}
+73
View File
@@ -0,0 +1,73 @@
<?php
class RemoveApi extends Api
{
public $apiName = 'remove';
public function indexAction()
{
return $this->response(
array(
'error' => 'Data not found'
), 404);
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/remove/1
* @return string
*/
public function viewAction()
{
//id must be the first parameter after /remove/x
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
public function createAction()
{
$message = "Unexpected remove error";
$member_id = $this->requestParams["member_id"] ?? 0;
try {
if ($member_id==null || $member_id<1) {
throw new Exception('Invalid member ID: '.$member_id);
}
$db = new Db();
// TODO: token check!
list ($res, $err) = OAuth2::remove($db->getConnect(), $member_id);
if ($res) {
return $this->response($res, 200);
} else if ($err && $err!="") {
throw new Exception($err);
} else {
throw new Exception("Failed to remove user's data");
}
} catch (Exception $e) {
$message = $e->getMessage();
}
return $this->response(
array(
"error" => $message
), 500);
}
public function updateAction()
{
return $this->response(
array(
"error" => "Update error"
), 400);
}
public function deleteAction()
{
return $this->response(
array(
"error" => "Delete error"
), 500);
}
}
@@ -0,0 +1,229 @@
<?php
class SignupOrLoginAppleApi extends Api
{
public $apiName = 'signuporloginapple';
/*
curl -H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporloginapple/?email=savvy@chiefsoft.com
*/
public function indexAction()
{
$email = $this->requestParams["email"] ?? 0;
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$db = new Db();
$result = OAuth2::getMemberByEmail($db->getConnect(), $email);
if (isset($result["id"])) {
$result["member_id"] = $result["id"];
unset($result["password"]);
return $this->response($result, 200);
} else {
return $this->response(
array(
'error' => 'Account is not found'
), 500);
}
}
return $this->response(
array(
'error' => 'Invalid e-mail'
), 500);
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/pull/?member_id=22&oauth2_token_id=153
* @return string
*/
public function viewAction()
{
//id must be the first parameter after /trips/x
/*
$id = array_shift($this->requestUri);
if($id && (int)$id>0){
$db = new Db();
$tripOptions = Trips::getOptionsById($db->getConnect(), (int)$id);
if(is_array($tripOptions) && count($tripOptions)>0){
return $this->response(
array(
'id' => $id,
'count' => count($tripOptions),
'options' => $tripOptions
), 200);
}
}*/
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
/**
* Method POST
* Create new record
* http://DOMAIN/pull + request parameters name, email
* @return string
*/
/*
{
"oauth2_provider_id":2,
"authorization_code": "c707cc913cca04439953da4df234e0781.0.mss.2i20cbkfT2jO9G3yFl5_8Q",
"identity_token": "eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3Mi0iJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoic2cubXlmbG9hdC5mbG9hdGFwcCIsImV4cCI6MTU5MjQ4Nzg4MCwiaWF0IjoxNTkyNDg3MjgwLCJzdWIiOiIwMDAwMjIuNTUwOGQxMzU0OGUxNGIyOTk4YTFmNzVlZWNlZTRiZGYuMTYyOSIsImNfaGFzaCI6IkVUcTFqazdjbE9BQlRjdmF0OFZnQUEiLCJlbWFpbCI6In1hbm1rdXJrajdAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIiwiZW1haWxfdmVyaWZpZWQiOiJ0cnVlIiwiaXNfcHJpdmF0ZV9lbWFpbCI6InRydWUiLCJhdXRoX3RpbWUiOjE1OTI0ODcyODAsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.DnptAwgs0kIsLv1LjxKZ8QetfutaDNqdHdDsPH5SG8xpzDEz798-NTBGLvcHpSHwBYLzm2W9G-VcSFRTOrjDcv1ZfzoYjwe107nTLzd5HOсEOTd-0gb3tn4xEjrdjiQxSyJKZqDUvfFO0g-x7sowzOtd3RRBIV7S0f1Cg5cX6qxJn-pSHh960oe18P8_IdykPnt-nuUZcqvsUr1tkN64SBJKCDPjZjOXJ_a0fBpOdw0BAviPiLEYtcHvtoCuSGWMBUWAueVXompo4FVVaQvp4diYFrI33H8j71t62uahgT_CKWBVeu1smBTIwANbdg-JRo8r7fr94JauPUvQh-2sZw",
"user_id": "000022.5508d13548e14b2998a1f75eecee4bdf.1629",
"email": "aciudmirae@mac.com",
"name": "Anatolii Okhotnikov"
}
curl -d '{"oauth2_provider_id":2, "identity_token":"identity_token", "authorization_code":"authorization_code", "user_id": "000022.5508d13548e14b2998a1f75eecee4bdf.1629", "email":"", "name":"Anatolii Okhotnikov"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporloginapple
curl -d '{"encrypted_payload": ""}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporloginapple
*/
public function createAction()
{
error_log("SignupOrLoginAppleApi::createAction()");
global $savvyext;
$saveToken = true;
$message = "";
$member_id = 0;
$oauth2_provider_id = (int)($this->requestParams["oauth2_provider_id"] ?? 0);
$refresh_token = $this->requestParams["identity_token"] ?? "";
$access_token = $this->requestParams["authorization_code"] ?? "";
$user_id = $this->requestParams["user_id"] ?? "";
$email = $this->requestParams["email"] ?? "";
$name = $this->requestParams["name"] ?? "";
/* $refresh_token!="" && */
if ($refresh_token=="" || $oauth2_provider_id!=2 || $access_token=="" || $user_id=="" || $name=="") {
$data = array();
$data[] = $refresh_token=="";
$data[] = $oauth2_provider_id<1;
$data[] = $access_token=="";
$data[] = $name=="";
$data[] = !filter_var($email, FILTER_VALIDATE_EMAIL);
error_log("SignupOrLoginAppleApi: Invalid OAuth2 data");
return $this->response(
array(
"debug" => $data,
"error" => "Invalid OAuth2 data"
), 500);
}
$db = new Db();
// If we login the second time there will be no email
if ($email=="" || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Get email base on the user id
$email = OAuth2::getMemberEmailByUserId($db->getConnect(), $oauth2_provider_id, $user_id);
}
$member = OAuth2::getMemberByEmail($db->getConnect(), $email);
if (isset($member["id"])) {
error_log("SignupOrLoginAppleApi: User found");
// User found
$member_id = $member["id"];
// We must create session and populate all fields properly
$in = array (
"action" => SAVVY_USER_LOGINACCOUNT,
"loc" => $_SERVER["REMOTE_ADDR"],
"pid" => 100,
"username" => $member["username"], /* Could be different from e-mail connected? */
"impersonate" => 1 /* we willbypass password check - we do not know the password! */
);
$member = $savvyext->savvyext_api($in);
// Do we save a new token?
$saveToken = true; //false;
} else {
error_log("SignupOrLoginAppleApi: Create new user");
list($firstname, $lastname) = SignupOrLoginAppleApi::splitName($name);
// Create new user
$in = array(
"action" => SAVVY_USER_CREATEACCOUNT,
"loc" => $_SERVER["REMOTE_ADDR"],
"pid" => 100,
"web" => 120012, /* MVP_DIRECT_CALL */
"start_mode" => 1,
"username" => $email,
"password" => "savvy",
"email" => $email,
"firstname" => $firstname,
"lastname" => $lastname,
"phone" => ""
);
$member = $savvyext->savvyext_api($in);
if (isset($member["member_id"]) && $member["member_id"]>0) {
//User created!
$member_id = $member["member_id"];
$surveyData = $this->requestParams["signUpSurveyData"] ?? [];
Oauth2::saveMembersSurvey($db->getConnect(), $surveyData, $member);
} else {
return $this->response(
array(
"error" => "Failed to register new user"
), 500);
}
$saveToken = true; // New user & new token?
}
// Save token
$token = array();
if ($saveToken) {
error_log("SignupOrLoginAppleApi: Will save OAuth2 token!");
$token = OAuth2::saveToken(
$db->getConnect(),
$oauth2_provider_id,
$member_id,
$refresh_token,
$access_token,
$email,
$name,
$user_id
);
} else {
error_log("SignupOrLoginAppleApi: get latest token");
// Do we get any token for the existing user?
$token = OAuth2::getLatestToken($db->getConnect(), $member_id, $oauth2_provider_id);
}
return $this->response(
array(
"error" => $message,
"token" => $token,
"member" => $member,
"member_id" => $member_id
), 200);
}
private function splitName($name) {
$my_name = trim($name);
$firstname = " ";
$lastname = " ";
$pos = strpos(trim($my_name), " ");
if ($pos!==false) {
$firstname = trim(substr($my_name, 0, $pos));
$lastname = trim(substr($my_name, $pos));
} else {
$firstname = $my_name ?? " ";
}
if ($firstname=="") $firstname = " ";
if ($lastname=="") $lastname = " ";
return array($firstname, $lastname);
}
public function updateAction() {
return $this->response(
array(
"error" => "Update error"
), 400);
}
public function deleteAction() {
return $this->response(
array(
"error" => "Delete error"
), 500);
}
}
@@ -0,0 +1,234 @@
<?php
class SignupOrLoginGoogleApi extends Api
{
public $apiName = 'signuporlogingoogle';
/*
curl -H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporlogingoogle/?email=savvy@chiefsoft.com
*/
public function indexAction()
{
$email = $this->requestParams["email"] ?? 0;
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$db = new Db();
$result = OAuth2::getMemberByEmail($db->getConnect(), $email);
if (isset($result["id"])) {
$result["member_id"] = $result["id"];
return $this->response($result, 200);
} else {
return $this->response(
array(
'error' => 'Account is not found'
), 500);
}
}
return $this->response(
array(
'error' => 'Invalid e-mail'
), 500);
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/pull/?member_id=22&oauth2_token_id=153
* @return string
*/
public function viewAction()
{
//id must be the first parameter after /trips/x
/*
$id = array_shift($this->requestUri);
if($id && (int)$id>0){
$db = new Db();
$tripOptions = Trips::getOptionsById($db->getConnect(), (int)$id);
if(is_array($tripOptions) && count($tripOptions)>0){
return $this->response(
array(
'id' => $id,
'count' => count($tripOptions),
'options' => $tripOptions
), 200);
}
}*/
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
/**
* Method POST
* Create new record
* http://DOMAIN/pull + request parameters name, email
* @return string
*/
/*
curl -d '{"oauth2_provider_id":1, "refresh_token":"refresh", "access_token":"access", "email":"acidumirae@gmail.com", "name":"Anatolii Okhotnikov"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporlogingoogle
curl -d '{"encrypted_payload": ""}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/signuporlogingoogle
*/
public function createAction()
{
error_log("SignupOrLoginGoogleApi::createAction()");
global $savvyext;
$saveToken = true;
$message = "";
$member_id = 0;
$oauth2_provider_id = (int)($this->requestParams["oauth2_provider_id"] ?? 0);
$refresh_token = $this->requestParams["refresh_token"] ?? "";
$access_token = $this->requestParams["access_token"] ?? "";
$email = $this->requestParams["email"] ?? "";
$name = $this->requestParams["name"] ?? "";
/* $refresh_token!="" && */
if ($refresh_token=="" || $oauth2_provider_id<1 || $access_token=="" || $name==""
|| !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$data = array();
$data[] = $refresh_token=="";
$data[] = $oauth2_provider_id<1;
$data[] = $access_token=="";
$data[] = $name=="";
$data[] = !filter_var($email, FILTER_VALIDATE_EMAIL);
error_log("SignupOrLoginGoogleApi: Invalid OAuth2 data");
return $this->response(
array(
"debug" => $data,
"error" => "Invalid OAuth2 data"
), 500);
}
$db = new Db();
$member = OAuth2::getMemberByEmail($db->getConnect(), $email);
if (isset($member["id"])) {
error_log("SignupOrLoginGoogleApi: User found");
// User found
$member_id = $member["id"];
// We must create session and populate all fields properly
$in = array (
"action" => SAVVY_USER_LOGINACCOUNT,
"loc" => $_SERVER["REMOTE_ADDR"],
"pid" => 100,
"username" => $member["username"], /* Could be different from e-mail connected? */
"impersonate" => 1 /* we willbypass password check - we do not know the password! */
);
$member = $savvyext->savvyext_api($in);
// Do we save a new token?
$saveToken = true; //false;
} else {
error_log("SignupOrLoginGoogleApi: Create new user");
list($firstname, $lastname) = SignupOrLoginGoogleApi::splitName($name);
// Create new user
$in = array(
"action" => SAVVY_USER_CREATEACCOUNT,
"loc" => $_SERVER["REMOTE_ADDR"],
"pid" => 100,
"web" => 120012, /* MVP_DIRECT_CALL */
"start_mode" => 1,
"username" => $email,
"password" => "savvy",
"email" => $email,
"firstname" => $firstname,
"lastname" => $lastname,
"phone" => ""
);
$member = $savvyext->savvyext_api($in);
if (isset($member["member_id"]) && $member["member_id"]>0) {
//User created!
$member_id = $member["member_id"];
$surveyData = $this->requestParams["signUpSurveyData"] ?? [];
Oauth2::saveMembersSurvey($db->getConnect(), $surveyData, $member);
} else {
return $this->response(
array(
"error" => "Failed to register new user"
), 500);
}
$saveToken = true; // New user & new token?
}
// Save token
$token = array();
if ($saveToken) {
error_log("SignupOrLoginGoogleApi: Will save OAuth2 token!");
$token = OAuth2::saveToken(
$db->getConnect(),
$oauth2_provider_id,
$member_id,
$refresh_token,
$access_token,
$email,
$name);
if ($token && $token["id"]>0) {
error_log("SignupOrLoginGoogleApi: token saved! id=".$token["id"]);
list($html, $result) = PullApi::callPullService($member_id, $token["id"]);
if (is_array($result)) {
if (isset($result["id"])) {
$result["token"] = $token;
$result["member"] = $member;
$result["member_id"] = $member_id;
return $this->response($result, 200);
} else if (isset($result["message"])) {
$message = $result["message"];
} else if (isset($result["error"])) {
$message = $result["error"];
} else {
$message = $html;
}
} else {
$message = "Failed to call pull service";
error_log("SignupOrLoginGoogleApi: ".$message);
}
} else {
$message = "Failed to save OAuth2 token";
error_log("SignupOrLoginGoogleApi: ".$message);
}
} else {
error_log("SignupOrLoginGoogleApi: get latest token");
// Do we get any token for the existing user?
$token = OAuth2::getLatestToken($db->getConnect(), $member_id, $oauth2_provider_id);
}
return $this->response(
array(
"error" => $message,
"token" => $token,
"member" => $member,
"member_id" => $member_id
), 200);
}
private function splitName($name) {
$my_name = trim($name);
$firstname = " ";
$lastname = " ";
$pos = strpos(trim($my_name), " ");
if ($pos!==false) {
$firstname = trim(substr($my_name, 0, $pos));
$lastname = trim(substr($my_name, $pos));
} else {
$firstname = $my_name ?? " ";
}
if ($firstname=="") $firstname = " ";
if ($lastname=="") $lastname = " ";
return array($firstname, $lastname);
}
public function updateAction() {
return $this->response(
array(
"error" => "Update error"
), 400);
}
public function deleteAction() {
return $this->response(
array(
"error" => "Delete error"
), 500);
}
}
+167
View File
@@ -0,0 +1,167 @@
<?php
class TokenApi extends Api
{
public $apiName = 'token';
/**
* Method GET
* Get all records
* http://DOMAIN/token
* @return string
*/
/*
curl -H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/token/?member_id=3
*/
public function indexAction()
{
// Get the parameters
$member_id = (int)($this->requestParams['member_id'] ?? 0);
if ($member_id<1) {
return $this->response(
array(
'error' => 'Data not found'
), 404);
}
$db = new Db();
list ($total, $tokens) = OAuth2::getAllTokens($db->getConnect(), $member_id);
if($total>0){
return $this->response(
array(
'member_id' => $member_id,
'limit' => (int)$total,
'offset' => 0,
'count' => count($tokens),
'total' => (int)$total,
'tokens' => $tokens
), 200);
}
return $this->response(
array(
'error' => 'Data not found'
), 404);
}
/**
* Method GET
* Get single record (by id)
* http://DOMAIN/token/1
* @return string
*/
/*
curl -H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/token/108
*/
public function viewAction()
{
//id must be the first parameter after /token/x
$id = array_shift($this->requestUri);
if($id && (int)$id>0){
$db = new Db();
$token = OAuth2::getTokenById($db->getConnect(), (int)$id);
if(is_array($token) && count($token)>0){
return $this->response($token, 200);
}
}
return $this->response(
array(
'error'=> 'Data not found'
), 404);
}
/**
* Method POST
* Create new record
* http://DOMAIN/token + request parameters name, email
* @return string
*/
/*
curl -d '{"oauth2_provider_id":1, "member_id":7, "refresh_token":"refresh", "access_token":"access", "email":"acidumirae@gmail.com", "name":"Anatolii Okhotnikov"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/token
curl -d '{"encrypted_payload": "ba3ea1e6e8102df163e25d1c2fc900241fc4b4b16e831a63589ab7f0646151d23f9b9b02a8ec7b482990a6d977c838a8efd84afea7bd7cef65aeec358220921b72f67365191965aafe211cb33611736f3296064017e98211051a68a4e30c358550ddf4173a3a3cd9891e40d2e29fd7c51795771eb5306787692baf4e16f13472041889b1ce99cba4c0ffd18aac27703881aa7353f583e565a6"}' \
-H "Content-Type: application/json" -H "Authorization: Server-Token 99dfe35fcb7de1ee" \
-X POST https://svrsavvy.sworks.float.sg/SAVVY/oauth2/api/token
*/
public function createAction()
{
$message = "Unknown error";
$oauth2_provider_id = $this->requestParams["oauth2_provider_id"] ?? 0;
$member_id = $this->requestParams["member_id"] ?? 0;
$refresh_token = $this->requestParams["refresh_token"] ?? "";
$access_token = $this->requestParams["access_token"] ?? "";
$email = $this->requestParams["email"] ?? 0;
$name = $this->requestParams["name"] ?? "";
if ($oauth2_provider_id>0 && $member_id>0 && $refresh_token!="" && $access_token!="" && $name!=""
&& filter_var($email, FILTER_VALIDATE_EMAIL)) {
$db = new Db();
$token = OAuth2::saveToken(
$db->getConnect(),
$oauth2_provider_id,
$member_id,
$refresh_token,
$access_token,
$email,
$name);
if ($token && $token["id"]>0) {
return $this->response($token, 200);
}
}
return $this->response(
array(
"error" => "Invalid request"
), 500);
}
/**
* Method PUT
* Update single record (by id)
* http://DOMAIN/token/1 + request parameters name, email
* @return string
*/
public function updateAction()
{
$member_id = $this->requestParams["member_id"] ?? 0;
if ($member_id>0) {
$db = new Db();
$updated = OAuth2::removeTokens($db->getConnect(), $member_id);
if ($updated) {
return $this->response($updated, 200);
}
}
return $this->response(
array(
"error" => "Update error"
), 400);
}
/**
* Method DELETE
* Delete single record (by id)
* http://DOMAIN/token/1
* @return string
*/
public function deleteAction()
{/*
$parse_url = parse_url($this->requestUri[0]);
$userId = $parse_url['path'] ?? null;
$db = (new Db())->getConnect();
if(!$userId || !Trips::getById($db, $userId)){
return $this->response("Trip with id=$userId not found", 404);
}
if(Trips::deleteById($db, $userId)){
return $this->response('Data deleted.', 200);
}*/
return $this->response(
array(
"error" => "Delete error"
), 500);
}
}
+69
View File
@@ -0,0 +1,69 @@
<?php
require_once('../common/vendor/autoload.php');
require_once('../../core/backend.php');
require_once('../constants.php');
require_once('../common/Api.php');
require_once('../common/Db.php');
require_once('../common/GoogleKMS.php');
require_once('OAuth2.php');
require_once('TokenApi.php');
require_once('PullApi.php');
require_once('RemoveApi.php');
require_once('SignupOrLoginAppleApi.php');
require_once('SignupOrLoginGoogleApi.php');
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
header("Access-Control-Allow-Origin: *");
header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, client_id");
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
header('Content-type: application/json');
if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
exit();
}
$headers = getallheaders();
if ((!isset($headers["Authorization"]) || substr($headers["Authorization"],-strlen($httpAuthToken))!=$httpAuthToken) &&
(!isset($headers["authorization"]) || substr($headers["authorization"],-strlen($httpAuthToken))!=$httpAuthToken)) {
header('HTTP/1.1 401 Unauthorized');
header('Status: 401 Unauthorized');
echo "{\"status\":\"Missing authorization\"}";
exit();
}
try {
if (strpos($_SERVER['REQUEST_URI'],'/api/')===false) {
throw new Exception("Invalid API request");
}
$requestUri = explode('/', trim($_SERVER['REQUEST_URI'],'/'));
while (array_shift($requestUri) !== 'api') {
};
if ($requestUri[0]=='token') {
$api = new TokenApi($requestUri);
}
else if ($requestUri[0]=='pull') {
$api = new PullApi($requestUri);
}
else if ($requestUri[0]=='remove') {
$api = new RemoveApi($requestUri);
}
else if ($requestUri[0]=='signuporloginapple') {
$api = new SignupOrLoginAppleApi($requestUri);
}
else if ($requestUri[0]=='signuporlogingoogle') {
$api = new SignupOrLoginGoogleApi($requestUri);
}
else {
echo json_encode(Array('error' => 'Invalid API request'));
}
echo $api->run();
}
catch (Exception $e) {
echo json_encode(Array('error' => $e->getMessage()));
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

@@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="swagger-ui.css" >
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="swagger-ui-bundle.js"> </script>
<script src="swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "../swagger.php",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
<?php
require('../../../adminsavvy/vendor/autoload.php');
$openapi = \OpenApi\scan('.');
header('Content-Type: application/json');
echo $openapi->toJson();
?>