This repository has been archived by the owner on Dec 16, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update to 9.16.2.0. MUST GET AN API KEY, SEE README
Showing
10 changed files
with
523 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
include_once dirname(__FILE__) . '/CasperAgent.php'; | ||
include_once dirname(__FILE__) . '/CasperException.php'; | ||
|
||
/** | ||
* @file | ||
* PHP implementation of the Casper API. | ||
*/ | ||
class CasperAPI extends CasperAgent { | ||
|
||
const SNAPCHAT_VERSION = "9.16.2.0"; | ||
|
||
public function __construct($api_key = null, $api_secret = null){ | ||
parent::setAPIKey($api_key); | ||
parent::setAPISecret($api_secret); | ||
} | ||
|
||
public function getSnapchatInfo(){ | ||
return parent::get("/snapchat"); | ||
} | ||
|
||
/** | ||
* Fetches a Snapchat Client Auth Signature (X-Snapchat-Client-Auth) from the Casper API | ||
* | ||
* @param string $username | ||
* Your Snapchat Username | ||
* | ||
* @param string $password | ||
* Your Snapchat Password | ||
* | ||
* @param string $timestamp | ||
* The timestamp you send in the Snapchat Login Request | ||
* | ||
* @return string | ||
* The Client Auth Token | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function getSnapchatClientAuth($username, $password, $timestamp){ | ||
|
||
$response = parent::post("/snapchat/clientauth/signrequest", null, array( | ||
"username" => $username, | ||
"password" => $password, | ||
"timestamp" => $timestamp, | ||
"snapchat_version" => self::SNAPCHAT_VERSION | ||
)); | ||
|
||
if(!isset($response->signature)){ | ||
throw new CasperException("Signature not found in Response"); | ||
} | ||
|
||
return $response->signature; | ||
|
||
} | ||
|
||
/** | ||
* Fetches an Attestation by making multiple API calls to the Google and Casper APIs. | ||
* | ||
* @param string $nonce | ||
* Base64 encoded value of the nonce | ||
* sha256(username|password|timestamp|/loq/login) | ||
* | ||
* @return string | ||
* The Client Auth Token | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function getSnapchatAttestation($nonce){ | ||
|
||
$response = parent::get("/snapchat/attestation/create"); | ||
|
||
if(!isset($response->binary)){ | ||
throw new CasperException("Binary not found in Response"); | ||
} | ||
|
||
$binary = base64_decode($response->binary); | ||
|
||
$response = parent::externalRequest("https://www.googleapis.com/androidantiabuse/v1/x/create?alt=PROTO&key=AIzaSyBofcZsgLSS7BOnBjZPEkk4rYwzOIz-lTI", array( | ||
"Content-Type: application/x-protobuf", | ||
"User-Agent: SafetyNet/7899000 (klte KOT49H); gzip" | ||
), $binary, true); | ||
|
||
$protobuf = base64_encode($response); | ||
|
||
$response = parent::post("/snapchat/attestation/attest", null, array( | ||
"protobuf" => $protobuf, | ||
"nonce" => $nonce, | ||
"snapchat_version" => self::SNAPCHAT_VERSION | ||
)); | ||
|
||
if(!isset($response->binary)){ | ||
throw new CasperException("Binary not found in Response"); | ||
} | ||
|
||
$binary = base64_decode($response->binary); | ||
|
||
$response = parent::externalRequest("https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=JSON&key=AIzaSyDqVnJBjE5ymo--oBJt3On7HQx9xNm1RHA", array( | ||
"Content-Type: application/x-protobuf", | ||
"User-Agent: SafetyNet/7899000 (klte KOT49H); gzip" | ||
), $binary, true); | ||
|
||
$json = json_decode($response); | ||
if($json == null){ | ||
throw new CasperException("Failed to decode response!"); | ||
} | ||
|
||
if(!isset($json->signedAttestation)){ | ||
throw new CasperException("Attestation not found in Response"); | ||
} | ||
|
||
return $json->signedAttestation; | ||
|
||
} | ||
|
||
/** | ||
* Generates an Nonce for Attestation requests. | ||
* | ||
* @param string $username | ||
* Snapchat Username | ||
* | ||
* @param string $password | ||
* Snapchat Password | ||
* | ||
* @param string $timestamp | ||
* Snapchat Login Timestamp | ||
* | ||
* @param string $endpoint | ||
* Snapchat Login Endpoint, always /loq/login at this stage. | ||
* | ||
* @return string | ||
* The Base64 Encoded Nonce | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function generateSnapchatNonce($username, $password, $timestamp, $endpoint = "/loq/login"){ | ||
return base64_encode(hash("sha256", "{$username}|{$password}|{$timestamp}|{$endpoint}", true)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
<?php | ||
|
||
/** | ||
* @file | ||
* Base methods of the CasperAPI class. | ||
*/ | ||
abstract class CasperAgent { | ||
|
||
/** | ||
* @var string Your Casper API Key | ||
*/ | ||
public $API_KEY; | ||
|
||
/** | ||
* @var string Your Casper API Secret | ||
*/ | ||
public $API_SECRET; | ||
|
||
/** | ||
* The User-Agent used in requests to the Casper API | ||
*/ | ||
const USER_AGENT = "Casper-API-PHP/1.0.0"; | ||
|
||
/* | ||
* The Casper API URL. | ||
*/ | ||
const URL = "https://api.casper.io"; | ||
|
||
/** | ||
* Default cURL headers. | ||
*/ | ||
public static $CURL_HEADERS = array( | ||
|
||
); | ||
|
||
/** | ||
* Default cURL options. | ||
*/ | ||
public static $CURL_OPTIONS = array( | ||
CURLOPT_TIMEOUT => 10, | ||
CURLOPT_CONNECTTIMEOUT => 10, | ||
CURLOPT_USERAGENT => self::USER_AGENT, | ||
CURLOPT_HEADER => false, | ||
CURLINFO_HEADER_OUT => true, | ||
CURLOPT_RETURNTRANSFER => true, | ||
CURLOPT_ENCODING => "gzip" | ||
); | ||
|
||
public function setAPIKey($api_key = null){ | ||
$this->API_KEY = $api_key; | ||
} | ||
|
||
public function setAPISecret($api_secret = null){ | ||
$this->API_SECRET = $api_secret; | ||
} | ||
|
||
/** | ||
* Performs a GET request. | ||
* | ||
* @param string $endpoint | ||
* Endpoint to make GET request to. | ||
* | ||
* @param array $headers | ||
* An array of parameters to send in the request. | ||
* | ||
* @return data | ||
* The response data. | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function get($endpoint, $headers = array()){ | ||
return $this->request($endpoint, $headers); | ||
} | ||
|
||
/** | ||
* Performs a POST request. | ||
* | ||
* @param string $endpoint | ||
* Endpoint to make POST request to. | ||
* | ||
* @param array $headers | ||
* An array of parameters to send in the request. | ||
* | ||
* @param array $params | ||
* An array of parameters to send in the request. | ||
* | ||
* @return data | ||
* The response data. | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function post($endpoint, $headers = array(), $params = array()){ | ||
return $this->request($endpoint, $headers, $params, true); | ||
} | ||
|
||
/** | ||
* Performs a POST request. | ||
* | ||
* @param string $endpoint | ||
* Endpoint to make request to. | ||
* | ||
* @param array $headers | ||
* An array of parameters to send in the request. | ||
* | ||
* @param array $params | ||
* An array of parameters to send in the request. | ||
* | ||
* @param boolean $post | ||
* true to make a POST request, else a GET request will be made. | ||
* | ||
* @return stdClass | ||
* The JSON data returned from the API. | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function request($endpoint, $headers = array(), $params = array(), $post = false){ | ||
|
||
$ch = curl_init(); | ||
|
||
if($headers == null){ | ||
$headers = array(); | ||
} | ||
|
||
if($params == null){ | ||
$params = array(); | ||
} | ||
|
||
$headers = array_merge(self::$CURL_HEADERS, $headers); | ||
|
||
$headers[] = "X-Casper-API-Key: " . $this->API_KEY; | ||
$headers[] = "X-Casper-Signature: " . $this->generateRequestSignature($params, $this->API_SECRET); | ||
|
||
curl_setopt_array($ch, self::$CURL_OPTIONS); | ||
curl_setopt($ch, CURLOPT_URL, self::URL . $endpoint); | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | ||
|
||
//curl_setopt($ch, CURLOPT_PROXY, "http://localhost:8888"); | ||
|
||
if($post){ | ||
if(is_array($params)){ | ||
$params = http_build_query($params); | ||
} | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params); | ||
} | ||
|
||
$result = curl_exec($ch); | ||
|
||
//If cURL doesn't have a bundle of root certificates handy, | ||
//we provide ours (see http://curl.haxx.se/docs/sslcerts.html). | ||
if(curl_errno($ch) == 60){ | ||
curl_setopt($ch, CURLOPT_CAINFO, "../ca_bundle.crt"); | ||
$result = curl_exec($ch); | ||
} | ||
|
||
//If the cURL request fails, return FALSE. | ||
if($result === FALSE){ | ||
$error = curl_error($ch); | ||
curl_close($ch); | ||
throw new CasperException($error); | ||
} | ||
|
||
$json = json_decode($result); | ||
if($json == null){ | ||
curl_close($ch); | ||
throw new CasperException("Failed to decode response!"); | ||
} | ||
|
||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
if($code != 200){ | ||
|
||
curl_close($ch); | ||
|
||
if(isset($json->code) && isset($json->message)){ | ||
throw new CasperException("API Response: [{$json->code}] {$json->message}"); | ||
} else { | ||
throw new CasperException("API Response: [{$code}] Unknown Error Message"); | ||
} | ||
|
||
} | ||
|
||
curl_close($ch); | ||
|
||
return $json; | ||
|
||
} | ||
|
||
/** | ||
* Performs a POST request. | ||
* | ||
* @param string $url | ||
* Url to make request to. | ||
* | ||
* @param array $headers | ||
* An array of parameters to send in the request. | ||
* | ||
* @param array $params | ||
* An array of parameters to send in the request. | ||
* | ||
* @param boolean $post | ||
* true to make a POST request, else a GET request will be made. | ||
* | ||
* @return stdClass | ||
* The JSON data returned from the API. | ||
* | ||
* @throws CasperException | ||
* An exception is thrown if an error occurs. | ||
*/ | ||
public function externalRequest($url, $headers = array(), $params = array(), $post = false){ | ||
|
||
$ch = curl_init(); | ||
|
||
if($headers == null){ | ||
$headers = array(); | ||
} | ||
|
||
if($params == null){ | ||
$params = array(); | ||
} | ||
|
||
curl_setopt_array($ch, self::$CURL_OPTIONS); | ||
curl_setopt($ch, CURLOPT_URL, $url); | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | ||
|
||
if($post){ | ||
if(is_array($params)){ | ||
$params = http_build_query($params); | ||
} | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params); | ||
} | ||
|
||
$result = curl_exec($ch); | ||
|
||
//If cURL doesn't have a bundle of root certificates handy, | ||
//we provide ours (see http://curl.haxx.se/docs/sslcerts.html). | ||
if(curl_errno($ch) == 60){ | ||
curl_setopt($ch, CURLOPT_CAINFO, "../ca_bundle.crt"); | ||
$result = curl_exec($ch); | ||
} | ||
|
||
//If the cURL request fails, return FALSE. | ||
if($result === FALSE){ | ||
curl_close($ch); | ||
throw new CasperException("cURL request failed!"); | ||
} | ||
|
||
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200){ | ||
|
||
curl_close($ch); | ||
throw new CasperException("External Request Failed!"); | ||
|
||
} | ||
|
||
curl_close($ch); | ||
|
||
return $result; | ||
|
||
} | ||
|
||
|
||
/** | ||
* | ||
* Generates an HMAC Signature of the Request Parameters | ||
* Parameter Keys need to be in alphabetical order. | ||
* Values are then appended to the end. | ||
* | ||
* @param array $parameters Parameters sent in your Request | ||
* @param string $secret Your Casper API Secret | ||
* @return string | ||
*/ | ||
public function generateRequestSignature($parameters = array(), $secret){ | ||
|
||
ksort($parameters); | ||
|
||
$string = ""; | ||
foreach($parameters as $key => $value){ | ||
$string .= $key.$value; | ||
} | ||
return "v1:".hash_hmac("sha256", $string, $secret); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
/** | ||
* Created by IntelliJ IDEA. | ||
* User: liamcottle | ||
* Date: 22/09/15 | ||
* Time: 8:15 PM | ||
*/ | ||
class CasperException extends Exception { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters