I am trying to build a contact form in Joomla 2.5. After filling all the fields and by submitting the form I am getting an error like this:
The following from address failed: myname#gmail.com.
The e-mail I use is valid.
My SMTP settings are as follows:
Mail Settings
Mailer: SMTP Server
Mail from: myname#gmail.com
From Name: joomla
Sendmail Path: /usr/sbin/sendmail
SMTP Authentication: Yes
SMTP Security: SSL
SMTP Port: 465
SMTP Username: myname#gmail.com
SMTP Password: ******
SMTP Host: smtp.gmail.com
This the code for sending email
<?php
/**
* #package Joomla.Site
* #subpackage com_mailto
* #copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* #license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* #package Joomla.Site
* #subpackage com_mailto
*/
class MailtoController extends JControllerLegacy
{
/**
* Show the form so that the user can send the link to someone
*
* #access public
* #since 1.5*/
function mailto()
{
$session = JFactory::getSession();
$session->set('com_mailto.formtime', time());
JRequest::setVar('view', 'mailto');
$this->display();
}
/**
* Send the message and display a notice
*
* #access public
* #since 1.5
*/
function send()
{
// Check for request forgeries
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$app = JFactory::getApplication();
$session = JFactory::getSession();
$db = JFactory::getDbo();
$timeout = $session->get('com_mailto.formtime', 0);
if ($timeout == 0 || time() - $timeout < 20) {
JError::raiseNotice(500, JText:: _ ('COM_MAILTO_EMAIL_NOT_SENT'));
return $this->mailto();
}
$SiteName = $app->getCfg('sitename');
$MailFrom = $app->getCfg('mailfrom');
$FromName = $app->getCfg('fromname');
$link = MailtoHelper::validateHash(JRequest::getCMD('link', '', 'post'));
// Verify that this is a local link
if (!$link || !JURI::isInternal($link)) {
//Non-local url...
JError::raiseNotice(500, JText:: _ ('COM_MAILTO_EMAIL_NOT_SENT'));
return $this->mailto();
}
// An array of email headers we do not want to allow as input
$headers = array ( 'Content-Type:',
'MIME-Version:',
'Content-Transfer-Encoding:',
'bcc:',
'cc:');
// An array of the input fields to scan for injected headers
$fields = array(
'mailto',
'sender',
'from',
'subject',
);
/*
* Here is the meat and potatoes of the header injection test. We
* iterate over the array of form input and check for header strings.
* If we find one, send an unauthorized header and die.
*/
foreach ($fields as $field)
{
foreach ($headers as $header)
{
if (strpos($_POST[$field], $header) !== false)
{
JError::raiseError(403, '');
}
}
}
/*
* Free up memory
*/
unset ($headers, $fields);
$email = JRequest::getString('mailto', '', 'post');
$sender = JRequest::getString('sender', '', 'post');
$from = JRequest::getString('from', '', 'post');
$subject_default = JText::sprintf('COM_MAILTO_SENT_BY', $sender);
$subject = JRequest::getString('subject', $subject_default, 'post');
// Check for a valid to address
$error = false;
if (! $email || ! JMailHelper::isEmailAddress($email))
{
$error = JText::sprintf('COM_MAILTO_EMAIL_INVALID', $email);
JError::raiseWarning(0, $error);
}
// Check for a valid from address
if (! $from || ! JMailHelper::isEmailAddress($from))
{
$error = JText::sprintf('COM_MAILTO_EMAIL_INVALID', $from);
JError::raiseWarning(0, $error);
}
if ($error)
{
return $this->mailto();
}
// Build the message to send
$msg = JText :: _('COM_MAILTO_EMAIL_MSG');
$body = sprintf($msg, $SiteName, $sender, $from, $link);
// Clean the email data
$subject = JMailHelper::cleanSubject($subject);
$body = JMailHelper::cleanBody($body);
$sender = JMailHelper::cleanAddress($sender);
// Send the email
if (JFactory::getMailer()->sendMail($from, $sender, $email, $subject, $body) !== true)
{
JError::raiseNotice(500, JText:: _ ('COM_MAILTO_EMAIL_NOT_SENT'));
return $this->mailto();
}
JRequest::setVar('view', 'sent');
$this->display();
}
}
Just check by changing mailer in global configuration at administration page
On Linux (SELINUX) apply:
setsebool -P httpd_can_network_connect=1
setsebool -P httpd_can_sendmail=1
reboot
On Windows:
In the php.ini
Un-comment
;extension=php_openssl.dll
Related
I want to reward users on signing up to my app by giving them gift card balance in their amazon account and to do that i have used Load Amazon Balance api which is similar to Amazon Incentive api.
Amazon requires a digitally signed authorization payload in order to access the api. I've compared my code to amazon's process of digitally signing using aws secret key and aws access key. But its still giving me
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
I'm attaching the code of my class in the post. Can anyone help me out by looking at the code and telling if there is any mistake in the process i'm performing for sending information to the api. Thanks.
<?php
/**
* Created by PhpStorm.
*
* Date: 07-09-2018
* Time: 01:18 PM
*/
namespace App;
use App\AppConstant\AppConstant;
use App\Entities\Models\User;
use Illuminate\Support\Facades\Auth;
class AmazonReward
{
/**
* This is the bulk of the logic for making AGCOD calls.
*/
//Constants
public static $apikey;
public static $clientId = env("client_id");
public static $clientSecret = env("client_secret");
public static $awsSecretKey = env("client_secret");
public static $partnerId = env("partner_id");
public static $SERVICE_NAME = "AGCODService";
public static $ACCEPT_HEADER = "accept";
public static $CONTENT_HEADER = "content-type";
public static $HOST_HEADER = "host";
public static $XAMZDATE_HEADER = "x-amz-date";
public static $XAMZTARGET_HEADER = "x-amz-target";
public static $AUTHORIZATION_HEADER = "Authorization";
public static $AWS_SHA256_ALGORITHM = "AWS4-HMAC-SHA256";
public static $KEY_QUALIFIER = "AWS4";
public static $TERMINATION_STRING = "aws4_request";
const SERVICE_NAME = "AGCODService";
const ACCEPT_HEADER = "accept";
const CONTENT_HEADER = "content-type";
const HOST_HEADER = "host";
const XAMZDATE_HEADER = "x-amz-date";
const XAMZTARGET_HEADER = "x-amz-target";
const AUTHORIZATION_HEADER = "Authorization";
const AWS_SHA256_ALGORITHM = "AWS4-HMAC-SHA256";
const KEY_QUALIFIER = "AWS4";
const TERMINATION_STRING = "aws4_request";
const ENDPOINT ='agcod-v2.amazon.com';
// const ENDPOINT ='agcod-v2-gamma.amazon.com';
public static function get_paypload_giftcard($partnerId, $gcRequestId, $currencyCode, $gcAmount, $customer_id)
{
$amount = trim($gcAmount);
$payload = array(
"loadBalanceRequestId" => $gcRequestId,
"partnerId" => $partnerId,
"amount" =>
array(
"currencyCode" => $currencyCode,
"value" => floatval($amount)
),
"account" =>
array(
"id" => $customer_id,
"type" => "2"
),
"timestamp" => time(),
// "transactionSource" => [
// "sourceId" => ""
// ],
"externalReference" => "",
"notificationDetails" => [
"notificationMessage" => ""
]
);
return json_encode($payload);
}
/**
* Builds the "formal" request that can be hashed to verify the contents of the request.
* The request does not get sent to the server in this format, but the hash of this is.
*
* #return The formal request
*/
public static function buildCanonicalRequest($serviceOperation, $payloadHash, $customer_id) {
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$HOST_HEADER = self::HOST_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$dateTimeString = Self::getTimeStamp();
$header1 = Self::header1($serviceOperation);
$canonicalRequest = "POST\n/$serviceOperation HTTP/1.1\n\n$header1\n\n$ACCEPT_HEADER;$HOST_HEADER;$XAMZDATE_HEADER;$XAMZTARGET_HEADER\n$payloadHash";
return $canonicalRequest;
}
/**
* Returns part of the header used in the canonical request.
*
* #return the portion of the header.
*/
public static function header1($serviceOperation) {
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$HOST_HEADER = Self::HOST_HEADER;
$dateTimeString = Self::getTimeStamp();
$endpoint = self::ENDPOINT;
$contentType = Self::getContentType();
return
"$ACCEPT_HEADER:$contentType\n$HOST_HEADER:$endpoint\n$XAMZDATE_HEADER:$dateTimeString\n$XAMZTARGET_HEADER:com.amazonaws.agcod.AGCODService.$serviceOperation";
}
public static function disburseFunds($customer_id){
$apiString = "https://" . Self::ENDPOINT . "/LoadAmazonBalance";
$ch = curl_init();
$xAmzDateTime = gmdate('Ymd\THis\Z');
$xAmzDate = substr($xAmzDateTime, 0, 8);
$xAmzTarget = "com.amazonaws.agcod.AGCODService.LoadAmazonBalance";
$region = "us-east-1";
$serviceOperation = "LoadAmazonBalance";
// $canonicalRequestHash = Self::myHash($canonicalRequest);
$payload = Self::get_paypload_giftcard( Self::$partnerId, Self::$partnerId . time(), "USD", 5.00, $customer_id);
$payloadHash = Self::myHash($payload);
$canonicalRequest = Self::buildCanonicalRequest($serviceOperation, $payloadHash , $customer_id);
$dateTimeString = Self::getTimeStamp();
$curl_response = Self::invokeRequest($payload, $xAmzDateTime,$canonicalRequest, $serviceOperation);
echo "<pre>";
print_r($curl_response);
exit;
$json = json_decode($curl_response);
if ( isset($json->message) || ! isset($json->cardInfo) )
{
echo "<pre>";
print_r($json);
exit;
$ret = array();
$ret['success']=false;
$ret['errorCode'] = time();
return $ret;
}
$ret = array();
$ret['success']=true;
$ret['gcValue']= $json->cardInfo->value->amount;
$ret["gcCode"]= $json->gcClaimCode;
$ret["gcResponseId"]= $json->gcId; ////done
$ret["gcRequestId"]=$json->creationRequestId;
echo "<pre>";
print_r($ret);
exit;
return $ret;
// echo "<pre>";
// print_r($canonicalRequestHash);
// exit;
// // $canonicalRequestHash = myHash($canonicalRequest);
// // $stringToSign = buildStringToSign($canonicalRequestHash);
// echo "<pre>";
// print_r($this->buildAuthSignature($stringToSign));
// exit;
// $authotization = "AWS4-HMAC-SHA256 Credential=AKIAIGHKAVYIDBOH3O3A/" . $xAmzTarget . "/" . $region . "/AGCODService/aws4_request,SignedHeaders=accept;host;x-amz-date;x-amz-target, Signature=ec86661c1d39f74b5891666505bb7656b172b0d060d911bee3b6a1c29ae17657";
// /*$post = http_build_query([
// ["Authorization" => "DEMO1"],
// ["x-amz-date" => $xAmzDate],
// ["x-amz-target" => $xAmzTarget],
// ["Accept" => "application/json"],
// ["Host" => "agcod-v2-gamma.amazon.com"]
// ]);*/
// // $post = [];
// $post = [];
// $post["loadBalanceRequestId"] = "Amazon123456";
// $post["partnerId"] = "";
// $post["amount"] = [];
// $post["amount"]["currencyCode"] = "";
// $post["amount"]["value"] = "";
// $post["account"] = [];
// $post["account"]["id"] = "F2044";
// $post["account"]["type"] = "0";
// $post["transactionSource"] = [];
// $post["transactionSource"]["sourceId"] = "";
// $post["externalReference"] = "";
// $post["notificationDetails"] = [];
// $post["notificationDetails"]["notificationMessage"] = "";
// $customHeaders = [
// "Authorization" => "Amazon",
// "x-amz-date" => $xAmzDateTime,
// "x-amz-target" => $xAmzTarget,
// "Accept" => "application/json",
// "Host" => "agcod-v2-gamma.amazon.com"
// ];
// curl_setopt($ch, CURLOPT_URL, $apiString);
// curl_setopt($ch, CURLOPT_POST, 1);
// curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
// curl_setopt($ch, CURLOPT_HTTPHEADER, $customHeaders);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// $server_output = curl_exec($ch);
// curl_close ($ch);
// // Further processing ...
// if ($server_output == "OK") {
// }else{
// }
}
/**
* Builds the authenication string used to prove that the request is allowed and made by the right party.
*
* #param $stringToSign The string to sign.
* #return The authenication signature.
*/
public static function buildAuthSignature($dateString, $stringToSign) {
$AWS_SHA256_ALGORITHM = Self::AWS_SHA256_ALGORITHM;
$SERVICE_NAME = Self::SERVICE_NAME;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$ACCEPT_HEADER = Self::ACCEPT_HEADER;
$HOST_HEADER = Self::HOST_HEADER;
$XAMZDATE_HEADER = Self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = Self::XAMZTARGET_HEADER;
$awsKeyId = Self::$clientId;
$regionName= Self::getRegion();
$derivedKey = Self::buildDerivedKey(Self::getDateString($dateString));
$derivedKey_lower = Self::buildDerivedKey(Self::getDateString($dateString), false);
$dateString = Self::getDateString($dateString);
// Calculate signature per http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
$finalSignature = Self::hmac($stringToSign, $derivedKey, false);
// Assemble Authorization Header with signing information
// per http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
$authorizationValue =
$AWS_SHA256_ALGORITHM
. " Credential=" . $awsKeyId
. "/" . $dateString . "/" . $regionName . "/" . $SERVICE_NAME . "/" . $TERMINATION_STRING . ","
. " SignedHeaders="
. $ACCEPT_HEADER . ";" . $HOST_HEADER . ";" . $XAMZDATE_HEADER . ";" . $XAMZTARGET_HEADER . ","
. " Signature="
. $finalSignature;
return $authorizationValue;
}
/**
* Hashes the string using sha256, the standard AWS hash.
*
* #param $data a string to sign
* #return a string hash of $data
*/
public static function myHash($data) {
return hash("sha256",$data);
}
/**
* Builds the string that gets hashed and used in the authenication.
*
* #param $canonicalRequestHash The hash of the canonicalRequest
* #return The string to sign.
*/
public static function buildStringToSign($canonicalRequestHash){
$AWS_SHA256_ALGORITHM = Self::AWS_SHA256_ALGORITHM;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$SERVICE_NAME = Self::SERVICE_NAME;
$awsSecretKey = Self::$awsSecretKey;
$regionName = Self::getRegion();
$dateTimeString = Self::getTimeStamp();
$dateString = Self::getDateString($dateTimeString);
$stringToSign = "$AWS_SHA256_ALGORITHM\n$dateTimeString\n$dateString/$regionName/$SERVICE_NAME/$TERMINATION_STRING\n$canonicalRequestHash";
return $stringToSign;
}
/**
* Gets the time stamp used to make the request. If not set by the client it is set to the current time on the first call to this function.
*
* #return The time stamp
*/
public static function getTimeStamp() {
global $timeStamp;
if(!isset($timeStamp)) {
//GMT time. Format is YYYYMMDDTHHmmssZ where T and Z are literals, YYYY is 4 digit year, MM is 2 digit month, DD is 2 digit day, HH is 2 digit hour (24 hour clock) mm is 2 digit minute, ss is 2 digit second.
$timeStamp = gmdate('Ymd\THis\Z');
}
return $timeStamp;
}
/**
* Get the format that we will make the request in. This tells the server how to parse the request.
* This value is retrieved from the client and can either be json or xml.
*
* #return The request format as to be passed to the AGCOD server.
*/
public static function getContentType() {
return "application/json"; //Request in JSON format
}
/**
* Makes the service call to the AGCOD server.
*
* #return The repsonse from the server (in XML or JSON format) with HTML character escaped.
*/
public static function invokeRequest($payload, $dateTimeString,$canonicalRequest, $serviceOperation) {
$KEY_QUALIFIER = self::KEY_QUALIFIER;
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$CONTENT_HEADER = self::CONTENT_HEADER;
$HOST_HEADER = self::HOST_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$AUTHORIZATION_HEADER = self::AUTHORIZATION_HEADER;
$canonicalRequestHash = Self::myHash($canonicalRequest);
$stringToSign = Self::buildStringToSign($canonicalRequestHash);
$authorizationValue = Self::buildAuthSignature($dateTimeString, $stringToSign);
$endpoint = Self::ENDPOINT;
$regionName = Self::getRegion();
$SERVICE_NAME = "AGCODService";
$serviceTarget = "com.amazonaws.agcod." . $SERVICE_NAME . "." . $serviceOperation;
$contentType = Self::getContentType();
$url = "https://" . Self::ENDPOINT . "/" . $serviceOperation;
// print_r($url);
// exit;
//Prepare to send the data to the server
$handle = curl_init($url);
//Yes, do POST not GET
curl_setopt($handle, CURLOPT_POST, true);
//This is header, not post fields
curl_setopt($handle, CURLOPT_HTTPHEADER , array(
"Content-Type:$contentType",
'Content-Length: ' . strlen($payload),
$AUTHORIZATION_HEADER. ":" . $authorizationValue,
$XAMZDATE_HEADER . ":" . $dateTimeString,
$XAMZTARGET_HEADER . ":" . $serviceTarget,
"host:" . Self::ENDPOINT,
$ACCEPT_HEADER . ":" . $contentType
));
curl_setopt($handle, CURLOPT_POSTFIELDS, $payload);
//Yes, don't print the result to the web page, just give it to us in a string.
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
//Do the request
$result = curl_exec($handle);
if (empty($result)) {
// some kind of an error happened
die(curl_error($handle));
curl_close($handle); // close cURL handler
}
//Free the resource
curl_close($handle);
$signaturePos = strpos($authorizationValue, "Signature=");
if($signaturePos == FALSE || $signaturePos + 10 >= strlen($authorizationValue)) {
$signatureStr = "Malformed";
}
else {
$signatureStr = substr($authorizationValue, $signaturePos + 10);
}
print_r($result);
exit;
return $result;
}
/**
* Gets the region based on the server we connect too.
*
* #return The region.
*/
public static function getRegion() {
$endpoint = Self::ENDPOINT;
$regionName = "us-east-1";
if ($endpoint == "agcod-v2-eu.amazon.com" || $endpoint == "agcod-v2-eu-gamma.amazon.com") {
$regionName = "eu-west-1";
}
else if ($endpoint == "agcod-v2-fe.amazon.com" || $endpoint == "agcod-v2-fe-gamma.amazon.com") {
$regionName = "us-west-2";
}
return $regionName;
}
/**
* Performs a hmac hash using sha256, which is what AWS uses.
*
* #param $data The data to sign.
* #param $key The key to sign the data with.
* #param $raw true to provide a raw ascii string, false to use a hex string.
* #return the hash of $data
*/
public static function hmac($data, $key, $raw = true) {
return hash_hmac("sha256", $data, $key, $raw);
}
/**
* Gets the date for the request, which is either what the client passed in, or today if none was given.
*
* #return The date in YYYYMMDD format.
*/
public static function getDateString($dateTimeString) {
// $dateTimeString = Self::getTimeStamp();
return substr($dateTimeString, 0, 8);
}
/**
* Builds the derived key, which is used for authorizating the request.
*
* #param $rawOutput true to return an ascii string using raw byes, false to return a hex string
*/
public static function buildDerivedKey($dateString, $rawOutput = true) {
$KEY_QUALIFIER = Self::KEY_QUALIFIER;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$SERVICE_NAME= Self::SERVICE_NAME;
// Get pasted AWS Secret Key from user input
$awsSecretKey = Self::$awsSecretKey;
// Append Key Qaulifier, "AWS4", to secret key per http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html
$signatureAWSKey = $KEY_QUALIFIER . $awsSecretKey;
$regionName = Self::getRegion();
// $dateString = Self::getDateString();
$kDate = Self::hmac($dateString, $signatureAWSKey);
$kRegion = Self::hmac($regionName, $kDate);
$kService = Self::hmac($SERVICE_NAME, $kRegion);
// Derived the Signing key (derivedKey aka kSigning)
$derivedKey = Self::hmac($TERMINATION_STRING, $kService, $rawOutput);
return $derivedKey;
}
}
Everything else works fine except for the location. The actual city/state does not come across. Instead the word Array is displayed. My field type in the database is text but I've tried every field type through mysql. The HTML file is JSON where it comes to the field names. I am very new at this so any help is appreciated.
This is my php file:
<? ob_start(); ?>
<?php
define('FACEBOOK_APP_ID', '');
define('FACEBOOK_SECRET', '');
// No need to change function body
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
if ($_REQUEST) {
$response = parse_signed_request($_REQUEST['signed_request'],
FACEBOOK_SECRET);
/*
echo "<pre>";
print_r($response);
echo "</pre>"; // Uncomment this for printing the response Array
*/
$name = $response["registration"]["name"];
$email = $response["registration"]["email"];
$gender = $response["registration"]["gender"];
$prosecutor = $response["registration"]["prosecutor"];
$location = $response["registration"]["location"];
// Connecting to Database
$con = mysql_connect("my_hosting_site","Database","password");
if (!$response)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("Database", $con);
mysql_query("INSERT INTO my_table (name, email, gender, prosecutor, location)
VALUES ('$name', '$email', '$gender', '$prosecutor', '$location')");
mysql_close($con);
}
$URL="https://www.facebook.com";
header ("Location: $URL");
?>
<? ob_flush(); ?>
Facebook
Basically, it's an array.
[location] => Array
(
[name] => Delhi, India
[id] => 1.1604xxxxxx286E+14
)
Use this for getting location stored in your db, like I have written below:
$location = $response["registration"]["location"]["name"];
I'm currently dealing with Symfony2's Security component.
I try to authenticate users against a webservice. To authenticate a user, I have to provide to the webservice a username and a password.
I know that I've got to create a class that implements UserProvider. But the loadUserByUsername function doesn't fit my webservice needs : in order to authenticate a user, it ask for both username and password whereas the UserProvider's function only requires username.
Here is a similar question to the problem I face : Symfony2 authentication without UserProvider
I've been struggling on this problem for a couple of days...
I fixed this problem in that way:
services.yml:
services:
user_provider:
class: "%my_class%"
arguments: ["#service_container"]
WebServiceUserProvider.php
/**
* #param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->apiClient = $container->get('api_client');
$this->request = $container->get('request');
}
and use $password = $this->request->get('password'); in your loadUserByUsername method
One way of accomplishing this would be to load the user by the username and then validate the password. If the a user exists for the given username and the password entered matches with the password of that user, then authenticate the user.
Example:
public function userLogin($username, $password)
{
$em = $this->getEntityManager();
$query = $em->createQuery('SELECT u FROM VenomCoreBundle:User u WHERE u.username = :username OR u.email = :username AND u.isDeleted <> 1 ')
->setParameter('username', $username);
try {
$entity = $query->getSingleResult();
if (count($entity) > 0) {
$encoder = new MessageDigestPasswordEncoder('sha512', true, 10);
$passwordEnc = $encoder->encodePassword($password, $entity->getSalt());
$userPassword = $entity->getPassword();
if ($passwordEnc == $userPassword) {
$tokenValue = $entity->getUserToken();
$profile = $entity->getUserProfile();
if(!$profile) {
return false;
}
$userName = $profile->getFullName();
$response = array(
'token' => $tokenValue,
'username' => $userName
);
} else {
return false;
}
}
} catch (\Doctrine\Orm\NoResultException $e) {
return false;
}
return $response;
}
i would write a test for Symfony2 with FOSUserBundle.
At the moment i tried some ways and no one works.
I need a function like "createAuthClient".
Here is my basic class.
I post it because you could understand my problem better.
<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\BrowserKit\Cookie;
class WebTestMain extends WebTestCase
{
protected static $container;
static protected function createClient(array $options = array(), array $server = array())
{
$client = parent::createClient($options, $server);
self::$container = self::$kernel->getContainer();
return $client;
}
static function createAuthClient(array $options = array(), array $server = array())
{
// see lines below with my tries
}
}
First try:
if(static::$kernel === null)
{
static::$kernel = static::createKernel($options);
static::$kernel->boot();
}
if(static::$container === null)
{
self::$container = self::$kernel->getContainer();
}
$parameters = self::$container->getParameter('test');
$server = array_merge(array('HTTP_HOST' => $parameters['host'], 'HTTP_USER_AGENT' => $parameters['useragent']), $server);
$client = self::createClient($options, $server);
$userProvider = self::$container->get('fos_user.user_manager');
$user = $userProvider->findUserBy(array('id' => 1));
$client->getCookieJar()->set(new Cookie('MOCKSESSID', true));
$session = self::$kernel->getContainer()->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$client->getContainer()->get('security.context')->setToken($token);
$session->set('_security_main', serialize($token));
return $client;
Then i searched and searched...
My second try.
if(static::$kernel === null)
{
static::$kernel = static::createKernel($options);
static::$kernel->boot();
}
if(static::$container === null)
{
self::$container = self::$kernel->getContainer();
}
$parameters = self::$container->getParameter('test');
$server = array_merge(
array(
'HTTP_HOST' => $parameters['host'],
'HTTP_USER_AGENT' => $parameters['useragent'],
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'admin'
),
$server
);
$client = static::createClient(array(), array());
$client->followRedirects();
return $client;
And here is my last try before i post this question...
$client = self::createClient($options, $server);
$parameters = self::$container->getParameter('test');
$server = array_merge(
array(
'HTTP_HOST' => $parameters['host'],
'HTTP_USER_AGENT' => $parameters['useragent']
),
$server
);
$client->setServerParameters($server);
$usermanager = self::$container->get('fos_user.user_manager');
$testuser = $usermanager->createUser();
$testuser->setUsername('test');
$testuser->setEmail('test#mail.org');
$testuser->setPlainPassword('test');
$usermanager->updateUser($testuser);
return $client;
Thank you in Advance.
The best way I have found to test with an authenticated user is to just visit your login page and submit the form with user name and password you have loaded from a fixture. This may seem slow and cumbersome but will test what the user will actually do. You can even create your own method to make using it quick and easy.
public function doLogin($username, $password) {
$crawler = $this->client->request('GET', '/login');
$form = $crawler->selectButton('_submit')->form(array(
'_username' => $username,
'_password' => $password,
));
$this->client->submit($form);
$this->assertTrue($this->client->getResponse()->isRedirect());
$crawler = $this->client->followRedirect();
}
Create an AbstractControllerTest and create an authorized client on setUp() as follow:
<?php
// ...
use Symfony\Component\BrowserKit\Cookie;
abstract class AbstractControllerTest extends WebTestCase
{
/**
* #var Client
*/
protected $client = null;
public function setUp()
{
$this->client = $this->createAuthorizedClient();
}
/**
* #return Client
*/
protected function createAuthorizedClient()
{
$client = static::createClient();
$container = $client->getContainer();
$session = $container->get('session');
/** #var $userManager \FOS\UserBundle\Doctrine\UserManager */
$userManager = $container->get('fos_user.user_manager');
/** #var $loginManager \FOS\UserBundle\Security\LoginManager */
$loginManager = $container->get('fos_user.security.login_manager');
$firewallName = $container->getParameter('fos_user.firewall_name');
$user = $userManager->findUserBy(array('username' => 'REPLACE_WITH_YOUR_TEST_USERNAME'));
$loginManager->loginUser($firewallName, $user);
// save the login token into the session and put it in a cookie
$container->get('session')->set('_security_' . $firewallName,
serialize($container->get('security.context')->getToken()));
$container->get('session')->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
return $client;
}
}
NOTE: Please, replace the username with your test username.
Then, extends the AbstractControllerTest and use the global $client to make requests as follow:
class ControllerTest extends AbstractControllerTest
{
public function testIndexAction()
{
$crawler = $this->client->request('GET', '/admin/');
$this->assertEquals(
Response::HTTP_OK,
$this->client->getResponse()->getStatusCode()
);
}
}
This method tested and works fine
I'm using Codeigniter 1.7. Does anyone have any experience of creating web services with PHP, particularly within the CodeIgniter framework? What are security measures need to consider while implementing web services? How to provide authentication with API keys?
Any Ideas?
It depends on the kind of web service you are inquiring about. Is the web service going to be a daemon for example? or a typical online web service. For either of these you must implement a RESTful type. RESTful meaning a stateless connection. This is where API keys are used; to identity a user for example.
Luckily Codeigniter is one with many libraries and extensions. An example of such libraries can be here: https://github.com/philsturgeon/codeigniter-restserver
Now for security concerns: API keys would replace sessions or any state. You would have to make full checks on the api. Many sites that implement APIs offer different solutions to the same end result.
Authentication with API keys are simple. You would check it against a storage type(database).
Here is a tutorial using codeigniter and the library linked previously: http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/
This might be somewhat vague, but since you dont have any specific problems or apparent needs its hard to be specific.
EDIT:
In that case it would be better implementing a RESTful interface so that your iphone app can also use all of the user functionalities that your service provides. The best way would be to make everything accessible in one way. Meaning not having different controllers / models for the iphone connections and web connections.
So for example you could have the following controller:
<?php
class Auth extends CI_Controller{
public function login(){
//Check if their accessing using a RESTful interface;
$restful = $this->rest->check();
if($restful){
//Check for the API keys;
$apiKey = $this->input->get('apiKey');
$secretKey = $this->input->get('secretKey');
//If you have any rules apon the keys you may check it (i.e. their lengths,
//character restrictions, etc...)
if(strlen($apiKey) == 10 and strlen($secretKey) == 14)
{
//Now check against the database if the keys are acceptable;
$this->db->where('apiKey', $apiKey);
$this->db->where('secretKey', $secretKey);
$this->db->limit(1);
$query = $this->db->get('keys');
if($this->db->count_all_results() == 1)
{
//It's accepted the keys now authenticate the user;
foreach ($query->result() as $row)
{
$user_id = $row->user_id;
//Now generate a response key;
$response_key = $this->somemodel->response_key($user_id);
//Now return the response key;
die(json_encode( array(
'response_key' => $response_key,
'user_id' => $user_id
)
)
);
} //End of Foreach
}//End of Result Count
}//End of length / character check;
} else {
//Perform your usual session login here...;
}
}
}
?>
Now this is just a small example for performing these types of requests. This could apply to any type of controller. Though there are a few options here. You could make every request pass the apikey, and the secret each time and verify it at each request. Or you could have some sort of whitelist that once you have been verified the first time each request after that would be whitelisted, and or black listed on the opposite.
Hope this helps,
Daniel
<?php
//First Create Api file in controller name Api.php
/*
api call in postman
login :
email , password
http://localhost/demo/api/login
https://prnt.sc/pbs2do
register (user): :
fullname , email , password , recipeunit
http://localhost/demo/api/signup
https://prnt.sc/pbs3cc
profile and list (user profile and all user ) :
View Profile : email, if all then pass blank
http://localhost/demo/api/userlist
change password :
http://localhost/demo/api/change_password
email ,password ,newpassword , conformnewpassword (if needed)
https://prnt.sc/pbs3rt
*/
if(!defined('BASEPATH')) exit('No direct script access allowed');
require APPPATH . '/libraries/BaseController.php'; // this file will download first and pest in library
class Api extends BaseController
{
/**
* This is default constructor of the class
*/
public function __construct()
{
parent::__construct();
$this->load->model('api/signup_model','signup_model');
}
/**
* Index Page for this controller.
*/
public function index()
{
}
public function signup()
{
$this->signup_model->signup();
}
public function login()
{
$this->signup_model->login();
}
public function userlist()
{
$this->signup_model->userlist();
}
public function edit_user()
{
$this->signup_model->edit_user();
}
public function change_password()
{
$this->signup_model->change_password();
}
public function testpass()
{
$this->signup_model->testpass();
}
}
// then create model in model folder create api folder create signup_model.php file
//after that
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Signup_model extends CI_Model {
public function __construct()
{
parent::__construct();
$this->load->database(); /* load database library */
}
// User register (signin) process
public function signup($data = array())
{
// another db field update like dt_createddate
if(!array_key_exists('dt_createddate', $data)){
$data['dt_createddate'] = date("Y-m-d H:i:s");
}
if(!array_key_exists('dt_updateddate', $data)){
$data['dt_updateddate'] = date("Y-m-d H:i:s");
}
if(!array_key_exists('dt_updateddate', $data)){
$data['dt_updateddate'] = date("Y-m-d H:i:s");
}
$data['var_fullname'] = $this->input->post('fullname');
$data['var_email'] = $this->input->post('email');
$data['var_password'] =getHashedPassword($this->input->post('password')) ;
$data['int_recipeunit'] = $this->input->post('recipeunit');
// if(!empty($data['var_fullname']) && !empty($data['var_email']) && !empty($data['var_password']) ){ }
/* check emailid all ready exist or not */
$email_check=$this->input->post('email');
$this->db->select('var_email');
$this->db->from('tbl_user');
$this->db->where('var_email', $email_check);
$query = $this->db->get();
$user = $query->result();
if(!empty($user))
{
echo "{\"status\" : \"404\",\"message\" : \"Email all ready register\",\"data\":".str_replace("<p>","",'{}'). "}";
}
else
{
$insert = $this->db->insert('tbl_user', $data);
if($insert){
$this->db->select('var_email as email,var_fullname as fullname,dt_createddate as createdate');
$insert_id = $this->db->insert_id();
$query = $this->db->get_where('tbl_user', array('int_id' => $insert_id));
echo "{\"status\" : \"200\",\"message\" : \"User added sucessfully\",\"data\":".str_replace("<p>","",json_encode($query->row_array())). "}";
// return $this->db->insert_id();
}else
{
$message="Something Wrong";
echo "{\"status\" : \"400\",\"data\":".str_replace("<p>","",json_encode($message)). "}";
// return false;
}
}
}
/* Login user $email, $password*/
function login()
{
$email=$this->input->post('email');
$password=$this->input->post('password');
$this->db->select('int_id,var_email,var_password');
$this->db->from('tbl_user');
$this->db->where('var_email', $email);
$this->db->where('chr_status', 'A');
$query = $this->db->get();
$user = $query->result();
if(!empty($user))
{
if(verifyHashedPassword($password, $user[0]->var_password))
{
$this->db->select('var_email as email,var_fullname as fullname,dt_createddate as createdate');
$query = $this->db->get_where('tbl_user', array('var_email' => $email));
echo "{\"status\" : \"200\",\"message\" : \"Login sucessfully\",\"data\":".str_replace("<p>","",json_encode($query->row_array())). "}";
}
else
{
echo "{\"status\" : \"404\",\"message\" : \"Password does not match\",\"data\":".str_replace("<p>","",'{}'). "}";
}
}
else
{
echo "{\"status\" : \"404\",\"message\" : \"Invalid email \",\"data\":".str_replace("<p>","",'{}'). "}";
}
}
/* Fetch user data all or single */
function userlist()
{
$email=$this->input->post('email'); // post id of which user data you will get
if(!empty($email))
{
$email=$this->input->post('email');
$password=$this->input->post('password');
$this->db->select('int_id,var_email,var_password');
$this->db->from('tbl_user');
$this->db->where('var_email', $email);
$this->db->where('chr_status', 'A');
$query = $this->db->get();
$user = $query->result();
if(!empty($user))
{
$this->db->select('var_email as email,var_fullname as fullname,dt_createddate as createdate');
$query = $this->db->get_where('tbl_user', array('var_email' => $email));
$responce_json=json_encode($query->row_array());
echo "{\"status\" : \"200\",\"message\" : \"User data\",\"data\":".str_replace("<p>","",$responce_json). "}";
}
else
{
echo "{\"status\" : \"404\",\"message\" : \"Invalid email \",\"data\":".str_replace("<p>","",'{}'). "}";
}
}
else
{
$this->db->select('var_email as email,var_fullname as fullname,dt_createddate as createdate');
$query = $this->db->get('tbl_user');
$responce_json=json_encode($query->result_array());
echo "{\"status\" : \"200\",\"message\" : \"User data\",\"data\":".str_replace("<p>","",$responce_json). "}";
}
}
/* Update user data */
function edit_user($data = array()) {
$id = $this->input->post('id');
$data['first_name'] = $this->input->post('first_name');
/* $data['last_name'] = $this->input->post('last_name');
$data['email'] = $this->input->post('email');
$data['phone'] = $this->input->post('phone'); */
if(!empty($data) && !empty($id)){
if(!array_key_exists('modified', $data)){
$data['modified'] = date("Y-m-d H:i:s");
}
$update = $this->db->update('users', $data, array('id'=>$id));
if($update){
$message="User Update Sucessfully";
$responce_json=json_encode($message);
echo "{\"status\" : \"200\",\"data\":".str_replace("<p>","",$responce_json). "}";
}
}
else
{
return false;
}
}
/* change password */
function change_password()
{
$email=$this->input->post('email');
$password=$this->input->post('password');
$newpassword=$this->input->post('newpassword');
//$conformnewpassword=$this->input->post('conformnewpassword');
$this->db->select('int_id,var_email,var_password');
$this->db->from('tbl_user');
$this->db->where('var_email', $email);
$this->db->where('chr_status', 'A');
$query = $this->db->get();
$user = $query->result();
if(!empty($user))
{
if(verifyHashedPassword($password, $user[0]->var_password))
{
//if($newpassword==$conformnewpassword)
//{
$data['var_password'] = getHashedPassword($newpassword);
$update = $this->db->update('tbl_user', $data, array('var_email'=>$email));
$this->db->select('var_email as email,var_fullname as fullname,dt_createddate as createdate');
$query = $this->db->get_where('tbl_user', array('var_email' => $email));
echo "{\"status\" : \"200\",\"message\" : \"Password change sucessfully\",\"data\":".str_replace("<p>","",json_encode($query->row_array())). "}";
/* }
else
{
echo "{\"status\" : \"404\",\"message\" : \"New pass and conform pass does not match \",\"data\":".str_replace("<p>","",'{}'). "}";
} */
}
else
{
echo "{\"status\" : \"404\",\"message\" : \"Invalid old password \",\"data\":".str_replace("<p>","",'{}'). "}";
}
}
else
{
echo "{\"status\" : \"404\",\"message\" : \"Invalid email \",\"data\":".str_replace("<p>","",'{}'). "}";
}
}
/*
* Delete user data
*/
/* public function delete($id){
$delete = $this->db->delete('users',array('id'=>$id));
return $delete?true:false;
} */
}
?>