I'm currently developing a REST API on my webserver for handling calls towards a Facebook application. This way I can check if the user has a valid license in our license database before allowing him/her to post to Facebook.
I'm using two separate calls at the moment, one to authorize the client with Facebook and store his/her access token in our license database. And another to actually publish to Facebook (and also other social platforms).
The Authorization seems to work. But the publishing always returns
{
"success": false,
"error": {
"message": "(#200) User must have accepted TOS",
"type": "FacebookRequestAppException",
"code": 200
}
}
I am currently working with a development app (on Facebook), without the proper permissions submitted, would this be the issue? And if so, how can I test it if I'm not allowed to use it?
The PHP code that triggers the Exception:
try {
$app = ( new FacebookRequest($app_session, 'POST', $post_url, array( 'appsecret_proof' => $appsecret_proof ) ) )->execute()->getGraphObject();
$output = array_merge( array( 'success' => true ), $output );
} catch(FacebookRequestException $e) {
$output = array_merge( $output, array( 'success' => false, 'error' => array( 'message' => $e->getMessage(), 'type'=> 'FacebookRequestAppException', 'code' => $e->getCode() ) ) );
}
Edit:
The call:
$app_id = '1503912413161954';
$app_secret = '<app_secret_censored>';
$user_access_token = (string)$this->getIdentity()->facebook_token;
$app_access_token = (string)$this->getIdentity()->facebook_app_token;
$license_id = (int)$this->getIdentity()->license_id;
$user_account_type = (string)$this->getIdentity()->user_account_type;
$redirect_url = 'http://api.example.com/authorize';
include 'lib/fb_authorize.php';
The authorization code - have in mind that it's not yet complete, and that I'm using Yii Framwork as well to add connectivity to our database:
<?php
$http_session = new CHttpSession;
$http_session->setTimeout(60);
$http_session->setSessionName('fb_session');
$http_session->open();
require( 'vendor/autoload.php' );
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\GraphUser;
use Facebook\FacebookHttpable;
use Facebook\FacebookCurl;
use Facebook\FacebookCurlHttpClient;
FacebookSession::setDefaultApplication($app_id, $app_secret);
$helper = new FacebookRedirectLoginHelper($redirect_url, $app_id, $app_secret);
if ( isset( $user_access_token ) ) {
$user_session = new FacebookSession( $user_access_token );
try {
if ( !$user_session->validate() ) {
$user_session = null;
}
} catch ( Exception $e ) {
$user_session = null;
$output = array_merge( $output, array( 'success' => false, 'error' => array( 'message' => $e->getMessage(), 'type'=> 'ExxicaUserSessionException', 'code' => $e->getCode() ) ) );
}
} else {
try {
$user_session = $helper->getSessionFromRedirect();
} catch( Exception $e ) {
$user_session = null;
$output = array_merge( $output, array( 'success' => false, 'error' => array( 'message' => $e->getMessage(), 'type'=> 'ExxicaUserSessionException', 'code' => $e->getCode() ) ) );
}
}
if( isset( $user_session ) ) {
$appsecret_proof= hash_hmac('sha256', $user_session->getToken(), $app_secret);
if( isset( $http_session['getpages'] ) ) {
try {
// Get Page ID
$user = ( new FacebookRequest($user_session, 'GET', '/me/accounts', array( 'appsecret_proof' => $appsecret_proof ) ) )->execute()->getGraphObject();
$output = array( 'success' => true, 'user' => $user );
} catch(FacebookRequestException $e) {
$output = array( 'success' => false, 'error' => array( 'message' => $e->getMessage(), 'type'=> 'FacebookRequestUserException', 'code' => $e->getCode() ) );
}
}
try {
$app_session = new FacebookSession( $app_access_token );
} catch ( Exception $e ) {
$app_session = null;
$output = array_merge( $output, array( 'success' => false, 'error' => array( 'message' => $e->getMessage(), 'type'=> 'ExxicaAppSessionException', 'code' => $e->getCode() ) ) );
}
$c = new CDbCriteria();
$c->compare( 'id', $license_id );
$l = _Licenses::model()->find( $c );
$l->facebook_token = $user_session->getToken();
$l->facebook_app_token = $app_session->getToken();
$l->save();
$output = array_merge( $output, array( 'success' => true, 'user_token' => $l->facebook_token ) );
} else {
header( 'Location: '.$helper->getLoginUrl( array( 'manage_pages','publish_actions','public_profile' ) ) );
}
?>
Related
Hi Stackoverflow community,
I am attempting to implement the "convertPaymentMethodToToken" method from USAePay soap api documentations. For the function to work, it is required to fetch the customer number from the UsaEpay acct, and it generates a Method ID through a "getCustomer" request, that will be used for the conversion. However, the implementation works only for a single customer and fails when I try to process multiple customers at once. The error message I receive is: "An error occurred while fetching details of customer 'customer1': 40030: Customer Not Found......".
I have a large customer database of over 20,000 customers, and my goal is to convert each of their payment methods to tokens efficiently, without having to perform individual conversions for each customer. The USAePay documentation only provides information on how to implement the feature for a single customer.
here is my code by getting Method ID for a single customer
<?php
$wsdl = "https://secure.usaepay.com/soap/gate/INBGTWZC/usaepay.wsdl";
$sourceKey = "your soruce key";
$pin = "1234";
function getClient($wsdl) {
return new SoapClient($wsdl, array(
'trace' => 1,
'exceptions' => 1,
'stream_context' => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
)
)
));
}
function getToken($sourceKey, $pin) {
$seed = time() . rand();
return array(
'SourceKey' => $sourceKey,
'PinHash' => array(
'Type' => 'sha1',
'Seed' => $seed,
'HashValue' => sha1($sourceKey . $seed . $pin)
),
'ClientIP' => $_SERVER['REMOTE_ADDR']
);
}
$client = getClient($wsdl);
$token = getToken($sourceKey, $pin);
try {
$custnum='customer number';
print_r($client->getCustomer($token,$custnum));
} catch (Exception $e) {
// Code to handle the exception
echo "An error occurred: " . $e->getMessage();
}
?>
and here the successful response I get back (with the Method ID included)
Successful response.
here Is the code I'm trying it to do with multiple customers
<?php
$wsdl = "https://sandbox.usaepay.com/soap/gate/43R1QPKU/usaepay.wsdl";
$sourceKey = "your api key";
$pin = "1234";
function getClient($wsdl) {
return new SoapClient($wsdl, array(
'trace' => 1,
'exceptions' => 1,
'stream_context' => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
)
)
));
}
function getToken($sourceKey, $pin) {
$seed = time() . rand();
return array(
'SourceKey' => $sourceKey,
'PinHash' => array(
'Type' => 'sha1',
'Seed' => $seed,
'HashValue' => sha1($sourceKey . $seed . $pin)
),
'ClientIP' => $_SERVER['REMOTE_ADDR']
);
}
$client = getClient($wsdl);
$token = getToken($sourceKey, $pin);
$custnums = array();
for ($i = 1; $i <= 3; $i++) {
$custnums[] = 'customer' . $i;
}
$methodIDs = array();
foreach ($custnums as $custnum) {
try {
$result = $client->getCustomer($token, $custnum);
$methodID = $result[0]->MethodID;
$methodIDs[] = $methodID;
error_log("Method ID for customer $custnum: $methodID");
} catch (Exception $e) {
echo " An error occurred: " . $e->getMessage();
}
}
?>
I've already been working on it all day,
Can anyone help me with this?
Thanks in advance
I'm rather new to Gravity Forms and building API's using PHP. I need to create a script that whenever a Gravity Form is completed the API sends this as JSON data to a POST URL. They gave me the security key name and value, how do I do this using PHP? Do I need Jquery and/or AJAX?
EDIT:
This is what I have so far but I have no idea if I'm on the right path: (I omitted some fields with "X's" due to obvious potential security reasons)
<?php
function calculate_signature( $string, $private_key ) {
$hash = hash_hmac( 'sha1', $string, $private_key, true );
$sig = rawurlencode( base64_encode( $hash ) );
return $sig;
}
//set API keys
$api_key = 'XXXXXXX';
$private_key = 'XXXXXXXXXX';
//set route
$route = '/XXXXXXX.php';
//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'POST', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'XXXXXXX.com' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;
// $form = array(
// array(
// 'title' => 'API Generated Form',
// 'description' => 'This is the description for the form generated by the API',
// 'labelPlacement' => 'top_label',
// 'button' => array(
// 'type' => 'text'
// ),
// 'confirmations' => array(
// array(
// 'id' => 0,
// 'name' => 'Default Confirmation',
// 'type' => 'message',
// 'message' => 'Thanks for contacting us! We will get in touch with you shortly.',
// 'isDefault' => true,
// ),
// ),
// 'fields' => array(
// array(
// 'id' => '1',
// 'label' => 'My Text',
// 'type' => 'text'
// )
// ),
// ),
// );
$form = array(
'age' => NULL
);
//json encode array
$form_json = json_encode( $form );
//retrieve data
$response = wp_remote_request( $url, array( 'method' => 'POST', 'body' => $form_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
//http request failed
die( 'There was an error attempting to access the API.' );
}
//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if( $body['status'] > 202 ){
$error = $body['response'];
//form insert failed, get error information
$error_code = $error['code'];
$error_message = $error['message'];
$error_data = isset( $error['data'] ) ? $error['data'] : '';
$status = "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
die( "Could not post forms. {$status}" );
}
$form_id = $body['response'][0];
echo 'The following form id was created: ' . $form_id . '</br>';
?>
The situation:
I build an authentication service that uses Basic Authentication to check if the user exists on an external database and fetches some data. The users in question only exist on the external database.
The problem:
Typo3 needs to have an user entry in the fe_user table to login the user.
So whenever this entry does not exist, the user cannot login.
What I want to do:
Create the user in the authentication service to avoid using a sql dump from the external database and ensure that synchronisation is possible.
The relevant code:
public function authUser(array $user) {
$a_user = $this->login['uname'];
$a_pwd = $this->login['uident_text'];
$url = 'https://soliday.fluchtpunkt.at/api/queryMediaItems';
$data = json_decode('{"language":"de-at"}');
$basicAuth = base64_encode("$a_user:$a_pwd");
// use key 'http' even if you send the request to https://...
$options = array (
'http' => array (
'header' => array(
"Content-Type: application/json",
"Accept: application/json",
"Authorization: Basic {$basicAuth}"
),
'method' => 'POST',
'content' => '{"language":"de-at"}'
)
);
$context = stream_context_create ( $options );
$result = file_get_contents ($url, false, $context);
$response = gzdecode($result);
$checkUser = $this->fetchUserRecord ( $this->login ['uname'] );
if (!is_array($checkUser)&& $result!== FALSE) {
$this->createUser();
}
// failure
if ($result === FALSE) {
return static::STATUS_AUTHENTICATION_FAILURE_BREAK;
}
$this->processData($response);
// success
return static::STATUS_AUTHENTICATION_SUCCESS_BREAK;
}
public function createUser() {
$username = $this->login ['uname'];
$password = $this->login ['uident_text'];
$record = $GLOBALS ['TYPO3_DB']->exec_SELECTgetSingleRow ( '*', 'fe_users', "username = '" . $username . "' AND disable = 0 AND deleted = 0" );
if (! $record) {
// user has no DB record (yet), create one using defaults registered in extension config
// password is not important, username is set to the user's input
$record = array (
'username' => $username,
'password' => $password,
'name' => '',
'email' => '',
'disable' => '0',
'deleted' => '0',
'pid' => $this->config ['storagePid'],
'usergroup' => $this->config ['addUsersToGroups'],
'tstamp' => time ()
);
if (t3lib_extMgm::isLoaded ( 'extbase' )) {
$record ['tx_extbase_type'] = $this->config ['recordType'];
}
$GLOBALS ['TYPO3_DB']->exec_INSERTquery ( 'fe_users', $record );
$uid = $GLOBALS ['TYPO3_DB']->sql_insert_id ();
$record = $GLOBALS ['TYPO3_DB']->exec_SELECTgetSingleRow ( '*', 'fe_users', 'uid = ' . intval ( $uid ) );
}
$_SESSION [$this->sessionKey] ['user'] ['fe'] = $record;
}
the ext_localconf.php file:
<?php
if (!defined('TYPO3_MODE')) {
die ('Access denied.');
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService(
$_EXTKEY,
'auth' /* sv type */,
'AuthService' /* sv key */,
array(
'title' => 'GET Authentication service',
'description' => 'Authenticates users with GET request.',
'subtype' => 'getUserFE, authUserFE',
'available' => true,
'priority' => 90,
'quality' => 90,
'os' => '',
'exec' => '',
'className' => Plaspack\professionalZoneLogin\Service\AuthService::class,
)
);
You should extend AuthenticationService with your own code, way of doing that is described here https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Xclasses/Index.html
Not sure if it's related, but t3lib_extMgm should be \TYPO3\CMS\Core\Utility\ExtensionManagementUtility unless you're using TYPO3 6.
You can also see if you get any SQL errors by calling $GLOBALS['TYPO3_DB']->sql_error().
I'm trying to transform my html page to Facebook Instant Articles format.
I keep getting on the screen
"DEBUG - =========================== DEBUG -"
When Im calling "$transformer->transformString" or "
$transformer->transform( $header, $document );"
Why that? I don't echo anything.
(This isn't wordpress site)
$header =
Header::create()
->withPublishTime(
Time::create( Time::PUBLISHED )->withDatetime(
\DateTime::createFromFormat(
'j-M-Y G:i:s',
date('j-M-Y G:i:s', strtotime($published_date))
))
)
->withModifyTime(
Time::create( Time::MODIFIED )->withDatetime(
\DateTime::createFromFormat(
'j-M-Y G:i:s',
date('j-M-Y G:i:s', strtotime($last_modified_date))
))
);
// Loads the rules configuration file
$rules_file_content = file_get_contents("rules-configuration.json", true);
// Load html content from a file.
//$content = file_get_contents("sample-html.html", true);
$content = get_the_content();
// Create a transformer object and load the rules
$transformer = new Transformer();
$transformer->loadRules($rules_file_content);
$document = new DOMDocument();
libxml_use_internal_errors(true);
$document->loadHTML( '<?xml encoding="' . $charset . '" ?><h1>' . $title . '</h1>' );
libxml_use_internal_errors(false);
$transformer->transform( $header, $document );
if($subtitle) {
$header->withSubTitle ($subtitle);
}
if ( $kicker ) {
$header->withKicker( $kicker );
}
define( 'IA_PLUGIN_VERSION', '4.0.5' );
$instant_article =
InstantArticle::create()
->withCanonicalUrl( $cannonical_link )
->withHeader( $header )
->addMetaProperty( 'op:generator:application', 'facebook-instant-articles' )
->addMetaProperty( 'op:generator:application:version', IA_PLUGIN_VERSION );
$instant_article->withStyle( 'default' );
$transformer->transformString( $instant_article, $content, $charset );
// Instantiate an API client
$client = Client::create(
$APP_ID,
$APP_SECRET,
$ACCESS_TOKEN,
$PAGE_ID,
$is_development
);
// Import the article
try {
$client->importArticle($instant_article, $is_published);
} catch (Exception $e) {
echo 'Could not import the article: '.$e->getMessage();
}
Add these lines :)
\Logger::configure(
[
'rootLogger' => [
'appenders' => ['facebook-instantarticles-traverser']
],
'appenders' => [
'facebook-instantarticles-traverser' => [
'class' => 'LoggerAppenderConsole',
'threshold' => 'INFO',
'layout' => [
'class' => 'LoggerLayoutSimple'
]
]
]
]);
Source: https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/examples/quiet_logger.php
Please i try to make REST API in Wordpress using the plugins WP OAuth Server and after create a new Client in Oauth server and generate a new access token, i could not connect by the Authorization in the header
function register_api_hooks2() {
register_rest_route(
'wp/v2/', '/beacon_products',
array(
'methods' => POST,
'callback' => 'beacon_products',
'args' => [
'id'
],
)
);
function beacon_products($request){
global $wpdb;
$current_user_id = get_current_user_id();
if ( empty( $current_user_id ) ) {
return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) );
}
$result = array();
/* filter_var($_POST['beacon_id'], FILTER_VALIDATE_INT)*/
if(isset($_POST['eid']) && !empty($_POST['eid']) && isset($_POST['uid']) && !empty($_POST['uid'])){
try {
/* code */
}else{
return new WP_Error( 'Beacon introuvable','Aucun beacon associé au ses paramétres', array( 'status' => 404 ) );
}
} catch (Exception $e) {
return new WP_Error( 'Une erreur s\'est produite','Une erreur au niveau de serveur', array( 'status' => 500 ) );
}
}else{
return new WP_Error( 'parametre manquant','eid ou bien uid introuvable', array( 'status' => 403 ) );
}
return $result;
}
}
Lots to do here. You really need to read the documentation
You should use the permissions callback in your initial function and current_user_can instead of get_current_user_id to determine whether or not to run the callback function.
You should return your callback output using return new WP_REST_Response( $result, 200 );