add password protection feature
authorgc <gc>
Thu, 27 Oct 2005 19:52:14 +0000 (19:52 +0000)
committergc <gc>
Thu, 27 Oct 2005 19:52:14 +0000 (19:52 +0000)
bin/booh
bin/booh-backend
data/booh/images/galeon-secure.png [new file with mode: 0644]

index 9232874bd193f8e2229b03210e450f8e4f7bcf74..36899466cf6508c1d501c5d2997bd625d31ca95e 100755 (executable)
--- a/bin/booh
+++ b/bin/booh
@@ -1563,6 +1563,9 @@ def show_popup(parent, msg, *options)
     if options[0] && options[0][:centered]
         lbl.set_justify(Gtk::Justification::CENTER)
     end
+    if options[0] && options[0][:selectable]
+        lbl.selectable = true
+    end
     if options[0] && options[0][:topwidget]
         dialog.vbox.add(options[0][:topwidget])
     end
@@ -3535,6 +3538,126 @@ def gtk_thread_abandon
     $protect_gtk_pending_calls.unlock
 end
 
+def ask_password_protect
+    value = $xmldir.attributes['password-protect']
+
+    dialog = Gtk::Dialog.new(utf8(_("Password protect this sub-album")),
+                             $main_window,
+                             Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
+                             [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
+                             [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+
+    lbl = Gtk::Label.new
+    lbl.markup = utf8(
+_("You can choose to <b>password protect</b> the sub-album '%s' (only available
+if you plan to publish your web-album with an Apache web-server). This will use
+the .htaccess/.htpasswd feature of Apache (not so strongly crypted password, but
+generally ok for protecting web contents). Users will be prompted with a dialog
+asking for a username and a password, failure to give the correct pair will
+block access.
+") % File.basename($current_path))
+    dialog.vbox.add(lbl)
+    dialog.vbox.add(Gtk::Alignment.new(0.5, 0.5, 0, 0).add(Gtk::HBox.new.add(rb_no = Gtk::RadioButton.new(utf8(_("free access")))).
+                                                                         add(rb_yes = Gtk::RadioButton.new(rb_no, utf8(_("password protect with password file:")))).
+                                                                         add(file = Gtk::Entry.new)))
+    dialog.vbox.add(Gtk::Alignment.new(0.5, 0.5, 0.5, 0.2).add(Gtk::HBox.new.add(bt_help = Gtk::Button.new(utf8(_("help about password file")))).
+                                                                             add(Gtk::Label.new).
+                                                                             add(bt_gen = Gtk::Button.new(utf8(_("generate a password file"))))))
+    dialog.window_position = Gtk::Window::POS_MOUSE
+    dialog.show_all
+    if value.nil?
+        rb_no.active = true
+    else
+        rb_yes.active = true
+        file.text = value
+    end
+
+    bt_help.signal_connect('clicked') {
+        show_popup(dialog, utf8(
+_("Password protection proposed here uses the .htaccess/.htpasswd features
+proposed by Apache. So first, be sure you will publish your web-album on an
+Apache web-server. Second, you will need to have a .htpasswd file accessible
+by Apache somewhere on the web-server disks. The password file you must
+provide in the dialog when choosing to password protect is the full absolute
+path to access this file <b>on the web-server</b> (not on your machine). Note
+that if you use a relative path, it will be considered relative to the
+Document Root of the Apache configuration.")))
+    }
+
+    bt_gen.signal_connect('clicked') {
+        gendialog = Gtk::Dialog.new(utf8(_("Generate a password file")),
+                                    dialog,
+                                    Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
+                                    [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
+                                    [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+        
+        lbl = Gtk::Label.new
+        lbl.text = utf8(
+_("I can generate a password file (.htpasswd for Apache) for you. Just type
+the username and password you wish to put in it below and validate."))
+        gendialog.vbox.add(lbl)
+        gendialog.vbox.add(Gtk::Alignment.new(0.5, 0.5, 0, 0).add(Gtk::HBox.new.add(Gtk::Label.new(utf8(_('Username:')))).
+                                                                                add(user = Gtk::Entry.new).
+                                                                                add(Gtk::Label.new(utf8(_('Password:')))).
+                                                                                add(pass = Gtk::Entry.new)))
+        pass.visibility = false
+        gendialog.window_position = Gtk::Window::POS_MOUSE
+        gendialog.show_all
+        gendialog.run { |response|
+            u = user.text
+            p = pass.text
+            gendialog.destroy
+            if response == Gtk::Dialog::RESPONSE_OK
+                def rand_letter
+                    ary = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [ '.', '/' ]
+                    return ary[rand(ary.length)]
+                end
+                fout = Tempfile.new("htpasswd")
+                fout.write("#{u}:#{p.crypt(rand_letter + rand_letter)}\n")
+                fout.close
+                File.chmod(0644, fout.path)
+                show_popup(dialog, utf8(
+_("The file <b>%s</b> now contains the username and the crypted password. Now
+copy it to a suitable location on the machine hosting the Apache web-server (better not
+below the Document Root), and specify this location in the password protect dialog.") % fout.path), { :selectable => true })
+            end
+        }
+    }
+
+    dialog.run { |response|
+        if rb_no.active?
+            newval = nil
+        else
+            newval = file.text
+        end
+        dialog.destroy
+        if response == Gtk::Dialog::RESPONSE_OK && value != newval
+            $modified = true
+            msg 3, "changing password protection of #{$current_path} to #{newval}"
+            if newval.nil?
+                $xmldir.delete_attribute('password-protect')
+            else
+                $xmldir.add_attribute('password-protect', newval)
+            end
+            save_undo(_("set password protection for %s") % File.basename($current_path),
+                      Proc.new {
+                          if value.nil?
+                              $xmldir.delete_attribute('password-protect')
+                          else
+                              $xmldir.add_attribute('password-protect', value)
+                          end
+                          Proc.new {
+                              if newval.nil?
+                                  $xmldir.delete_attribute('password-protect')
+                              else
+                                  $xmldir.add_attribute('password-protect', newval)
+                              end
+                          }
+                      })
+        end
+    }
+end
+
 def create_main_window
 
     mb, tb = create_menu_and_toolbar
@@ -3557,6 +3680,17 @@ def create_main_window
         end
         pop_mousecursor
     }
+    $albums_tv.signal_connect('button-release-event') { |w, event|
+        if event.event_type == Gdk::Event::BUTTON_RELEASE && event.button == 3 && !$current_path.nil?
+            menu = Gtk::Menu.new
+            menu.append(passprotect = Gtk::ImageMenuItem.new(utf8(_("Password protect"))))
+            passprotect.image = Gtk::Image.new("#{$FPATH}/images/galeon-secure.png")
+            passprotect.signal_connect('activate') { ask_password_protect }
+            menu.show_all
+            menu.popup(nil, nil, event.button, event.time)
+        end
+    }
+
     $albums_ts = Gtk::TreeStore.new(String, String)
     $albums_tv.set_model($albums_ts)
     $albums_tv.signal_connect('realize') { $albums_tv.grab_focus }
index 35ec7b4f26b8b1b9c01267db57af22cf05d87878..6dacc456165314bb92b761f5086570888213b315 100755 (executable)
@@ -795,6 +795,13 @@ def walk_source_dir
                 end
             }
 
+            #- generate .htaccess file if needed
+            if auth_user_file = xmldir.attributes['password-protect']
+                ios = File.open("#{dest_dir}/.htaccess", "w")
+                ios.write("AuthType Basic\nAuthName \"protected area\"\nAuthUserFile #{auth_user_file}\nrequire valid-user\n")
+                ios.close
+            end
+
             msg 3, _("\tgenerating HTML pages...")
 
             #- generate thumbnails.html (page with thumbnails)
diff --git a/data/booh/images/galeon-secure.png b/data/booh/images/galeon-secure.png
new file mode 100644 (file)
index 0000000..05b2ec3
Binary files /dev/null and b/data/booh/images/galeon-secure.png differ