Mail Index


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: meta info for images... db? // WAS: [ApacheGallery] Proposal for an admin site



I've seen this come up again with this db and xml discussion, and I thought
I would bring this to the attention of some of the new users. I haven't had
time to complete this work, but it does already provide the following
features:

* decently secure administrator authentication
* rotation interface
* comments interface

Missing, but in fact the most urgent feature from my standpoint, is photo
upload, folder create, photo folder move, photo delete, folder delete, etc.

With this in place, we could create gallery areas and allow friends to
upload, rotate and annotate their own photos at will.

The pm above is no doubt out of date now, but the diff will still be of
interest.

Best regards,
Paul
----- Original Message -----
From: "Paul Vallee" <vallee@xxxxxxxxxxx>
To: "Thomas Eibner" <thomas@xxxxxxxxxx>; <users@xxxxxxxxxxxxxxxx>
Sent: Friday, March 08, 2002 4:06 PM
Subject: Re: [ApacheGallery] Proposal for an admin site


Hi Thomas,

Happy annivesary!

Thanks for your advice.

I've changed the software to use Digest::MD5 (very painless, thanks for the
tip.)

I don't really understand your suggestion of an additional secret over and
above the password, and why it improves security. Does the user define it at
login, like a PIN? And if so, would I track the valid values in a local
file? I understand how this improves security but if that's what you have in
mind we might as well do (arbitrary database based?) multi-user
authentication with expiring sessions, and track the sessionid in the cookie
and the (database/file) rather than the password. I would prefer to leave
that for later, unless you feel strongly about it. Let me know if I've
misunderstood. Right now, the risk is manageable in my opinion, especially
if the user "logs out", which zeros out the cookie.

I have studied the documentation for CGI::FastTemplate at
http://theoryx5.uwinnipeg.ca/CPAN/data/CGI-FastTemplate/FastTemplate.html
and I'm afraid I don't understand your suggestion of using it to avoid
hard-coding the form. I am already using CGI to dynamically generate the
form and CGI::FastTemplate to set a template variable for display. Perhaps
you could help me to understand better what you have in mind? Even better,
if it's not too arduous, by all means just fix it in my code if you like. I
certainly wouldn't consider it meddling! ;-)

Please find the new Gallery.pm (using Digest::MD5) and the new diff
attached.

Best regards,
Paul

----- Original Message -----
From: "Thomas Eibner" <thomas@xxxxxxxxxx>
To: <users@xxxxxxxxxxxxxxxx>
Sent: Thursday, March 07, 2002 4:21 PM
Subject: Re: [ApacheGallery] Proposal for an admin site


On Thu, Mar 07, 2002 at 04:03:05PM -0500, Paul Vallee wrote:
> Hello everyone,
>
> I'm having trouble accessing the cvs repository (no doubt my own lame
fault,
> but there you have it!). So instead of stalling any longer, here's the
diff
> patch and the new copy of Gallery.pm, attached.

You're using ssh right? Tried doing it from the machine the repository is
on?

> If any of you have cvs access and are willing, please go ahead and upload
> it. Michael has already given me permission to bang it in before an
intense
> QA, I guess his feeling is that problems can be fixed afterwards.

As long as we don't release any untested code it should be fine, that is
what
-dev is for anyway ;)

> This implements authentication, rotation and the editing of annotation
files
> on the server.
> Feedback welcomed and appreciated, and cheers!

>From looking at the code I just have one tiny question, why don't we
build the form with help of CGI::FastTemplate so we don't hardcode it
into the program? (This is not a requirement from my side and could
always be implemented later). And for the MD5 part:

The "MD5" module is depreciated.  Use "Digest::MD5" instead. (perldoc MD5)

(and using the hexhash method instead of using unpack to convert it to
hex might be a good idea too). Should we furthermore let the user set a
secret so it's gonna be even harder breaking the "encryption" of the
cookie. Like:
MD5->hexhash('USERDEFINEDSECRET' . MD5->hexhash($password));

> Paul (30 years old today!)

Congrats!

Thomas (1 year wedding anniversary today!)

