forum.coppermine-gallery.net

No Support => Feature requests => Topic started by: Raisingdad on January 15, 2005, 09:55:13 pm

Title: Limit Viewing
Post by: Raisingdad on January 15, 2005, 09:55:13 pm
My Feature Request:

Allowing admin to limit User Groups Viewing of Pictures (or anybody), by setting a Time Frame Flood Limit.

IE. View 30 pictures in 1 Hour, to stop Bots, and to stop Abusive Users from running up Bandwdith.
Title: Re: Limit Viewing
Post by: andy_cul on May 10, 2005, 05:26:27 pm
Is this possible? Because this is what my website needs.
Title: Re: Limit Viewing
Post by: autobahn on May 10, 2005, 10:26:41 pm
the problem is your users could always just directly hotlink to the pictures on the server. you can disable that but it disables it for everyone.
Title: Re: Limit Viewing
Post by: Joachim Müller on May 11, 2005, 10:01:45 am
what you're requesting is currently not possible, and I doubt that such a feature will be implemented in the core code of future coppermine versions. Of course everybody is welcome to post a hack instead.
Title: Re: Limit Viewing
Post by: Loki66 on May 23, 2005, 12:32:37 pm
I dont' agree, there are various ways to limit bandwith abuse (hotlinking, ....). Here is a summary taken from WinHTTrack :

Hope that somebody will implement this with Coppermine because this is a key feature for CPG to become "professional" ...


Bandwidth abuse:

Many Webmasters are concerned about bandwidth abuse, even if this problem is caused by a minority of people. Offline browsers tools, like HTTrack, can be used in a WRONG way, and therefore are sometimes considered as a potential danger.
But before thinking that all offline browsers are BAD, consider this: students, teachers, IT consultants, websurfers and many people who like your website, may want to copy parts of it, for their work, their studies, to teach or demonstrate to people during class school or shows. They might do that because they are connected through expensive modem connection, or because they would like to consult pages while travelling, or archive sites that may be removed one day, make some data mining, comiling information ("if only I could find this website I saw one day..").
There are many good reasons to mirror websites, and this helps many good people.
As a webmaster, you might be interested to use such tools, too: test broken links, move a website to another location, control which external links are put on your website for legal/content control, test the webserver response and performances, index it..

Anyway, bandwidth abuse can be a problem. If your site is regularly "clobbered" by evil downloaders, you have
various solutions. You have radical solutions, and intermediate solutions. I strongly recomment not to use
radical solutions, because of the previous remarks (good people often mirror websites).

