#!/usr/bin/env ruby # coding: utf-8 ############################################################################ # Copyright 2009-2019 Benjamin Kellermann # # # # This file is part of Dudle. # # # # Dudle is free software: you can redistribute it and/or modify it under # # the terms of the GNU Affero General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # Dudle is distributed in the hope that it will be useful, but WITHOUT ANY # # WARRANTY; without even the implied warranty of MERCHANTABILITY or # # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public # # License for more details. # # # # You should have received a copy of the GNU Affero General Public License # # along with dudle. If not, see <http://www.gnu.org/licenses/>. # ############################################################################ if __FILE__ == $0 load "../dudle.rb" require "digest" $d = Dudle.new acusers = {} File.open(".htdigest","r").each_line{|l| user,realm = l.scan(/^(.*):(.*):.*$/).flatten acusers[user] = realm } def write_htaccess(acusers) File.open(".htaccess","w"){|htaccess| if acusers.include?("admin") htaccess << <<HTACCESS <Files ~ "^(edit_columns|invite_participants|access_control|delete_poll).cgi$"> AuthType digest AuthName "dudle-#{$d.urlsuffix.gsub('"', '\\\\"')}" AuthUserFile "#{File.expand_path(".").gsub('"','\\\\"')}/.htdigest" Require user admin ErrorDocument 401 #{$cgi.script_name.gsub(/[^\/]*\/[^\/]*$/,"")}authorization_required.cgi?user=admin&poll=#{CGI.escape($d.urlsuffix)} </Files> HTACCESS end if acusers.include?("participant") htaccess << <<HTACCESS AuthType digest AuthName "dudle-#{$d.urlsuffix.gsub('"', '\\\\"')}" AuthUserFile "#{File.expand_path(".").gsub('"','\\\\"')}/.htdigest" Require valid-user ErrorDocument 401 #{$cgi.script_name.gsub(/[^\/]*\/[^\/]*$/,"")}authorization_required.cgi?user=participant&poll=#{CGI.escape($d.urlsuffix)} HTACCESS end } VCS.commit("Access Control changed") unless acusers.empty? $d.html.header["status"] = "REDIRECT" $d.html.header["Cache-Control"] = "no-cache" $d.html.header["Location"] = "access_control.cgi" end end def add_to_htdigest(user,password) File.open(".htdigest","a"){|f| f << "#{user}:dudle-#{$d.urlsuffix.gsub(':', '\\:')}:#{Digest::MD5.hexdigest("#{user}:dudle-#{$d.urlsuffix.gsub(':', '\\:')}:#{password}")}\n" } end def createform(userarray,hint,acusers) usernamestr = _("Username:") ret = <<FORM <form id='ac_#{userarray[0]}' method='post' action='' > <table class='settingstable'> <tr> <td class='label'>#{usernamestr}</td> <td title="#{userarray[1]}"> #{userarray[0]} <input type='hidden' name='ac_user' value='#{userarray[0]}' /> </td> </tr> FORM passwdstr = _("Password") repeatstr = _("repeat") 2.times{|i| ret += <<PASS <tr> <td class='label'><label for='password#{i}'>#{passwdstr}#{i == 1 ? " (#{repeatstr})" : ""}:</label></td> <td> PASS if acusers.include?(userarray[0]) ret += PASSWORDSTAR*14 else ret += "<input id='password#{i}' size='6' value='' type='password' name='ac_password#{i}' />" end ret += "</td></tr>" } ret += <<FORM <tr> <td></td> <td id='#{userarray[0]}hint' class='shorttextcolumn'>#{acusers.include?(userarray[0]) ? "" : hint}</td> </tr> <tr> <td></td> <td> FORM if acusers.include?(userarray[0]) if userarray[0] == "admin" && acusers.include?("participant") ret += "<div class='shorttextcolumn'>" + _("You have to remove the participant user before you can remove the administrator.") + "</div>" else ret += "<input type='hidden' name='ac_delete_#{userarray[0]}' value='Delete' />" ret += "<input type='submit' value='" + _("Delete") + "' />" end else ret += "<input type='hidden' name='ac_create' value='Save' />" ret += "<input type='submit' value='" + _("Save") + "' />" end ret += <<FORM <input type='hidden' name='ac_activate' value='Activate' /> </td> </tr> </table> </form> FORM ret end if $cgi.include?("ac_user") user = $cgi["ac_user"] if !(user =~ /^[\w]*$/) # add user usercreatenotice = "<div class='error'>" + _("Only letters and digits are allowed in the username.") + "</div>" elsif $cgi["ac_password0"] != $cgi["ac_password1"] usercreatenotice = "<div class='error'>" + _("Passwords did not match.") + "</div>" else if $cgi.include?("ac_create") add_to_htdigest(user,$cgi["ac_password0"]) acusers[user] = true write_htaccess(acusers) end # delete user deleteuser = "" acusers.each{|user,action| if $cgi.include?("ac_delete_#{user}") deleteuser = user end } acusers.delete(deleteuser) htdigest = [] File.open(".htdigest","r"){|file| htdigest = file.readlines } File.open(".htdigest","w"){|f| htdigest.each{|line| f << line unless line =~ /^#{deleteuser}:/ } } File.chmod(0600, ".htdigest") write_htaccess(acusers) end end $d.wizzard_redirect if $d.html.header["status"] != "REDIRECT" $d.html << "<h2>" + _("Change access control settings") + "</h2>" if acusers.empty? && $cgi["ac_activate"] != "Activate" acstatus = ["red",_("not activated")] acswitchbutton = "<input type='hidden' name='ac_activate' value='Activate' />" acswitchbutton += "<input type='submit' value='" + _("Activate") + "' />" else if acusers.empty? acstatus = ["blue",_("controls will be activated when at least the admin user is configured")] acswitchbutton = "<input type='hidden' name='ac_activate' value='Deactivate' />" acswitchbutton += "<input type='submit' value='" + _("Deactivate") + "' />" else acstatus = ["green", _("activated")] acswitchbutton = "<div class='shorttextcolumn'>" + _("You have to remove all users before you can deactivate the access control settings.") + "</div>" end admincreatenotice = usercreatenotice || _("You will be asked for the password you have entered here after you press save!") user = ["admin", _("The user ‘admin’ has access to both the vote and the configuration interface.")] createform = createform(user,admincreatenotice,acusers) if acusers.include?("admin") participantcreatenotice = usercreatenotice || "" user = ["participant", _("The user ‘participant’ only has access to the vote interface.")] createform += createform(user,participantcreatenotice,acusers) end end acstr = _("Access control:") $d.html << <<AC <form id='ac' method='post' action='' > <table class='settingstable'> <tr> <td> #{acstr} </td> <td style='color: #{acstatus[0]}'> #{acstatus[1]} </td> </tr> <tr> <td></td> <td> #{acswitchbutton} </td> </tr> </table> </form> #{createform} AC end $d.out end