How to set up download authentication? - authentication

I am looking for some sort of download authentication. I am going to give a user a link to a file, and I want to make sure only that person will get it only once. Is there a simple solution without setting up a database?
Even better: if it's possible to have an encrypted web link that will let you download a file from my FTP server just once, after that the link becomes invalid.

You can use simple php script. This script returing inputet in GET file on the brower.
After his excecution you can rename this file to random string.
this only first person download this file.
Your link get somethis like this. www.domain.tld/dir/script.php?file=./usr/123.tar.gz.
You can filename encrypt in base64 too, in this option your link is www.domain.tld/dir/script.php?file=Li91c3IvMTIzLnRhci5neg==
Script without base64:
<?php
$file = $_GET['file'];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
rename($file, "secret_new_filename");
exit;
}
else
{
echo 'File don\'t exist';
}
?>
And with base64:
<?php
$file = base64_decode($_GET['file']);
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
rename($file, "secret_new_filename");
exit;
}
else
{
echo 'File don\'t exist';
}
?>

Related

download a file from a prestashop module

I am trying to download a file from a prestashop module. For that I have this code. It finds the file (since i receive the mail with the message "el file existe") but doesn't download it.
$directorioActual = _PS_UPLOAD_DIR_;
$filename = $directorioActual."ejemploCsv.csv";
if (!file_exists($filename)) {
mail("luilli.guillan#gmail.com", "el file no existe", "failed");
} else {
mail("luilli.guillan#gmail.com", "el file si existe", "success");
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Content-Length: ' . filesize($filename));
readfile($filename);

How can I configure Apigility to send HMAC-Authorization response headers?

I'm implementing an authorization in Apigility using Hmac. Basically I'm using the classe of this fella both for client and server (https://github.com/reinaldoborges/rb-sphinx-hmac-zf2-client).
Now I have this piece of code before sending a GET to my Api.
$hmac = new HMAC(
new HMACv0(),
new PHPHash('sha256'),
new StaticKey('[PRE-SHARED KEY]'),
new DummyNonce()
);
$hmac->setKeyId('certkey');
$hmac->setNonceValue('certNonce');
$uri = "http://apicert.local/certificados";
$cliente = new HMACHttpClient($uri);
$cliente->setMethod('GET');
$cliente->setHmac($hmac);
try {
$cliente->send();
/**
* Resposta
*/
echo "Request HMAC Header:", PHP_EOL; **I'm asking for a Reply using HMAC-Authorization type of header **
echo ' ', HMACHttpClient::HEADER_NAME, ' = ', $cliente->getHeader(HMACHttpClient::HEADER_NAME), PHP_EOL, PHP_EOL;
} catch (Exception $e) {
/**
* ERRO
*/
echo "##### ERRO #####", PHP_EOL;
echo $e->getCode(), ' : ', $e->getMessage(), PHP_EOL;
echo "##### ERRO #####", PHP_EOL, PHP_EOL;
}
$response = $cliente->getResponse();
echo "Response Status Code: ", $response->getStatusCode(), PHP_EOL, PHP_EOL;
echo "Response Headers: ";
print_r($response->getHeaders()->toArray());
echo PHP_EOL;
echo "Response Cookies:", PHP_EOL;
$cookies = $response->getCookie();
foreach ($cookies as $cookie) {
echo ' ', $cookie->toString(), PHP_EOL;
}
echo PHP_EOL;
echo "Response Body:", PHP_EOL;
echo $response->getBody();
echo PHP_EOL, PHP_EOL;
And I'm receiving a 406 Status Code that refers that this kind of header is not acceptable. I tried to add in content negotion whitelist but there is not this option. How can I receive the authorization from the server then?
Request HMAC Header: HMAC-Authentication = 1:certkey:certNonce:f9c9edcda43df5c466e54449f31900a6f9387afa32168327a0873a69b023abef Response Status Code: 406 Response Headers: Array ( [Date] => Thu, 11 Aug 2016 23:55:33 GMT [Server] => Apache/2.4.7 (Ubuntu) [Access-Control-Max-Age] => 1000 [Access-Control-Allow-Headers] => X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding [Access-Control-Allow-Methods] => POST, GET, OPTIONS, DELETE, PUT [Access-Control-Allow-Origin] => * [Content-Length] => 149 [Connection] => close [Content-Type] => application/problem+json ) Response Cookies: Response Body: {"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Not Acceptable","status":406,"detail":"Cannot honor Accept type specified"}
You will have to create a new Authorization type.
In the APigility ui there is a button in the top named Authorization.
Here you can add any authorization adapter you want. Even the hmac adapter if you want.
Personally i have used this to create a jwt adapter.
Now, this adapter should extend ZF\MvcAuth\Authentication\AdapterInterface.
I've also added this adapter to my service manager.

how to send an HTML content via php mail()

I am trying to send an HTML e-mail using this code but all i am getting is FALSE from the mail() function.
The error_log is empty.
Can someone tell me why mail() is not working?
$message = '<html><body>';
$message .= '<table rules="all" style="border-color: #666;" cellpadding="10">';
$message .= "<tr style='background: #eee;'><td><strong>Name:</strong> </td><td>SDFSDF</td></tr>";
$message .= "<tr><td><strong>Email:</strong> </td><td>VXCVSDF</td></tr>";
$message .= "</table>";
$message .= "</body></html>";
$to = 'my_mail#gmail.com';
$subject = 'Website Change Reqest';
$headers = "From: USER NAME"."\r\n";
$headers .= "Reply-To: USER EMAIL"."\r\n";
$headers .= "MIME-Version: 1.0"."\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1"."\r\n";
if (mail($to, $subject, $message, $headers)) {
echo 'Your message has been sent.';
} else {
echo 'There was a problem sending the email.';
}
It's hard to debug PHP mail() function.
After checking your script, I can confirm that your code is working fine. It's something with your server or/and PHP configuration.
Start with this little snippet to see what is happening:
error_reporting(E_ALL);
ini_set('display_errors', -1);
echo '<br>I am : ' . `whoami`.'<br>';
$result = mail('myaddress#mydomain.com','This is the test','This is a test.');
echo '<hr>Result was: ' . ( $result === FALSE ? 'FALSE' : 'TRUE') . ' ('. $result. ')';
echo '<hr>';
echo phpinfo();
After output, check your sendmail_path, in most case sendmail_path uses sendmail MTA:
/usr/sbin/sendmail -t -i
Edit your php.ini file, set the following and don't forget to restart httpd server:
sendmail_path = /usr/sbin/sendmail -t -i
Check log files at /var/log/maillog, it could really help you to solve the problem.
If you still have a problem, just take a good look at PHPMailer, SwiftMailer, PEAR's Mail or Zend Framework's Zend_Mail an excellent, comprehensive, modern PHP mailing library. It will be easy to debug your problem after all.
You can using phpmailer for this way!
https://code.google.com/a/apache-extras.org/p/phpmailer/
Hope this help!

Using ini_set in PHP file

I just asked this question here regarding sending email from Windows server. Got the answer that the php.ini file has to be configured. After reading a little bit more, I found out about ini_set() function in PHP. So I tried to use it like that:
ini_set('SMTP', 'mail.mysite.com');
ini_set('smtp_port', 25);
ini_set('auth_username', 'me#mysite.com');
ini_set('auth_password', 'mypass');
ini_set('sendmail_from', 'me#mysite.com');
function send_contact_form($strName, $strEmail, $strPhone, $strMessage)
{
$to = 'mymail#mysite.com';
$subject = 'From the site';
$message = '<html lang="HE">
<head>
<title>
'.$subject.'
</title>
</head>
<body style="text-align:right; direction:rtl; font-family: Arial;">
Name: '.$strName.'<br>Email: '
.$strEmail.'<br>Phone: '.$strPhone
.'<br><br>Message: <br>'.$strMessage.'
</body>
</html>';
$email = $strEmail;
$header = 'MIME-Version: 1.0' . "\r\n";
$header .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$header .= "From: $email\r\nReply-To: $email" . "\r\n";
mail($to, $subject, $message, $header);
}
However, I still don't receive any email. What am I doing wrong? Why is it not working?

How to force a pdf download automatically?

Is there any way to force the user's download-manager to start a download for .PDF instead of showing the .PDF in a new window/tab?
use the download attribute inside your <a> tag
<a href="content/file.pdf" download > pdf link </a>
<a href="content/file.doc" download > doc link </a>
Set Content-Disposition in your HttpResponse header:
Content-Disposition = 'attachment; filename=filename.pdf'
This needs to be done in the server side. You can't do this at the client side.
How to do it depends on the server side language in question.
PHP:
header('Content-Disposition: attachment; filename="' . $filename . '"');
Java:
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
.NET:
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
If there's no means of any server side code which streams the PDF file, then you need to configure it at webserver level. In for example Apache HTTPD, you can place/expand a .htaccess file in the PDF folder's root with the following entry:
<Files *.pdf>
Header set Content-Disposition attachment
</Files>
or configure it globally in httpd.conf file. Similar approach exist for IIS with web.config file.
For IIS:
Put all files you want to force to download in their own folder.
Then in IIS go that folder and double click HTTP Response Headers.
Add a new header with the following info:
Name:
content-disposition
Value:
attachment
All files in that folder, when accessed, should prompt the save as dialog box for the appropriate browser.
You need to send HTTP headers ( Content-disposition ) in order to do this. You cannot do this on the client side.
.htaccess solution:
AddType application/octet-stream .pdf
<?php
header('Content-disposition: attachment; filename=filename.pdf');
header('Content-type: application/pdf');
readfile('path/to/filename.pdf');
Yes it can be done in JSP page... By giving a Download link in One JSP page on which goes to new script page...and download the PDF file as follows
DownloadPage.JSP code :-
<a href='downloadPdf.jsp?file=FILE.pdf' >Download PDF File</a>
downloadPdf.JSP code :-
<%# page import="java.util.*,java.io.*"%>
<%
File f = new File ("E:/PDFfiles/Downloads/" + request.getParameter("file") );
response.setContentType ("application/pdf");
response.setHeader ("Content-Disposition", "attachment; filename=""+request.getParameter("file")+""");
String name = f.getName().substring(f.getName().lastIndexOf("/") + 1,f.getName().length());
InputStream in = new FileInputStream(f);
ServletOutputStream outs = response.getOutputStream();
int bit = 256;
int i = 0;
try {
while ((bit) >= 0) {
bit = in.read();
outs.write(bit);
}
}
catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
outs.flush();
outs.close();
in.close();
%>
Source (this is my blog): http://bloggerplugnplay.blogspot.in/2012/05/how-to-create-force-download-link-for.html
<?php
// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
}
$reader = fopen($filename, "r");
$contents = fread($reader, filesize($filename));
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
ob_end_clean();
echo $contents;
From vb asp net code found on the internet i made this simple c# download.aspx page.
You can use with the file url passed as "f" querystring parameter. (/folder/download.aspx?f=/folder1/example.pdf).
<!DOCTYPE html>
<html>
<head><title></title>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
String strRequest = "";
try
{
strRequest = Request.QueryString["f"].ToString();
}
catch
{ }
if (strRequest.Length > 0)
{
String path = Server.MapPath(strRequest);
System.IO.FileInfo File = new System.IO.FileInfo(path);
if (File.Exists)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + File.Name);
Response.AddHeader("Content-Length", File.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(File.FullName);
Response.End();
};
}
}
</script>
</head>
<body></body>
</html>