--
  Thomas Eibner <http://thomas.eibner.dk/> DnsZone <http://dnszone.org/>
  mod_pointer <http://stderr.net/mod_pointer> <http://photos.eibner.dk/>
  !(C)<http://copywrong.dk/>                  <http://apachegallery.dk/>
          Putting the HEST in .COM <http://www.hestdesign.com/>

---------------------------------------------------------------------
Apache::Gallery users mailinglist. http://apachegallery.dk/
To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx




Attachment: Gallery.pm
Description: Binary data

16,17d15
< use Apache::Cookie;
< use Digest::MD5;
22d19
< use CGI;
51,56d47
< 	my $authenticated = '';
< 	if ( isauth() )
< 	{ 
< 	    $authenticated = '( User authenticated ) ';
< 	}
< 
98,147c89,91
< 
< 		$tpl->assign(AUTH => '' );
< 
< 		if ( $apr->param('auth')  )
< 		{
< 		    if ( $apr->param('password')  )
< 		    {
< 			$authenticated = authenticate_user( $apr->param('password') );
< 
< 			if ( $authenticated eq '( User authenticated ) ' ) {
< 			    my $hash=Digest::MD5->new;
< 			    $hash->add($apr->param('password'));
< 			    my $digest = $hash->hexdigest();
< 			    my $cookie = Apache::Cookie->new($apr,
<                              -name    =>  'password',
<                              -value   =>  $digest,
<                              -expires =>  '+1h'
< 				       );
< 
< 			$cookie->bake;
< 			} else {
<     			    my $cookie = Apache::Cookie->new($apr,
<                              -name    =>  'password',
<                              -value   =>  '',
<                              -expires =>  '+1h'
< 				       );
< 			    $cookie->bake;
< 			}
< 
< 		    } else {
< 
< 			if ( $apr->param('logout_button') )
< 			{
<     			    my $cookie = Apache::Cookie->new($apr,
<                              -name    =>  'password',
<                              -value   =>  '',
<                              -expires =>  '+1h'
< 				       );
< 			    $cookie->bake;
< 			    $authenticated = '';
< 			}
< 
< 		    }
< 
< 		    $tpl->assign(AUTH => build_auth_form($authenticated));
< 
< 	           } 
< 
< 		$tpl->assign(MENU => $authenticated . generate_menu($r));
< 
---
> 		
> 		$tpl->assign(MENU => generate_menu($r));
> 	
235d178
< 
282,392d224
< 		# admin section
< 		# admin form section
< 		
< 		if ( isauth() ) {
< 
< 		    my $query = new CGI;
< 		    my $admin;
< 
< 		    # Rotate form
< 
< 		    my @rotatefile;
< 		    my $rotateval = '0';
< 		    if ( open (ROTATE, "$filename.rotate") ) {
< 			@rotatefile = <ROTATE>;
< 			close ROTATE;
< 		    }
< 		    foreach my $line (@rotatefile) {
< 			chomp($rotateval = $line);
< 		    }
<     		    $tpl->assign(DEBUG => "rotatefile is $filename.comment and contents are $rotateval");
< 
< 		    $admin=$query->start_form;
< 		    my %labels = ('0'=>'0', '1'=>'90', '2'=>'180', '3'=>'270');
< 		    $admin = $admin . 'Rotation: ' . $query->popup_menu('rotate_menu',
< 						    ['0','1','2','3'],
< 						"$rotateval",\%labels);
< 		    $admin = $admin . $query->submit(-name=>'resolution_button', -value=>'submit');
< 		    $admin = $admin . $query->end_form;
< 
< 
< 		    # Comments form
< 		    my @commentfile;
< 		    my $comments = '';
< 		    if ( open (COMMENTS, "$filename.comment") ) {
< 			@commentfile = <COMMENTS>;
< 			close COMMENTS;
< 		    }
< 		    foreach my $line (@commentfile) {
< 			$comments = $comments . $line;
< 		    }
< 
< 		    $admin = $admin . $query->start_form;
< 		    $admin = $admin . 'Comments: ' . $query->textarea(-name=>'comments',
< 		         -default=>$comments,
< 		         -rows=>10,
< 		         -columns=>50);
< 		    $admin = $admin . $query->submit(-name=>'comments_button', -value=>'submit');
< 		    $admin = $admin . $query->end_form;
< 
< 		    $tpl->assign(ADMIN => $admin );
< 
< 		} else {
< 		    $tpl->assign(ADMIN => '');
< 		}
< 
< 		# end admin form section
< 
< 		# admin processing section
< 		if ( isauth() ) {
< 
< 		my @dirs = split(/\//, $filename);
< 		my $fileonly = pop(@dirs);
< 		my $cache = join ("/", @dirs) . "/.cache";
< 
< 		    if ( $apr->param('resolution_button') && $apr->param('resolution_button') eq 'submit' )
< 		    {
< 			
< 			if ( $apr->param('rotate_menu') eq '0' )
< 			{ unlink "$filename.rotate";
< 			}
< 			else {
< 			    open ROTATEFILE, ">$filename.rotate";
< 			    print ROTATEFILE $apr->param('rotate_menu') . "\n";
< 			    close ROTATEFILE;
< 			}
< 
< 			# Blow the cache for this file.
< 
< 			unless (opendir (DIR, $cache)) {
< 			    show_error ($r, $!, "Unable to access cache directory $cache: $!");
< 			    return OK;
< 			}
< 
< 			my @files = readdir (DIR);
< 			@files = sort @files;
< 			my $filelist;
< 
< 			if (@files) {
< 
< 			    foreach my $picture (@files) {
< 
< 				if (-f $cache.'/'.$picture && ($picture =~ m/$fileonly/i)) {
< 				    unlink $cache.'/'.$picture;
< 				}
< 			    }
< 			}
< 			$tpl->assign(DEBUG => 'rotate!');
< 		    }
< 		    if ( $apr->param('comments_button') && $apr->param('comments_button') eq 'submit' )
< 		    {
< 			open COMMENTFILE, ">$filename.comment";
< 			print COMMENTFILE $apr->param('comments');
< 			close COMMENTFILE;
< 			$tpl->assign(DEBUG => $apr->param('comments'));
< 		    }
< 
< 		}
< 
< 		# end admin processing section
< 		# end admin section
< 
395c227
< 		$tpl->assign(MENU => $authenticated . generate_menu($r));
---
> 		$tpl->assign(MENU => generate_menu($r));
581c413
< 		if ($r->dir_config('GalleryCopyrightImage') && -f $r->dir_config('GalleryCopyrightImage')) {
---
> 		if (-f $r->dir_config('GalleryCopyrightImage')) {
771,828d602
< 
< sub build_auth_form {
< 
<     my $form;
<     my $query = new CGI;
<     my $authenticated = shift;
<     $form = $query->start_form();
< 
<     if ( $authenticated eq '( User authenticated ) ' )
<     {   
< 	$form = $form . $query->submit(-name=>'logout_button', -value=>'logout');
<     } 
<     else {
< 	$form = $form . $query->password_field(-name=>'password',
<                                -value=>'');
< 	$form = $form . $query->submit(-name=>'submit_button', -value=>'submit');
<     }
<     $form = $form . $query->endform();
< 
< 
<     return $form;
< }
< 
< sub authenticate_user {
< 
<     my $password = shift;
<     my $returnstring;
<     if ( Apache->request()->dir_config('AdminPassword') && 
< 	 Apache->request()->dir_config('AdminPassword') eq $password )
<     { $returnstring = '( User authenticated ) ';
< 
<       } else {
< 	  $returnstring = '( User authentication failed )' ;
< 	  }
< 
<     return $returnstring;
< 
< }
< 
< sub isauth {
<     my %cookies = Apache::Cookie->fetch;
<     my $isauth;
<     my $hash=Digest::MD5->new;
< 
<     if (Apache->request()->dir_config('AdminPassword')) {
< 	$hash->add(Apache->request()->dir_config('AdminPassword'));
<     } else {
< 	return 0;
<     }
< 
<     my $digest = $hash->hexdigest();
< 
<     if ( $cookies{'password'} && $cookies{'password'}->value eq $digest )
<     { $isauth = 1 ;
<   } else { $isauth = 0 }
< return $isauth;
< }
<