Page 1 of 2
Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 12:52 pm
by ninja2222
I would like to create a page for my clients to login and check for updates on their accounts. Then I would like to create a page where my employees can login and make updates, specifically new file uploads, to the clients accounts. I have seen similar sites everywhere, such as bank websites, USPS site, et cetera. What is
required to accomplish this? I'm trying to do this with the PHP, MySQL and Adobe CS3 Master collection's 'Dreamweaver CS3'
I thought it would be as easy as setting up a database with a table containing 'Id, username, password, customer-name, text, files'
then setting up a server behavior of 'login user' where 'username, password' are the authenticating fields and then setting up dynamic text fields Where the 'customer-name' is the heading
followed by html text 'Account Files' then the where 'text' is the body of the clients information then where 'files' is the customers
links to their updated files. Does this sound correct or possible and what are the steps I need to take?
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 2:14 pm
by alex.barylski
Honestly, you'd probably be better off hiring a developer. Could probably be done for a couple grand at most.
I'm not sure what it is your even trying to offer, but it sounds like for the time being you could just offer a RSS feed? Or does each client see information/news pertinent to them?
I'm not sure Login is something that can canned and reused. I'm not sure how Dreamweaver behaviors work either. The gist of the idea goes like this:
1. You create a DB table such as: pkid, username, password
2. You execute a function or code to accept the username/password details from a FORM and perform a lookup
Code: Select all
$res = mysql_query('SELECT pkid FROM users WHERE username = "'.$username.'" AND password = "'.$password.'"');
$row = mysql_fetch_row($res);
if($row['pkid'] !== 0){
echo 'You have logged in now redirect to admin panel';
}
The above is only authentication the tricky part is usually implementing the authorization (checking to ensure they are logged in and redirecting to login page if they are not).
The process can be more or less complex depending on your requirements.
Some alternatives:
1) Use .htaccess and separate folders for each client. The in each folder generate the news listings
2) Find an open source product which does something like what you want and use it.
Unfortunately I'm not aware of anything like this...although I can see how having a login section where you could create custom news sections for each client with downloads, etc might be handy.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 2:30 pm
by ninja2222
wonderful a response. I have the login and have protected an 'accounts page'
I need to create/understand how to build the Client Information Management System for the employees to be able to upload the files. Also I need to know how to show these uploaded files as links to the file. In answer to your question to whether I need this to show info pertinent to the customer, Yes, the files I want to show have to be user specific.
What I'm trying to provide to the user is a tracking system similar to other COURIERS
where the user can login and check on there accounts.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 2:55 pm
by alex.barylski
I have only ever used Dreamweaver once and that was many moons ago so I'm not really sure how it constructs PHP scripts.
File uploading is a pretty trivial process, but there are security implications.
1. If you upload to a directory inside the doc root files can be accessed naturally via a normall constructed URL. The problem with such as approach is that PHP typically runs as the same user as Apache and that means you need to likely have CHMOD 777 on a publically accessible directory. This can make it possible for attackers to gain write access to your directory, either uploading (HTTP PUT) PHP scripts to screw up your server or allowing them to delete (HTTP DELETE) files willy nilly. I would assume this functionality (if available in Apache) is disabled by default. However if Apache had a security hole, such as a buffer overflow, an attacker could possibly still gain access to your server files because they would effectively run custom code under the user Apache.
Storing files in a publically accessible directory also makes it trivial work for anyone to retrieve the file(s) via HTTP unless they are protected via .htaccess in which case you would need to implement a proxy script to access the files in the admin panel area otherwise your clients would need to enter the .htaccess user/pass each time they logged in (effectively having to login twice) whihc is a PITA.
2. Your second option is to store the files outside the document root and thus eliminate the issue of publically accessible files however they are still exploitable via a buffer overflow attack because they are still likely under the user Apache.
The second approach would also require a proxy script to fetch and retrieve files as they are not available publically via HTTP.
The last problem with the last approach, is that not all shared hosts allow you to upload files outside of the document root.
So your best bet is to implement a proxy script, which is easy:
download.php
Code: Select all
<?php
// TODO: Make sure whoever requested file is logged in and valid user
$file = $_GET['file'];
// TODO: Make sure the file is allowed to be access by this user
// TODO: Assign the client ID to separate client files
$cilentid = 1;
// TODO: You should probably set some headers so the browser knows how to handle the file download (PDF, XLS, etc)
echo file_get_contents("path/to/files/$clientid/$file");
Now in the admin panel area you would need to glob the files stored in the .htaccess protected areas which is also easy and you would generate a mirror of the directory.
showfiles.php
Code: Select all
<?php
// TODO: Determine who is logged in and use their clientid to locate files.
$arr = glob("path/to/files/$clientid/*");
foreach($arr as $file){
echo '<div><a href="'.$file.'">'.$file.'</a></div>';
}
Lastly you would need a .htaccess directive to redirect file requests for the storage directory of each client to the script I first showed, so something like this:
Code: Select all
RewriteRule ^([a-z0-9\-]+)\.pdf$ download.php?file=$1 [QSA]
NOTE: The above is likely invalid and all it does I think is say (if a PDF file is requested send the request to download.php)
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 3:09 pm
by Dynamis
That solution sounds difficult. If I were doing this, I would store everything in the database.
Database:
-----------------------------
Table1
- ID
- Username
- Password
- Customer Name
- Text
Table2
-----------------------------
So in this situation, when a user registers table1 is created, and they can edit text if you so please. When they want to upload a file, their ID along with the file data is saved to table2. So when you want to display links for all their files, you just search table2 for their id and display links to all the results.
For employees, they simply upload a file with the users id number that they want the file to go to.
Just another option, much easier in my opinion. Let me know if you want more details.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 3:35 pm
by ninja2222
But if the files are in a separate table than how do they relate/connect with the other table when the user logs in? Also, how do I upload the files to the the database. Then how do you make them links when showing them.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 4:03 pm
by Dynamis
So when the user logs in, you have to check if his password and username are correct. If so, you pull the id from table 1 based on his username:
My following code I am not checking, just so you get the idea, but it probably isn't syntactically correct:
check login and password:
Code: Select all
select * from table1 where username = "user_input" && password = "user_input"
Ok, so now the user is logged in, so get his ID number and save it somewhere
Code: Select all
select id from table1 where username = "username_that_logged_in_with"
Here is an update on what table2 should more likely look like in the DB
- ID
- file_name
- file_type
- file
So grab all the filenames for the logged in user based on his id
Code: Select all
select file_name from table2 where id = "logged_in_users_id_number"
So now to make the links
Code: Select all
For(all file_names)
{
<a href=displayPage.php?id=users_id&file_name=current_file_name>current_file_name</a>
}
where users_id is put there with php and same with current_file_name inside the <a> tags
Now to displaying the info. On displayPage.php you'll use $_GET to get the id number and filename then pull it from database
Code: Select all
select * from table2 where id=id_num && file_name = filename
Set the header to the file_type returned with the last select statement, and print the file to screen
Here is a good link on fileupload to review before continuing
http://www.tizag.com/phpT/fileupload.php
Finally, you can save the file data as a variable and write it to the database
Code: Select all
$var = $_FILES["file"]["tmp_name"];
insert into table2 (id,file) values (user_id_here, $var)
Hope this helps. There are many tutorials online if you google for them on pieces of this tutorial. If you want some exact code to help you out, let me know and I'll get back to you when possible with the actual code to do some of this stuff. Most of this is very basic though and you can find on google.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 4:05 pm
by alex.barylski
Using a database is another solution whihc many favour because of the inherent security improvements. Personally I dislike using a database for file storage because I like to be able to allow my clients to directly upload files to a directory via FTP or WebDAV if required...but...
The table relation is easy:
clients:
pkid, username, password
resources:
pkid, clientid, storage
Now when you select the files associated with the client you would use a simple query:
To list all files associated with client account:
Code: Select all
$clientid = $_SESSION['clientid'];
$sql = 'SELECT * FROM resources WHERE clientid = '.$clientid.'';
To download a single file:
Code: Select all
$pkid = $_GET['pkid'];
$clientid = $_SESSION['clientid'];
$sql = 'SELECT * FROM resources WHERE clientid = '.$clientid.' AND pkid = '.$pkid;
// TODO: Determine file type, set appropriate headers and send to browser
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 5:47 pm
by ninja2222
what would be the setting for the file table
such as
Id(varchar) Auto Increment ?
file_name(?)
file(?)
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 6:46 pm
by alex.barylski
I usually make primary key an INTEGER
Filename would be VARCHAR(128)
Filebuff would be BLOB
Although you don't really need to store the filename as you will index the file by it's PKID for faster indexing. You might want to store a title attribute or comments so you know what the file is all about.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 6:54 pm
by Dynamis
You will want to use
id int auto_increment,
file_name varchar(64), //could make this number smaller if you don't want such huge filenames
file mediumtext, //I have overrun blob's size many times. You could use mediumblob, but I prefer text
and since you want links, you will probably want to store the title. You will need 2 fields to specify which file you are talking about since there will be multiple files with the same id number.
(ex.
id=5 title = firstFile.doc
id=5 title = SecondFile.pdf)
So for the get you will need id=5&file_name=firstFile.doc, just as an example. You could use another field if you wanted, but filename is nice and small normally.
Re: Business client accounts pages for customer's files
Posted: Mon Jul 14, 2008 7:30 pm
by alex.barylski
file mediumtext, //I have overrun blob's size many times. You could use mediumblob, but I prefer text
MySQL: Documentation:
BLOB columns are treated as binary strings (byte strings). TEXT columns are treated as non-binary strings (character strings). BLOB columns have no character set, and sorting and comparison are based on the numeric values of the bytes in column values. TEXT columns have a character set, and values are sorted and compared based on the collation of the character set.
Binary data should be stored as binary IMHO.
EDIT | Also requiring the request to use a filename and ID is redundant. Just use the PKID it's faster, easier to implement more elegant solution.
When you select files from the resources table, use clientid to return only those files that belong to logged in client. When you select the file for download, pass in only the PKID of the resource and check to ensure it belongs to client A before setting headers and returning to the browser.
You need to set the file name and mime type using headers...
Re: Business client accounts pages for customer's files
Posted: Tue Jul 15, 2008 7:55 am
by Dynamis
Hockey wrote:
EDIT | Also requiring the request to use a filename and ID is redundant. Just use the PKID it's faster, easier to implement more elegant solution.
When you select files from the resources table, use clientid to return only those files that belong to logged in client. When you select the file for download, pass in only the PKID of the resource and check to ensure it belongs to client A before setting headers and returning to the browser.
You need to set the file name and mime type using headers...
I didn't really think it through, hockey is def. correct. This is the best route to take.
Re: Business client accounts pages for customer's files
Posted: Tue Jul 15, 2008 3:50 pm
by ninja2222
this is the user accounts page where the user is directed after they log in.
So how exactly would I show the file as a link. Would I save the file name to the
'clientid' field and/or what?
please help?
Code: Select all
<?php require_once('Connections/connex.php'); ?>
<?php
//initialize the session
session_start();
// ** Logout the current user. **
$logoutAction = $HTTP_SERVER_VARS['PHP_SELF']."?doLogout=true";
if ((isset($HTTP_SERVER_VARS['QUERY_STRING'])) && ($HTTP_SERVER_VARS['QUERY_STRING'] != "")){
$logoutAction .="&". $HTTP_SERVER_VARS['QUERY_STRING'];
}
if ((isset($HTTP_GET_VARS['doLogout'])) &&($HTTP_GET_VARS['doLogout']=="true")){
//to fully log out a visitor we need to clear the session varialbles
session_unregister('MM_Username');
session_unregister('MM_UserGroup');
$logoutGoTo = "adminlogin.php";
if ($logoutGoTo) {
header("Location: $logoutGoTo");
exit;
}
}
?>
<?php
if (!isset($_SESSION)) {
session_start();
}
$MM_authorizedUsers = "";
$MM_donotCheckaccess = "true";
// *** Restrict Access To Page: Grant or deny access to this page
function isAuthorized($strUsers, $strGroups, $UserName, $UserGroup) {
// For security, start by assuming the visitor is NOT authorized.
$isValid = False;
// When a visitor has logged into this site, the Session variable MM_Username set equal to their username.
// Therefore, we know that a user is NOT logged in if that Session variable is blank.
if (!empty($UserName)) {
// Besides being logged in, you may restrict access to only certain users based on an ID established when they login.
// Parse the strings into arrays.
$arrUsers = Explode(",", $strUsers);
$arrGroups = Explode(",", $strGroups);
if (in_array($UserName, $arrUsers)) {
$isValid = true;
}
// Or, you may restrict access to only certain users based on their username.
if (in_array($UserGroup, $arrGroups)) {
$isValid = true;
}
if (($strUsers == "") && true) {
$isValid = true;
}
}
return $isValid;
}
$MM_restrictGoTo = "adminlogin.php";
if (!((isset($_SESSION['MM_Username'])) && (isAuthorized("",$MM_authorizedUsers, $_SESSION['MM_Username'], $_SESSION['MM_UserGroup'])))) {
$MM_qsChar = "?";
$MM_referrer = $_SERVER['PHP_SELF'];
if (strpos($MM_restrictGoTo, "?")) $MM_qsChar = "&";
if (isset($QUERY_STRING) && strlen($QUERY_STRING) > 0)
$MM_referrer .= "?" . $QUERY_STRING;
$MM_restrictGoTo = $MM_restrictGoTo. $MM_qsChar . "accesscheck=" . urlencode($MM_referrer);
header("Location: ". $MM_restrictGoTo);
exit;
}
?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
switch ($theType) {
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}
$colname_username = "-1";
if (isset($_SESSION['MM_Username'])) {
$colname_username = $_SESSION['MM_Username'];
}
mysql_select_db($database_connex, $connex);
$query_username = sprintf("SELECT * FROM customerup WHERE username = %s", GetSQLValueString($colname_username, "text"));
$username = mysql_query($query_username, $connex) or die(mysql_error());
$row_username = mysql_fetch_assoc($username);
$totalRows_username = mysql_num_rows($username);
$colname_Recordset1 = "-1";
if (isset($_SESSION['pkid'])) {
$colname_Recordset1 = $_SESSION['pkid'];
}
mysql_select_db($database_connex, $connex);
$query_Recordset1 = sprintf("SELECT * FROM files WHERE pkid = %s", GetSQLValueString($colname_Recordset1, "int"));
$Recordset1 = mysql_query($query_Recordset1, $connex) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>A-LINE MESSENGER SERVICE UCLA ETA AND ROUTE TRACKING</title>
<script type="text/javascript">
function MM_CheckFlashVersion(reqVerStr,msg){
with(navigator){
var isIE = (appVersion.indexOf("MSIE") != -1 && userAgent.indexOf("Opera") == -1);
var isWin = (appVersion.toLowerCase().indexOf("win") != -1);
if (!isIE || !isWin){
var flashVer = -1;
if (plugins && plugins.length > 0){
var desc = plugins["Shockwave Flash"] ? plugins["Shockwave Flash"].description : "";
desc = plugins["Shockwave Flash 2.0"] ? plugins["Shockwave Flash 2.0"].description : desc;
if (desc == "") flashVer = -1;
else{
var descArr = desc.split(" ");
var tempArrMajor = descArr[2].split(".");
var verMajor = tempArrMajor[0];
var tempArrMinor = (descArr[3] != "") ? descArr[3].split("r") : descArr[4].split("r");
var verMinor = (tempArrMinor[1] > 0) ? tempArrMinor[1] : 0;
flashVer = parseFloat(verMajor + "." + verMinor);
}
}
// WebTV has Flash Player 4 or lower -- too low for video
else if (userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 4.0;
var verArr = reqVerStr.split(",");
var reqVer = parseFloat(verArr[0] + "." + verArr[2]);
if (flashVer < reqVer){
if (confirm(msg))
window.location = "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash";
}
}
}
}
</script>
<script src="Scripts/AC_RunActiveContent.js" type="text/javascript"></script>
<style type="text/css">
<!--
body,td,th {
font-family: Arial Black, Arial, sans-serif;
font-size: medium;
color: #FFFFFF;
}
body {
background-color: #000066;
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}
#container {
background-color: #000066;
width: 780px;
margin-right: auto;
margin-left: auto;
border: thin solid #333333;
}
.style1 {color: #FF0000}
#container #top {
font-family: "Arial Black", Arial, sans-serif;
font-size: larger;
font-style: oblique;
font-weight: bolder;
font-variant: small-caps;
color: #FF0000;
background-color: #FFFFFF;
border: thick solid #313031;
width: 770px;
}
a {
font-family: Arial Black, Arial, sans-serif;
font-size: medium;
color: #FFFF00;
}
#nav {
background-color: #333333;
text-align: center;
padding: 10px;
border: thin solid #000000;
}
#form1 table {
background-color: #313031;
border: thin solid #000000;
}
#nav ul {
margin: 0px;
padding: 0px;
}
#nav li {
list-style-type: none;
display: inline;
margin-right: 10px;
margin-left: 10px;
}
#nav a {
font-size: 90%;
text-decoration: none;
}
#nav a:hover {
color: #FF0000;
font-size: 90%;
text-decoration: none;
}
#container #footer {
height: auto;
background-color: #333333;
}
#lower_links ul {
margin: 0px;
padding: 0px;
}
#lower_links li {
list-style-type: none;
display: inline;
margin-right: 10px;
margin-left: 10px;
}
#lower_links a {
font-size: 90%;
text-decoration: none;
}
#lower_links a:hover {
color: #FF0000;
font-size: 90%;
text-decoration: none;
}
.style2 {
font-family: Georgia, "Times New Roman", Times, serif;
color: #FFFF00;
font-style: italic;
}
.style3 {
color: #FFFFFF;
font-style: italic;
}
.style12 {font-size: small}
#log-in { padding: 0px;
width: 229px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 20px;
float: right;
}
#logtable {
background-color: #313031;
border-right-width: thin;
border-bottom-width: thin;
border-left-width: thin;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-right-color: #000000;
border-bottom-color: #000000;
border-left-color: #000000;
}
.style13 {color: #FFFF00}
#customername {
font-family: Arial, Helvetica, sans-serif;
font-size: large;
color: #FF0000;
font-style: oblique;
text-decoration: underline;
}
#files {
font-family: Arial, Helvetica, sans-serif;
font-size: medium;
font-style: oblique;
font-weight: bold;
color: #FFFF00;
text-align: center;
}
-->
</style>
</head>
<div id="container">
<img src="images/ALM.gif" name="top" width="780" height="65" id="top" />
<div id="nav">
<ul>
<li><a href="/index.html">Home</a></li>
<li><a href="/about_us.html">About Us</a></li>
<li><a href="/delivery_services.html">Services</a></li>
<li><a href="/on_line_order.html">Place Order</a></li>
<li><a href="adminlogin.php">Tracking/Reports</a></li>
<li><a href="/contact_us.html">Contact Us</a></li>
<li><a href="/links.html">Links</a></li>
</ul>
</div>
<div align="center" id="log-in">
<div align="right">
<table width="228" border="0" cellpadding="0" id="logtable">
<tr>
<td height="68" colspan="2" bordercolor="#FFFFFF" id="form2"><span class="style12">
<label></label>
</span>
<span class="style12"></span>
<label> </label>
<div align="center">
<p><span class="style13">Logged In</span><br />
<a href="<?php echo $logoutAction ?>" class="style12">Log out</a></p>
</div></td>
</tr>
</table>
</div>
</div>
<div id="body">
<h2 align="right"><span class="style2">TRACKING & REPORTS<br />
<br />
</span></h2>
<?php if ($totalRows_username > 0) { // Show if recordset not empty ?>
<?php } // Show if recordset not empty ?>
<div id="customername">
<div align="center">
<h3><?php echo $row_username['menu_name']; ?></h3>
</div>
</div>
<h3 align="center"><br /><span class="style13"><em>CUSTOMER ACCOUNT FILES</em></span></h3>
<?php if ($totalRows_Recordset1 > 0) { // Show if recordset not empty ?>
<div id="files"><?php echo $row_Recordset1['clientid']; ?></div>
<?php } // Show if recordset not empty ?>
<p align="center"> </p>
</div>
</div>
<div id="footer"><div id="nav">
<ul>
<li><a href="/index.html">Home</a></li>
<li><a href="/about_us.html">About Us</a></li>
<li><a href="/delivery_services.html">Services</a></li>
<li><a href="/on_line_order.html">Place Order</a></li>
<li><a href="adminlogin.php">Tracking/Reports</a></li>
<li><a href="/contact_us.html">Contact Us</a></li>
<li><a href="/links.html">Links</a></li>
</ul>
</div>
<!--end of the footer div -->
</div>
<h4 align="center"><em><span class="style1">A-LINE MESSENGER SERVICE </span></em><span class="style3">- 2 - DELIVER - 4 - YOU</span><em>!</em></h4>
</div>
<!--this is the close of the container div--></body>
<?php
mysql_free_result($username);
mysql_free_result($Recordset1);
?>
Re: Business client accounts pages for customer's files
Posted: Wed Jul 16, 2008 9:33 pm
by jack_indigo
I hate to say this, but...
lol. Reads like, I'm a PHP newbie, please help me write an entire online banking system on this single thread. Just about.
The original author should either take some classes, or hire a developer. Any attempt to work out the complications could just end up having him expose his site to hacking by not understanding security stuff, and could be a real pain for him to fix problems rapidly that arise (embarassing himself in front of his clients), without some decent skills. That's what taking some courses on PHP can help with, or working with a book and several intranet apps (not exposed on the web) for a few years, or hiring and learning from a professional developer, can do.
I also think $2K are very low numbers. Is that USD pricing? If so, very low. Now $4K and up might be more like it. I mean, at $40 an hour USD, $2K only covers 50 hours -- a little over a week. I don't know anyone except in near-third-world countries who can tackle something that includes all discovery/documentation/functional spec writing, coding, testing time, tweaks, security fortifying, styling/CSS/XHTML/graphics, 30 day warranty -- in 50 hours. If they did, they'd be either one step from asking for handouts from the street, or just plain crazy or new or stupid.