I have been trying for a while now and need to find a step by step from ground up on creating a consumer app for magento.
I have looked at the following:
And many others, but it's not clear what to do really. What i need to so is make a winform in C# that will need to use the rest api for magento with oAuth. Really here I'm a little lost.
Really the info i get to have as a consumer is
String callbackUrl = "liconnect://success";
String temporaryCredentialsRequestUrl = "http://domain.xxx/oauth/initiate?oauth_callback=" + HttpUtility.UrlEncode(callbackUrl);
String adminAuthorizationUrl = "http://domain.xxx/admin/oauth_authorize";
String accessTokenRequestUrl = "http://domain.xxx/oauth/token";
String apiUrl = "http://domain.xxx/api/rest";
String consumerKey = "KKKKKKKKKKKKKKK";
String consumerSecret = "SSSSSSSSSSSSSSSSSSS";
The "liconnect://success"; is to get to some where pass but I haven't gotten that far either lol...
The oauth_token and the oauth_token_secret need to be saved so I don't know if that can be stored from with in? but the deal is that you have to login too if you don't know the magento path .. I tried building a scraper with HtmlAgilityPack and got all the way to the login form but even thou i pass the form with everything that was on the page magento thinks there is an issue. I would guess do to the headers.. so going that route has not worked.
I also have tried to work to just do a post and use System.Security.Cryptography but that has not worked out as well.
The Question: Any mad programmer that would have a line on a solid "how to" or want to take the challenge to put one here for people? There are many out there asking the same question here.
UPDATE
Ok for anyone that can't seem to figure this out there is a way around. So I wrote a php script that does the authentication and stores this in a file that is hidden away. I then created a login that is what you get to with the C# winform. So.. a simple example but NOTE this is just an example as you should check the agent and salt the post data to increse securty here. The first time in you need to go directly to the php file so you get the files that keep the sessions.
The example:
<?php
/**
* Example of retrieving the products list using Admin account
* via Magento REST API. OAuth authorization is used
* Preconditions:
* 1. Install php oauth extension
* 2. If you were authorized as a Customer before this step, clear browser cookies for 'yourhost'
* 3. Create at least one product in Magento
* 4. Configure resource permissions for Admin REST user for retrieving all product data for Admin
* 5. Create a Consumer
**/
// $callbackUrl is a path to your file with OAuth authentication example for the Admin user
session_start();
//The user name and pass are md5 on the C# side of things and send over like this so it's more then just pass your username and pass
$u="461d544a174bcb5asf2a9fd14576251e169";
$p="c3762e47e025a2e0b6f77afca8da626a81";
if(isset($_POST['username']) && $p == $_POST['pass'] && $u == $_POST['username']){
$callbackUrl = "http://domain.xxx/quick_look.php";
$temporaryCredentialsRequestUrl = "http://domain.xxx/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = 'http://domain.xxx/admin/oauth_authorize';
$accessTokenRequestUrl = 'http://domain.xxx/oauth/token';
$apiUrl = 'http://domain.xxx/api/rest';
$consumerKey = 'nar78rw5nlkssddksdflklvkezgdria';
$consumerSecret = 'mo0lnht5;sdf;lsdgjcfdpgad5';
//sodoSess is a folder that is hidden and protected via .htaccess
// note.. secure it or else!!
function write_session($name,$value){
$myFile = "sodoSess/".$name.".txt";
$fh = fopen($myFile, 'w') or die("can't open file sodoSess/".$name.".txt");
fwrite($fh, $value);
fclose($fh);
}
function read_session($name){
$myFile = "sodoSess/".$name.".txt";
$fh = fopen($myFile, 'r') or die("can't open file sodoSess/".$name.".txt");
$data = fgets($fh);
fclose($fh);
return $data;
}
if (!isset($_GET['oauth_token']) && read_session('state') == 1) {
write_session('state',0);
}
try {
$authType = (read_session('state') == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && read_session('state')=="") {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
write_session('secret',$requestToken['oauth_token_secret']);
write_session('state',1);
header('Location: ' . $adminAuthorizationUrl . '?oauth_token=' . $requestToken['oauth_token']);
exit;
} else if (read_session('state') == 1) {
$oauthClient->setToken($_GET['oauth_token'], read_session('secret'));
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
write_session('state',2);
write_session('token',$accessToken['oauth_token']);
write_session('secret',$accessToken['oauth_token_secret']);
header('Location: ' . $callbackUrl);
exit;
} else {
$oauthClient->setToken(read_session('token'), read_session('secret'));
//print_r($_POST);
if(isset($_POST["addCustomer"])){
require_once ( "/var/www/html/app/Mage.php" );
umask(0);
Mage::app('default');
$customer = Mage::getModel('customer/customer');
//$customer = new Mage_Customer_Model_Customer();
$password = "321456321456";
$email = $_POST["email"];
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$street1 = $_POST["street1"];
$street2 = $_POST["street2"];
$city = $_POST["city"];
$postcode = $_POST["postcode"];
$telephone = $_POST["telephone"];
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->loadByEmail($email);
//Zend_Debug::dump($customer->debug()); exit;
if(!$customer->getId()) {
$customer->setEmail($email);
$customer->setFirstname($firstname);
$customer->setLastname($lastname);
$customer->setPassword($password);
}
try {
$customer->save();
$customer->setConfirmation(null);
$customer->save();
//Make a "login" of new customer
//Mage::getSingleton('customer/session')->loginById($customer->getId());
echo "added user";
}
catch (Exception $ex) {
//Zend_Debug::dump($ex->getMessage());
}
//Build billing and shipping address for customer, for checkout
$_custom_address = array (
'firstname' => $firstname,
'lastname' => $lastname,
'street' => array (
'0' => $street1,
'1' => $street2,
),
'city' => $city,
'region_id' => '',
'region' => '',
'postcode' => $postcode,
'country_id' => 'US',
'telephone' => $telephone,
);
$customAddress = Mage::getModel('customer/address');
//$customAddress = new Mage_Customer_Model_Address();
$customAddress->setData($_custom_address)
->setCustomerId($customer->getId())
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try {
$customAddress->save();
}
catch (Exception $ex) {
//Zend_Debug::dump($ex->getMessage());
}
Mage::getSingleton('checkout/session')
->getQuote()
->setBillingAddress(Mage::getSingleton('sales/quote_address')->importCustomerAddress($customAddress));
//echo $_POST["firstname"]." ".$_POST["lastname"]." <br/>-- ".$_POST["email"]." <br/>MADE IT!";
}else{
/* call class to handle everything */
//for now what is the stock level here?
$resourceUrl = "$apiUrl/products?filter[1][attribute]=sku&filter[1][in]=".$_POST['sku'];
if(isset($_GET['p_id']))$resourceUrl .="/".$_GET['p_id'];
$oauthClient->fetch($resourceUrl, array(), 'GET', array('Content-Type' => 'application/json'));
$productsList = json_decode($oauthClient->getLastResponse());
//print_r($productsList);
foreach($productsList as $item){
$resourceUrl = "$apiUrl/stockitems/".$item->entity_id;
$oauthClient->fetch($resourceUrl, array(), 'GET', array('Content-Type' => 'application/json'));
}
$item = json_decode($oauthClient->getLastResponse());
echo "<h1>currently there is</h1>".round($item->qty);
}
}
} catch (OAuthException $e) {
print_r($e->getMessage());
echo "<br/>";
print_r($e->lastResponse);
}
}else{
echo "fail";
}
?>
Now on the other side.. C# in the Form1.cs (where your event method are)
private void button5_Click(object sender, EventArgs e)
{
var myValue = Microsoft.VisualBasic.Interaction.InputBox("What is the sku of the itme you wish to find", "Look product", "");
if (myValue != "") {
sendPost("&sku=" + myValue);
}
}
public void sendPost(String postData) {
//step 1 talk with site
WebRequest req = WebRequest.Create("http://domain.xxx/quick_look.php");
string MainPostData = "username=YOURUSERNAME_MD5&pass=YOURPASSWORD_MD5";
byte[] send = Encoding.Default.GetBytes(MainPostData + (!String.IsNullOrWhiteSpace(postData) ? "&" + postData.TrimStart('&') : ""));
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = send.Length;
//this is where you salt the data by adjusting the header
//then testing for that adjustment
Stream sout = req.GetRequestStream();
sout.Write(send, 0, send.Length);
sout.Flush();
sout.Close();
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
string returnvalue = sr.ReadToEnd();
HtmlAgilityPack.HtmlDocument hDoc = new HtmlAgilityPack.HtmlDocument();
webBrowser1.Navigate("about:blank");
webBrowser1.Document.OpenNew(true);
webBrowser1.Document.Write("<html><body>" + returnvalue + "</body></html>");
webBrowser1.Stop();
}
And there you go. You can now connect to the magento api from a C# WinForms in a secure way that will take forever (if you add the salts and agent adjustments) to hack. I would still like a way to do it stright but.. this works.
code
in Winforms/C# ? The idea / concept should be the same. – Kesley