In general, for all solutions,
the good thing: it will limit the bandwidth abuse
the bad thing: depending on the solution, it will be either a small constraint, or a fatal nuisance (you'll get 0 visitors)
or, to be extreme: if you unplug the wire, there will be no bandwidth abuse


Inform people, explain why ("please do not clobber the bandwidth")
Good: Will work with good people. Many good people just don't KNOW that they can slow down a network.
Bad: Will **only** work with good people
How to do: Obvious - place a note, a warning, an article, a draw, a poeme or whatever you want


Use "robots.txt" file
Good: Easy to setup
Bad: Easy to override
How to do: Create a robots.txt file on top dir, with proper parameters
Example:
    User-agent: *

    Disallow: /bigfolder


Ban registered offline-browsers User-agents
Good: Easy to setup
Bad: Radical, and easy to override
How to do: Filter the "User-agent" HTTP header field


Limit the bandwidth per IP (or by folders)
Good: Efficient
Bad: Multiple users behind proxies will be slow down, not really easy to setup
How to do: Depends on webserver. Might be done with low-level IP rules (QoS)


Priorize small files, against large files
Good: Efficient if large files are the cause of abuse
Bad: Not always efficient
How to do: Depends on the webserver


Ban abuser IPs
Good: Immediate solution
Bad: Annoying to do, useless for dynamic IPs, and not very user friendly
How to do: Either ban IP's on the firewall, or on the webserver (see ACLs)


Limit abusers IPs
Good: Intermediate and immediate solution
Bad: Annoying to do, useless for dynamic IPs, and annoying to maintain..
How to do: Use routine QoS (fair queuing), or webserver options


Use technical tricks (like javascript) to hide URLs
Good: Efficient
Bad: The most efficient tricks will also cause your website to he heavy, and not user-friendly (and therefore less attractive, even for surfing users). Remember: clients or visitors might want to consult offline your website. Advanced users will also be still able to note the URLs and catch them. Will not work on non-javascript browsers. It will not work if the user clicks 50 times and put downloads in background with a standard browser
How to do: Most offline browsers (I would say all, but let's say most) are unable to "understand" javascript/java properly. Reason: very tricky to handle!
Example:
You can replace:
    <a href="bigfile.zip">Foo</a>
by:
    <script language="javascript">
    <!--
    document.write('<a h' + 're' + 'f="');
    document.write('bigfile' + '.' + 'zip">');
    // -->
    </script>
    Foo
    </a>

You can also use java-based applets. I would say that it is the "best of the horrors". A big, fat, slow, bogus java applet. Avoid!


Use technical tricks to lag offline browsers
Good: Efficient
Bad: Can be avoided by advanced users, annoying to maintain, AND potentially worst that the illness (cgi's are often taking some CPU usage). . It will not work if the user clicks 50 times and put downloads in background with a standard browser
How to do: Create fake empty links that point to cgi's, with long delays
Example: Use things like <ahref="slow.cgi?p=12786549"><nothing></a> (example in php:)
    <?php
    for($i=0;$i<10;$i++) {
        sleep(6);
        echo " ";
    }
    ?>


Use technical tricks to temporarily ban IPs
Good: Efficient
Bad: Radical (your site will only be available online for all users), not easy to setup
How to to: Create fake links with "killing" targets
Example: Use things like <a href="killme.cgi"><nothing></a> (again an example in php:)

<?php
   // Add IP.
   add_temp_firewall_rule($REMOTE_ADDR,"30s");
?>
function add_temp_firewall_rule($addr) {
   // The chain chhttp is flushed in a cron job to avoid ipchains overflow
    system("/usr/bin/sudo -u root /sbin/ipchains -I 1 chhttp -p tcp -s ".$addr." --dport 80 -j REJECT");
    syslog("user rejected due to too many copy attemps : ".$addr);
}







Copyright issues

You do not want people to "steal" your website, or even copy parts of it. First, stealing a website does not
require to have an offline browser. Second, direct (and credited) copy is sometimes better than disguised
plagiarism. Besides, several previous remarks are also interesting here: the more protected your website will be,
the potentially less attractive it will also be. There is no perfect solution, too. A webmaster asked me one day
to give him a solution to prevent any website copy. Not only for offline browsers, but also against "save as",
cut and paste, print.. and print screen. I replied that is was not possible, especially for the print screen - and
that another potential threat was the evil photographer. Maybe with a "this document will self-destruct in 5 seconds.."
or by shooting users after consulting the document.
More seriously, once a document is being placed on a website, there will always be the risks of copy (or plagiarism)

To limit the risk, previous a- and h- solutions, in "bandwidth abuse" section, can be used



Privacy

Might be related to section 2.
But the greatest risk is maybe email grabbers.


A solution can be to use javascript to hide emails.
Good: Efficient
Bad: Non-javascript browsers will not have the "clickable" link
How to do: Use javascript to build mailto: links
Example:
    <script language="javascript">
    <!--
    function FOS(host,nom,info) {
      var s;
      if (info == "") info=nom+"@"+host;
      s="mail";
      document.write("<a href='"+s+"to:"+nom+"@"+host+"'>"+info+"</a>");
    }
    FOS('mycompany.com','smith?subject=Hi, John','Click here to email me!')
    // -->
    </script>
    <noscript>
    smith at mycompany dot com
    </noscript>


Another one is to create images of emails
Good: Efficient, does not require javascript
Bad: There is still the problem of the link (mailto:), images are bigger than text, and it can cause problems for blind people (a good solution is use an ALT attribute with the email written like "smith at mycompany dot com")
How to do: Not so obvious of you do not want to create images by yourself
Example: (php, Unix)
<?php
/*
Email contact displayer
Usage: email.php3?id=<4 bytes of user's md5>
The <4 bytes of user's md5> can be calculated using the 2nd script (see below)
Example: http://yourhost/email.php3?id=91ff1a48
*/
$domain="mycompany.com";
$size=12;

/* Find the user in the system database */
if (!$id)
  exit;
unset($email);
unset($name);
unset($pwd);
unset($apwd);
$email="";
$name="";
$fp=@fopen("/etc/passwd","r");
if ($fp) {
  $pwd=@fread($fp,filesize("/etc/passwd"));
  @fclose($fp);
}
$apwd=split("\n",$pwd);
foreach($apwd as $line) {
  $fld=split(":",$line);
  if (substr(md5($fld[0]),0,8) == $id) {
    $email=$fld[0]."@".$domain;
    $nm=substr($fld[4],0,strpos($fld[4],","));
    $name=$email;
    if ($nm)
      $name="\"".$nm."\" <".$email.">";
  }
}
if (!$name)
  exit;

/* Create and show the image */
Header ("Content-type: image/gif");
$im = imagecreate ($size*strlen($name), $size*1.5);
$black = ImageColorAllocate ($im, 255, 255, 255);
$white = ImageColorAllocate ($im, 0,0,0);
ImageTTFText($im, $size, 0, 0, $size , $white, "/usr/share/enlightenment/E-docs/aircut3.ttf",$name);
ImageGif ($im);
ImageDestroy ($im);
?>

The script to find the id:

#!/bin/sh

# small script for email.php3
echo "Enter login:"
read login
echo "The URL is:"
printf "http://yourhost/email.php3?id="
printf $login|md5sum|cut -c1-8
echo


You can also create temporary email aliases, each week, for all users
Good: Efficient, and you can give your real email in your reply-to address
Bad: Temporary emails
How to do: Not so hard todo
Example: (script & php, Unix)
#!/bin/sh
#
# Anonymous random aliases for all users
# changed each week, to avoid spam problems
# on websites
# (to put into /etc/cron.weekly/)

# Each alias is regenerated each week, and valid for 2 weeks

# prefix for all users
# must not be the prefix of another alias!
USER_PREFIX="user-"

# valid for 2 weeks
ALIAS_VALID=2

# random string
SECRET="my secret string `hostname -f`"

# build
grep -vE "^$USER_PREFIX" /etc/aliases > /etc/aliases.new
for i in `cut -f1 -d':' /etc/passwd`; do
  if test `id -u $i` -ge 500; then
    off=0
    while test "$off" -lt $ALIAS_VALID; do
      THISWEEK="`date +'%Y'` $[`date +'%U'`-$off]"
      SECRET="`echo \"$SECRET $i $THISWEEK\" | md5sum | cut -c1-4`"
      FIRST=`echo $i | cut -c1-3`
      NAME="$USER_PREFIX$FIRST$SECRET"
      echo "$NAME : $i" >> /etc/aliases.new
      #
      off=$[$off+1]
    done
  fi
done

# move file
mv -f /etc/aliases /etc/aliases.old
mv -f /etc/aliases.new /etc/aliases

# update aliases
newaliases

And then, put the email address in your pages through:

<a href="mailto:<?php
    $user="smith";
    $alias=exec("grep ".$user." /etc/aliases | cut -f1 -d' ' | head -n1");
    print $alias;
?>@mycompany.com>>
Title: Re: Limit Viewing
Post by: Joachim Müller on May 24, 2005, 06:54:35 am
I agree that it's impossible to make any website bullet-proof against copy cats, but most often it helps to make it harder for newbies to steal. Most newbie website owners fall for easy tricks and try to implement silly "no-right-click" JavaScript gimmicks, which are very annoying in the first place.

This is my recommendation for those who actually want to protect their site against bandwidth theft:
Code: [Select]
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?mysite.tld(/)?.*$     [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?site-of-a-friend-who-is-allowed-to-hotlink.tld(/)?.*$     [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?another-site-of-a-friend.tld(/)?.*$     [NC]
RewriteRule .*\.(gif|jpg|jpeg|bmp)$ http://mysite.tld/pic/that/is/displayed/when/somebody/hotlinks/stolen.gif [R,NC]

As I said above: all other methods of reducing bandwidth usage, e.g. by counting the number of pics a registered user has made and not letting him view more than X pics within a certain period is difficult to implement and will require additional queries to be run. You database will become fatter, and coppermine will load slower. I'm not convinced that such a feature should be implemented into coppermine's core code, although it would drastically limit abuse by leechers, but as well spidering by search engines.
Title: Re: Limit Viewing
Post by: Loki66 on May 24, 2005, 09:27:46 am
Is it possible to make the following changes with CPG ?

 
http://www.mysite.com/albums/album 1/thum_xyz0001.jpg
 
http://www.mysite.com/albums/album 1//normal_xyz0001.jpg
 
http://www.mysite.com/albums/album 1/originalname.jpg

all thumbnails and intermediate pics are renamed by the script so that the original name of the pic is preserved .............

Thanks,

Loki
Title: Re: Limit Viewing
Post by: Joachim Müller on May 24, 2005, 10:25:10 am
being considered, but any naming scheme that we will come up with is bound to break, as there surely will be users who just name their files in a way that collides with anything you can possible come up with. We believe in doing as few file-level operations as possible: with so many people around who don't have the slightest idea what CHMOD is (search the support board to get a rough idea how many people fail to do this simple operation), there surely will be some where there (silly) server setup will prevent coppermine from doing what it currently can do just fine. Another naming scheme means additional checks needed (if a file exists etc.), which will be even harder with filesnames in non-latin encoding.
In other words: we're very reluctant to change anything there.

Joachim
Title: Re: Limit Viewing
Post by: Loki66 on May 25, 2005, 05:55:49 pm
Original picture names can be generated from the original name by some simple function like:
get first 3 digits of the name and encipher them with md5 algorithm.
This way it won't confuse with any other names.

For sure, its is a technical challenge but do we want Coppermine to become the best ASP gallery software or not ?. Newbies have to learn to swim ...as there are sharks in the water.

Loki
Title: Re: Limit Viewing
Post by: Joachim Müller on May 26, 2005, 08:18:12 am
asp? ::) I prefer PHP... ;)
Title: Re: Limit Viewing
Post by: Loki66 on May 30, 2005, 12:20:57 am
Heuu, sorry, I meant "online" .... ;)
Title: Re: Limit Viewing
Post by: Loki66 on May 31, 2005, 08:30:18 pm
So can we have this function, protection of original pics, agreed so it become a full feature of CPG ?.

Loki
Title: Re: Limit Viewing
Post by: andy_cul on July 02, 2005, 10:23:36 am
but is the mod possible? this would be a great mod if ever coded
Title: Re: Limit Viewing
Post by: Loki66 on July 04, 2005, 01:02:17 pm
No reply .... Please put this feature in the wish list !
Title: Re: Limit Viewing
Post by: andy_cul on July 04, 2005, 03:03:10 pm
Quote
Please put this feature in the wish list !

I Secong Emotion  ;D

This will help me save a lot of bandwidth.
Title: Re: Limit Viewing
Post by: Joachim Müller on July 05, 2005, 07:52:07 am
@andy_cul: I think everybody has understood that you want this feature, no need to repeat this over.
If you need it that badly, why don't you code it, or hire someone to code it for you?
Title: Re: Limit Viewing
Post by: andy_cul on July 05, 2005, 11:12:25 am
sorry for being pesky  :-X

Quote
If you need it that badly, why don't you code it, or hire someone to code it for you?

Its ok i'll just wait someone to code it.  I'm not a programmer  ;D
Title: Re: Limit Viewing
Post by: Loki66 on July 16, 2005, 01:07:11 am
I would be more than happy fo find a coder that would implement that picture, is Mr Cul interested in joining me ?
Title: Re: Limit Viewing
Post by: lilleman on July 18, 2005, 11:13:23 pm
if someone can make a x gig limit per usergroup per day i would gladly donate some $ to that guy
like: group 1 (donators/members) = limit of 3 gigs/day
group 2 (non donators/non members)= limit of 1 gig/day
group 3 (admin/moderator)= unlimited
Title: Re: Limit Viewing
Post by: RatKing on July 22, 2005, 03:53:21 pm
I would love to take up hat chalange I'll see what I can do next week. This weekend I'm to bussy but during work I should be able to find a few hours to code this.

I'll see about making this in two flavors even as I can see the first requests comming in for that already:

Both should be completely configurable without breaking the current CPG database, and of course should work on all platforms.

The price well thats not importand lets first see if it can be done, if so it will be published and a paypal donate button will be added somewhere so people can if they feel like paying for this send me some of their hard earned cash.  ;D
Title: Re: Limit Viewing
Post by: RatKing on August 01, 2005, 06:05:16 pm
What I have so far is user based bandwith monitoring that will not care about tumbnails being shown only the full pictures includign the once that you see in the slideshow are monitored.

Ok, the files that need to be modified are:

lang/<your language>.php
usermgr.php
delete.php
displayimage.php
include/init.inc.php
include/slideshow.inc.php

On top of that the database needs a change... (we will add a table)

Ok lets start with the language file(s) this will not be noticed by anyone for obvious reasons I will only show how to

change the english language file.


Look for:
Code: [Select]
  'user_occupation' => 'User occupation',
  'latest_upload' => 'Recent uploads', //cpg1.3.0

Replace with:
Code: [Select]
  'user_occupation' => 'User occupation',
  'user_bandwidth' => 'User bandwidth limit (in Mb)',
  'latest_upload' => 'Recent uploads', //cpg1.3.0


Look for:
Code: [Select]
$lang_error = 'Error';

Replace with:
Code: [Select]
$lang_error = 'Error';
$lang_bandwidth_limit = 'Bandwidth limit reached';

Look for:
Code: [Select]
$lang_errors = array(
  'access_denied' => 'You don\'t have permission to access this page.',

Replace with:
Code: [Select]
$lang_errors = array(
  'bandwidth_limit' => 'You have exceeded your bandwidth limit of [limit]Mb',
  'access_denied' => 'You don\'t have permission to access this page.',

Look for:
Code: [Select]
  'Cookies settings',
  array('Name of the cookie used by the script (when using bbs integration, make sure it differs from the bbs\'s cookie

name)', 'cookie_name', 0),
  array('Path of the cookie used by the script', 'cookie_path', 0),

  'Miscellaneous settings',
  array('Enable debug mode', 'debug_mode', 9), //cpg1.3.0
  array('Display notices in debug mode', 'debug_notice', 1), //cpg1.3.0

Replace with:
Code: [Select]
  'Cookies settings',
  array('Name of the cookie used by the script (when using bbs integration, make sure it differs from the bbs\'s cookie

name)', 'cookie_name', 0),
  array('Path of the cookie used by the script', 'cookie_path', 0),

  'Bandwidth monitoring',
  array('Monitor bandwidth per user', 'monitor_bandwidth', 1),

  'Miscellaneous settings',
  array('Enable debug mode', 'debug_mode', 9), //cpg1.3.0
  array('Display notices in debug mode', 'debug_notice', 1), //cpg1.3.0

Ok, now that should be it.... as far as the language file goes.


Then we will do the table creation in the database which again should not be noticed by our dear users.
Code: [Select]
DROP TABLE IF EXISTS `cpg133_bandwidth`;
CREATE TABLE IF NOT EXISTS `cpg133_bandwidth` (
  `user_id` int(11) NOT NULL default '0',
  `bandwidth` bigint(20) NOT NULL default '0',
  `download` bigint(20) NOT NULL default '0',
  PRIMARY KEY  (`user_id`)
) TYPE=MyISAM;

Then we need to make sure all our users are in there plus an extra which is the unknown user (iow logged in)
Code: [Select]
INSERT INTO `cpg133_bandwidth` VALUES (0, 0, 0);
INSERT INTO `cpg133_bandwidth` VALUES (select user_id, 0, 0 from `cpg133_users`);


Now we need to add a configuration field to the admin screen so we can en/disable bandwidth checking
The following SQL code will do that:
Code: [Select]
INSERT INTO `cpg133_config` VALUES ('monitor_bandwidth', '0');

Now we need to make sure we can access the bandwidth table and add some custom error message to do this we edit init.inc.php

Look for:
Code: [Select]
$CONFIG['TABLE_ECARDS']          = $CONFIG['TABLE_PREFIX']."ecards";
$CONFIG['TABLE_TEMPDATA']        = $CONFIG['TABLE_PREFIX']."temp_data";

Replace with:
Code: [Select]
$CONFIG['TABLE_ECARDS']          = $CONFIG['TABLE_PREFIX']."ecards";
$CONFIG['TABLE_TEMPDATA']        = $CONFIG['TABLE_PREFIX']."temp_data";
$CONFIG['TABLE_BANDWIDTH']       = $CONFIG['TABLE_PREFIX']."bandwidth";

Look for:
Code: [Select]
define('CRITICAL_ERROR', 3);

Replace with:
Code: [Select]
define('CRITICAL_ERROR', 3);
define('BANDWIDTH_LIMIT', 4);

Ok, so now we have a table and we have the language files changed lets make sure that new users get added with their own

personal bandwidth limit.


So now then usermgr.php

Look for:
Code: [Select]
    case 'new_user' :
        db_query("INSERT INTO {$CONFIG['TABLE_USERS']}(user_regdate, user_active) VALUES (NOW(), 'YES')");

        $user_id = mysql_insert_id();

Replace with:
Code: [Select]
    case 'new_user' :
        db_query("INSERT INTO {$CONFIG['TABLE_USERS']}(user_regdate, user_active) VALUES (NOW(), 'YES')");

        $user_id = mysql_insert_id();
        db_query("INSERT INTO {$CONFIG['TABLE_BANDWIDTH']}(user_id, bandwidth, download) VALUES ($user_id, 0, 0)");

Look for:
Code: [Select]
function update_user($user_id)
{
    global $CONFIG, $PHP_SELF, $HTTP_POST_VARS;
    global $lang_usermgr_php, $lang_register_php;

    $user_name = addslashes(trim($HTTP_POST_VARS['user_name']));
    $user_password = addslashes(trim($HTTP_POST_VARS['user_password']));
    $user_email = addslashes(trim($HTTP_POST_VARS['user_email']));
    $user_location = addslashes($HTTP_POST_VARS['user_location']);
    $user_interests = addslashes($HTTP_POST_VARS['user_interests']);
    $user_website = addslashes($HTTP_POST_VARS['user_website']);
    $user_occupation = addslashes($HTTP_POST_VARS['user_occupation']);
    $user_active = $HTTP_POST_VARS['user_active'];
    $user_group = $HTTP_POST_VARS['user_group'];
    $group_list = isset($HTTP_POST_VARS['group_list']) ? $HTTP_POST_VARS['group_list'] : '';

Replace with:
Code: [Select]
function update_user($user_id)
{
    global $CONFIG, $PHP_SELF, $HTTP_POST_VARS;
    global $lang_usermgr_php, $lang_register_php;

    $user_name = addslashes(trim($HTTP_POST_VARS['user_name']));
    $user_password = addslashes(trim($HTTP_POST_VARS['user_password']));
    $user_email = addslashes(trim($HTTP_POST_VARS['user_email']));
    $user_location = addslashes($HTTP_POST_VARS['user_location']);
    $user_interests = addslashes($HTTP_POST_VARS['user_interests']);
    $user_website = addslashes($HTTP_POST_VARS['user_website']);
    $user_occupation = addslashes($HTTP_POST_VARS['user_occupation']);
    $user_active = $HTTP_POST_VARS['user_active'];
    $user_group = $HTTP_POST_VARS['user_group'];
    $user_bandwidth = $HTTP_POST_VARS['bandwidth'];
    $group_list = isset($HTTP_POST_VARS['group_list']) ? $HTTP_POST_VARS['group_list'] : '';

Look for:
Code: [Select]
    $sql_update = "UPDATE {$CONFIG['TABLE_USERS']} " . "SET " . "user_name           = '$user_name', " . "user_email     

    = '$user_email', " . "user_active    = '$user_active', " . "user_group           = '$user_group', " . "user_location 

= '$user_location', " . "user_interests = '$user_interests', " . "user_website          = '$user_website', " .

"user_occupation= '$user_occupation', " . "user_group_list      = '$user_group_list'";
    if (strlen($user_password)) $sql_update .= ", user_password = '$user_password'";
    $sql_update .= " WHERE user_id = '$user_id'";

    db_query($sql_update);
}

Replace with:
Code: [Select]
    $sql_update = "UPDATE {$CONFIG['TABLE_USERS']} " . "SET " . "user_name           = '$user_name', " . "user_email     

    = '$user_email', " . "user_active    = '$user_active', " . "user_group           = '$user_group', " . "user_location 

= '$user_location', " . "user_interests = '$user_interests', " . "user_website          = '$user_website', " .

"user_occupation= '$user_occupation', " . "user_group_list      = '$user_group_list'";
    if (strlen($user_password)) $sql_update .= ", user_password = '$user_password'";
    $sql_update .= " WHERE user_id = '$user_id'";

    db_query($sql_update);
    $sql_update = "UPDATE {$CONFIG['TABLE_BANDWIDTH']} SET bandwidth = '" . round(($user_bandwidth*1024)*1024) .
                  "' WHERE user_id = '$user_id'";
    db_query($sql_update);
}

Look for:
Code: [Select]
function edit_user($user_id)
{
    global $CONFIG, $PHP_SELF;
    global $lang_usermgr_php, $lang_yes, $lang_no;

    $form_data = array(
        array('input', 'user_name', $lang_usermgr_php['name'], 25),
        array('password', 'user_password', $lang_usermgr_php['password'], 25),
        array('yesno', 'user_active', $lang_usermgr_php['user_active']),
        array('group_list', 'user_group', $lang_usermgr_php['user_group']),
        array('input', 'user_email', $lang_usermgr_php['user_email'], 255),
        array('input', 'user_location', $lang_usermgr_php['user_location'], 255),
        array('input', 'user_interests', $lang_usermgr_php['user_interests'], 255),
        array('input', 'user_website', $lang_usermgr_php['user_web_site'], 255),
        array('input', 'user_occupation', $lang_usermgr_php['user_occupation'], 255),
        );

    $sql = "SELECT * FROM {$CONFIG['TABLE_USERS']}  WHERE user_id = '$user_id'";


Replace with:
Code: [Select]
function edit_user($user_id)
{
    global $CONFIG, $PHP_SELF;
    global $lang_usermgr_php, $lang_yes, $lang_no;

    $form_data = array(
        array('input', 'user_name', $lang_usermgr_php['name'], 25),
        array('password', 'user_password', $lang_usermgr_php['password'], 25),
        array('yesno', 'user_active', $lang_usermgr_php['user_active']),
        array('group_list', 'user_group', $lang_usermgr_php['user_group']),
        array('input', 'user_email', $lang_usermgr_php['user_email'], 255),
        array('input', 'user_location', $lang_usermgr_php['user_location'], 255),
        array('input', 'user_interests', $lang_usermgr_php['user_interests'], 255),
        array('input', 'user_website', $lang_usermgr_php['user_web_site'], 255),
        array('input', 'user_occupation', $lang_usermgr_php['user_occupation'], 255),
        array('input', 'bandwidth', $lang_usermgr_php['user_bandwidth'], 255),
        );

    $sql = "SELECT * FROM {$CONFIG['TABLE_USERS']} as tu, {$CONFIG['TABLE_BANDWIDTH']} as tb WHERE tu.user_id =

'$user_id' AND tb.user_id = tu.user_id";

Look for:
Code: [Select]
    foreach ($form_data as $element) switch ($element[0]) {
        case 'input' :
            $user_data[$element[1]] = $user_data[$element[1]];
            echo <<<EOT

Replace with:
Code: [Select]
    foreach ($form_data as $element) switch ($element[0]) {
        case 'input' :
            if ( $element[1] == 'bandwidth' ) { $user_data[$element[1]] = ($user_data[$element[1]]/1024)/1024; }
            echo <<<EOT

And we can add users with their bandwith limit set, now we need to make sure that if we remove them we clean up this

users info in the bandwith table as well.

So now for delete.php

Look for:
Code: [Select]
        db_query("UPDATE {$CONFIG['TABLE_PICTURES']} SET  owner_id = '0' WHERE  owner_id = '$user_id'");

Replace with:
Code: [Select]
        db_query("UPDATE {$CONFIG['TABLE_PICTURES']} SET  owner_id = '0' WHERE  owner_id = '$user_id'");
        // BANDWIDTH MONITORING
        db_query("DELETE FROM {$CONFIG['TABLE_BANDWIDTH']} WHERE user_id = '$user_id'");
        // BANDWIDTH MONITORING
Title: Re: Limit Viewing
Post by: RatKing on August 01, 2005, 06:06:35 pm
So now that all user both old and new will have a bandwith limit set and removed all we need to do is enforce the policy.


Lets edit displayimage.php (this will as long as you copy and paste correctly not be noticed by the users)

Look for:
Code: [Select]
function html_picture()
{
    global $CONFIG, $CURRENT_PIC_DATA, $CURRENT_ALBUM_DATA, $USER, $HTTP_COOKIE_VARS;
    global $album, $comment_date_fmt, $template_display_picture;
    global $lang_display_image_php, $lang_picinfo, $lang_errors;

Replace with:
Code: [Select]
function html_picture()
{
    global $CONFIG, $CURRENT_PIC_DATA, $CURRENT_ALBUM_DATA, $USER, $HTTP_COOKIE_VARS;
    global $album, $comment_date_fmt, $template_display_picture;
    global $lang_display_image_php, $lang_picinfo, $lang_errors;

    if ( $CONFIG['monitor_bandwidth'] ) {
      $sql = "select * from ".$CONFIG['TABLE_BANDWIDTH']." WHERE user_id = '".USER_ID."' ";
      $result = db_query($sql);

      if (!mysql_num_rows($result)) cpg_die(ERROR, $lang_errors['action_failed'], __FILE__, __LINE__);
      $row = mysql_fetch_array($result);

      if ( ($row['bandwidth'] != 0) && (($row['download']+$CURRENT_PIC_DATA['filesize']) > $row['bandwidth']) ) {
        $msg = strtr($lang_errors['bandwidth_limit'], array('[limit]' => (round(($row['bandwidth']/1024)/1024))));
        cpg_die(BANDWIDTH_LIMIT, $msg, __FILE__, __LINE__);
      }
    }

Look for:
Code: [Select]
    $image_size = compute_img_size($CURRENT_PIC_DATA['pwidth'], $CURRENT_PIC_DATA['pheight'], $CONFIG['picture_width']);

    $pic_title = '';
    $mime_content = get_type($CURRENT_PIC_DATA['filename']);

    if ($CURRENT_PIC_DATA['title'] != '') {
        $pic_title .= $CURRENT_PIC_DATA['title'] . "\n";
    }

Replace with:
Code: [Select]
    $image_size = compute_img_size($CURRENT_PIC_DATA['pwidth'], $CURRENT_PIC_DATA['pheight'], $CONFIG['picture_width']);

    $pic_title = '';
    $mime_content = get_type($CURRENT_PIC_DATA['filename']);

    if ( $CONFIG['monitor_bandwidth'] ) {
      if ($CURRENT_PIC_DATA['filesize'] != '') {
        $result = db_query("UPDATE ".$CONFIG['TABLE_BANDWIDTH']." SET download=download+".$CURRENT_PIC_DATA['filesize']." WHERE user_id='".USER_ID."' ");
      }
    }

    if ($CURRENT_PIC_DATA['title'] != '') {
        $pic_title .= $CURRENT_PIC_DATA['title'] . "\n";
    }

Look for:
Code: [Select]
        // Treat the album set
        if (count($ALBUM_SET_ARRAY)) {
            $set = '';
            foreach ($ALBUM_SET_ARRAY as $album_id) $set .= ($set == '') ? $album_id : ',' . $album_id;
            $ALBUM_SET .= "AND aid IN ($set) ";
        }
    }
}

// Retrieve data for the current picture
if ($pos < 0) {
    $pid = - $pos;

Replace with:
Code: [Select]
        // Treat the album set
        if (count($ALBUM_SET_ARRAY)) {
            $set = '';
            foreach ($ALBUM_SET_ARRAY as $album_id) $set .= ($set == '') ? $album_id : ',' . $album_id;
            $ALBUM_SET .= "AND aid IN ($set) ";
        }
    }
}

  if ( $CONFIG['monitor_bandwidth'] ) {
    $result = db_query("UPDATE ".$CONFIG['TABLE_BANDWIDTH']." SET download=download+".$addsize." WHERE user_id='".USER_ID."' ");
  }

// Retrieve data for the current picture
if ($pos < 0) {
    $pid = - $pos;

To prevent our users from using the slideshow feature to escape our watchful eye we will have to modify slideshow.inc.php

Just replace all code in that file with:
Code: [Select]
<?php
/*************************
  Coppermine Photo Gallery
  ************************
  Copyright (c) 2003-2005 Coppermine Dev Team
  v1.1 originaly written by Gregory DEMAR

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  ********************************************
  Coppermine version: 1.3.3
  $Source: /cvsroot/coppermine/stable/include/slideshow.inc.php,v $
  $Revision: 1.9 $
  $Author: gaugau $
  $Date: 2005/04/19 03:17:11 $
**********************************************/
?>


<script language="JavaScript" type="text/JavaScript">
// (C) 2000 www.CodeLifter.com
// http://www.codelifter.com
// Free for all users, but leave in this  header
// NS4-6,IE4-6
// Fade effect only in IE; degrades gracefully

// $Id: slideshow.inc.php,v 1.9 2005/04/19 03:17:11 gaugau Exp $

// Set slideShowSpeed (milliseconds)
var slideShowSpeed = <?php echo (int)$HTTP_GET_VARS['slideshow'?>

// Agent sniffer shamelessly 'stolen' from the excellent X library from cross-browser.com
var xOp7=false,xOp5or6=false,xIE4Up=false,xNN4=false,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  xOp7=(xUA.indexOf('opera 7')!=-1 || xUA.indexOf('opera/7')!=-1);
  if (!xOp7) xOp5or6=(xUA.indexOf('opera 5')!=-1 || xUA.indexOf('opera/5')!=-1 || xUA.indexOf('opera 6')!=-1 || xUA.indexOf('opera/6')!=-1);
}
else if(document.layers) xNN4=true;
else {xIE4Up=document.all && xUA.indexOf('msie')!=-1 && parseInt(navigator.appVersion)>=4;}

// Duration of crossfade (seconds)
var crossFadeDuration = 3

// Specify the image files
var Pic = new Array() // don't touch this
// BANDWIDTH MONITOR
var Pic_size = new Array() // don't touch this
// BANDWIDTH MONITOR
// to add more images, just continue
// the pattern, adding to the array below
<?php
    
global $CONFIG$USER$HTTP_COOKIE_VARS;
    global 
$lang_errors;

// BANDWIDTH MONITOR
    
$sql "select * from ".$CONFIG['TABLE_BANDWIDTH']." WHERE user_id = '".USER_ID."' ";
    
$result db_query($sql);

    if (!
mysql_num_rows($result)) cpg_die(ERROR$lang_errors['action_failed'], __FILE____LINE__);
    
$row mysql_fetch_array($result);
// BANDWIDTH MONITOR

$bandwidth $row['bandwidth'];
$download  $row['download'];
$i 0;
$j 0;
$pid = (int)$HTTP_GET_VARS['pid'];
$start_img '';
$pic_data get_pic_data($HTTP_GET_VARS['album'], $pic_count$album_name, -1, -1false);
foreach (
$pic_data as $picture) {

    if(
$CONFIG['thumb_use']=='ht' && $picture['pheight'] > $CONFIG['picture_width'] ){ // The wierd comparision is because only picture_width is stored
      
$condition true;
    }elseif(
$CONFIG['thumb_use']=='wd' && $picture['pwidth'] > $CONFIG['picture_width']){
      
$condition true;
    }elseif(
$CONFIG['thumb_use']=='any' && max($picture['pwidth'], $picture['pheight']) > $CONFIG['picture_width']){
      
$condition true;
    }else{
     
$condition false;
    }

    if (
is_image($picture['filename'])) {
        if (
$CONFIG['make_intermediate'] && $condition ) {
            
$picture_url get_pic_url($picture'normal');
        } else {
            
$picture_url get_pic_url($picture'fullsize');
        }

        echo 
"Pic[$i]      = '" $picture_url "'\n";
// BANDWIDTH MONITOR
        
echo "Pic_size[$i] = " $picture['filesize'] . "\n";
// BANDWIDTH MONITOR
        
if ($picture['pid'] == $pid) {
            
$j $i;
            
$start_img $picture_url;
        }
        
$i++;
    }
}
if (!
$i) {
    echo 
"Pic[0]      = 'images/thumb_document.jpg'\n";
// BANDWIDTH MONITOR
    
echo "Pic_size[0] = 0\n";
// BANDWIDTH MONITOR
}
?>


var t
var j = <?php echo "$j\n" ?>
var p = Pic.length
var pos = j
var bandwidth = <?php echo "$bandwidth\n" ?>
var download  = <?php echo "$download\n" ?>
var viewed_size = 0

var preLoad = new Array()

function preLoadPic(index)
{
        if (Pic[index] != ''){
                window.status='Loading : '+Pic[index]
                preLoad[index] = new Image()
                preLoad[index].src = Pic[index]
<? if ( $CONFIG['monitor_bandwidth'] ) { echo "                viewed_size = viewed_size + Pic_size[index]\n"; } ?>
                Pic[index] = ''
                window.status=''
        }
}

function runSlideShow(){
<? if ( $CONFIG['monitor_bandwidth'] ) {
     echo "   if ((bandwidth != 0) && (download + viewed_size > bandwidth)) {\n";
     echo "     pos++;\n";
     echo "     endSlideShow(1)\n";
     echo "   }\n";
   } ?>
   if (xIE4Up){
        document.images.SlideShow.style.filter="blendTrans(duration=2)"
        document.images.SlideShow.style.filter= "blendTrans(duration=crossFadeDuration)"
        document.images.SlideShow.filters.blendTrans.Apply()
        }
        document.images.SlideShow.src = preLoad[j].src
        if (xIE4Up){
           document.images.SlideShow.filters.blendTrans.Play()
        }

        pos = j

        j = j + 1
        if (j > (p-1)) j=0
        t = setTimeout('runSlideShow()', slideShowSpeed)
        preLoadPic(j)
}

function endSlideShow(limit){
  self.document.location = 'displayimage.php?album=<?php echo isset($HTTP_GET_VARS['album']) ? $HTTP_GET_VARS['album'] : '';
  echo isset(
$HTTP_GET_VARS['cat']) ? '&cat=' $HTTP_GET_VARS['cat'] : '' ?>
&pos='+pos+'&addsize='+viewed_size
}

preLoadPic(j)

</script>

Now then we should have a very crude but working bandwidth monitoring setup.
Title: Re: Limit Viewing
Post by: RatKing on August 01, 2005, 08:21:06 pm
Ok, it seems that so far no one has noticed that there is no resetting of the user's downloaded data total.  :)

Doesn't really mather it will come it's just that this mod is quite big as far as mods go I'm nearly done with that bit right now so expect to see a post with more code to complete this mod during the comming week.

Oh, and yes it is more difficult than I expected it to be not because it is so complex (well it isn't so far) but because it is a lot of searching thru the code trying to figure out how things can best be done without harming the other parts within CPG.
Title: Re: Limit Viewing
Post by: andy_cul on August 03, 2005, 07:35:58 pm
How to reset bandwidth used everyday and can we add the bandwidth limit mod to Group manager so that it will be easy to manage all the users.

Issue:
I tried registering a test account and it is successful and can login but when I login as admin then go to user manager when click edit on the test account it has an error "Selected user does not exist !" While the user that I create manually can be edited
Title: Re: Limit Viewing
Post by: loki on August 08, 2005, 10:33:05 am
Hello RatKing,

My problem is not really bandwith but the users that go directly to large images without registering by guessing the url path. I believe a mod that would hide the original pictures or put them in protected directory would be much needed by all the CPG community. Do U think this can be done ?

Thanks,

Loki
Title: Re: Limit Viewing
Post by: Joachim Müller on August 08, 2005, 10:18:12 pm
has been requested before, and there's no support on the feature requests board. Please don't try to hijack threads.
Title: Re: Limit Viewing
Post by: loki on August 08, 2005, 11:30:14 pm
I am not "hijacking" as you say, and this is a discussion forum don't forget ... ::)
Title: Re: Limit Viewing
Post by: RatKing on August 08, 2005, 11:51:02 pm
 >:( Have been limited in my free time this week will need to spend some more time on this later on just bare with me on this it will take time which I have very little of  >:(
Title: Re: Limit Viewing
Post by: RatKing on August 15, 2005, 06:27:40 pm
 ::)

Yeah well time to update you lot on whats been going on... Been very bussy actualy and I have thanks to a clients request found a much much better way of protecting images and keeping track of what is being servered.

It's based upon the hide image location script by omniscientdeveloper http://forum.coppermine-gallery.net/index.php?topic=3069.0

The final details are being worked on but it is a much much cleaner and better way of doing this than the messing about with so may of the CPG core files. When it is completely done it will be posted in a seperate thread but for now I am officialy stopping development for this thread as I can see to many issues and problems with this way of trying to monitor bandwith.

When the solution that I am now working on is released is upto my client he agrees that it will be released at some point in time so for now all I can say is that it will be released.... (I still own the code  8) )
Title: Re: Limit Viewing
Post by: andy_cul on September 05, 2005, 02:50:12 am
any update :)
Title: Re: Limit Viewing
Post by: RatKing on September 06, 2005, 11:55:37 am
 ;D

Sorry for the slow pace at which this is going... I have been a little bussy, company has been sending me around the planet lately for training and courses... Anyway last weekend I have added usage graphics and I have finalized the design for the restricting of user access.

Currently it is monitored and you can give it a try, if you like so you know what the direction is I am working in.

Go to: http://ratking.net/protection

There is a user: test password: test
And there is a admin user: admin password: foobar

I would like to ask you not to change the user settings just have a look and try it. Upload images look at them try and get to an image without actualy hacking the whole system. (It's a hosting provider and they will be a little upset should their box be hacked) Anyway as long as you respect the fact that this is a shared host and that others would like to test as well then you can do what ever you like.  :-[ Did I just say that  :-[

Anyway have a look and see let me know what you think I know the template behaves a bit bas when looking at the user views but it is as I said not finished yet....
Title: Re: Limit Viewing
Post by: Stramm on September 06, 2005, 12:17:52 pm
I just tried both logins without any hacking ;) haven't tried to grab images so far just noticed that I can't view fulsized images when using the testuser account. However no problem as admin. Is this intended behaviour?
Title: Re: Limit Viewing
Post by: RatKing on September 07, 2005, 09:13:34 am
Look at the edit user page and find out if it is  ;)

If you have no time to do that, yes it is you can set any level of access, even thumbnails can be blocked.... The image used for blocking will be configurable of course... (I don't think I have done that yet)
Title: Re: Limit Viewing
Post by: Stramm on September 07, 2005, 10:26:27 am
got it... works nice.... have done some standard stuff to get the images as non user... nada
Title: Re: Limit Viewing
Post by: Sigma on September 30, 2005, 09:31:09 pm
Bump .....

Anything new on this great future ?