Feature #2647 » svnpatch251_v3.patch
redmine-2.5.1-new/app/controllers/application_controller.rb 2014-06-03 22:19:00.306007981 +0200 | ||
---|---|---|
419 | 419 |
return false |
420 | 420 |
end |
421 | 421 | |
422 |
#by heagdl, added 2 error msgs |
|
423 |
def render_ad(options={}) |
|
424 |
render_error({:message => "Access to this repository denied! Please contact your system administrator for further information.", :status => 401}.merge(options)) |
|
425 |
return false |
|
426 |
end |
|
427 | ||
428 |
def render_rd(options={}) |
|
429 |
render_error({:message => "Access to this revision denied! You are not authorized to see the associated paths. Please contact your system administrator for further information.", :status => 401}.merge(options)) |
|
430 |
return false |
|
431 |
end |
|
432 | ||
422 | 433 |
# Renders an error response |
423 | 434 |
def render_error(arg) |
424 | 435 |
arg = {:message => arg} unless arg.is_a?(Hash) |
redmine-2.5.1-new/app/controllers/repositories_controller.rb 2014-06-04 02:21:26.728007983 +0200 | ||
---|---|---|
19 | 19 |
require 'SVG/Graph/BarHorizontal' |
20 | 20 |
require 'digest/sha1' |
21 | 21 |
require 'redmine/scm/adapters' |
22 |
require 'open3' #may be unused |
|
23 |
require 'svncheck' |
|
22 | 24 | |
23 | 25 |
class ChangesetNotFound < Exception; end |
24 | 26 |
class InvalidRevisionParam < Exception; end |
... | ... | |
32 | 34 |
before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] |
33 | 35 |
before_filter :find_project_repository, :except => [:new, :create, :edit, :update, :destroy, :committers] |
34 | 36 |
before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] |
37 |
before_filter :check_repo_access, :only => [:revision, :revisions, :show, :changes, :diff, :graph, :stats, :entry, :annotate, :raw] |
|
35 | 38 |
before_filter :authorize |
36 | 39 |
accept_rss_auth :revisions |
37 | 40 | |
... | ... | |
435 | 438 |
) |
436 | 439 |
graph.burn |
437 | 440 |
end |
441 | ||
442 |
#check if the current user is allowed to access the repository at the requested paths |
|
443 |
def check_repo_access |
|
444 |
if (@repository.type.eql? "Repository::Subversion") |
|
445 |
begin |
|
446 |
@svnchk = SVNCheck.new(@repository.url,@repository.root_url,User.current.login) |
|
447 |
if params[:action] == "revision" |
|
448 |
if !@svnchk.chkrev(@changeset.id) |
|
449 |
render_rd; return false |
|
450 |
end |
|
451 |
else |
|
452 |
if params[:path].nil? |
|
453 |
reqpath = "/" |
|
454 |
else |
|
455 |
reqpath = "/"+params[:path] |
|
456 |
end |
|
457 |
logger.info 'SVN-Request for following path: ' + reqpath |
|
458 |
if !(@svnchk.chkurl(reqpath)) |
|
459 |
render_ad; return false |
|
460 |
end |
|
461 |
end |
|
462 |
rescue Exception => e |
|
463 |
logger.fatal "An error occured during svnchk!" |
|
464 |
logger.info e.message |
|
465 |
end |
|
466 |
end |
|
467 |
end |
|
438 | 468 |
end |
redmine-2.5.1-new/app/helpers/application_helper.rb 2014-06-03 22:24:07.820007037 +0200 | ||
---|---|---|
771 | 771 |
:repository_id => repository.identifier_param, |
772 | 772 |
:rev => changeset.revision}, |
773 | 773 |
:class => 'changeset', |
774 |
:title => truncate_single_line_raw(changeset.comments, 100)) |
|
774 |
:title => if (repository.type.eql? "Repository::Subversion") |
|
775 |
require 'svncheck' |
|
776 |
svnc = SVNCheck.new(repository.url,repository.root_url,User.current.login) |
|
777 |
if !svnc.chkrev(changeset.id) |
|
778 |
"Access to this revision denied!" |
|
779 |
else |
|
780 |
truncate_single_line_raw(changeset.comments, 100) |
|
781 |
end |
|
782 |
else |
|
783 |
truncate_single_line_raw(changeset.comments, 100) |
|
784 |
end) |
|
775 | 785 |
end |
776 | 786 |
end |
777 | 787 |
elsif sep == '#' |
redmine-2.5.1-new/app/models/changeset.rb 2014-06-03 22:19:00.308007965 +0200 | ||
---|---|---|
267 | 267 |
comments =~ /\A(.+?)\r?\n(.*)$/m |
268 | 268 |
@short_comments = $1 || comments |
269 | 269 |
@long_comments = $2.to_s.strip |
270 |
#check if allowed to show by haegdl: |
|
271 |
if (repository.type.eql? "Repository::Subversion") |
|
272 |
require 'svncheck' |
|
273 |
svnc = SVNCheck.new(repository.url,repository.root_url,User.current.login) |
|
274 |
if !svnc.chkrev(id) |
|
275 |
@short_comments = "Access to this revision denied!" |
|
276 |
@long_comments = "You have no rights to access this path in your svn repository!" |
|
277 |
end |
|
278 |
end |
|
270 | 279 |
return @short_comments, @long_comments |
271 | 280 |
end |
272 | 281 |
redmine-2.5.1-new/lib/svncheck.rb 2014-06-04 02:22:59.513007752 +0200 | ||
---|---|---|
1 |
################################################# |
|
2 |
# INFO |
|
3 |
# |
|
4 |
# This file was written by Daniel Haeger (haegdl@idmt.fraunhofer.de) |
|
5 |
# Its a helper for checking if a user is permitted to access a SVN |
|
6 |
# repository protected by mod_authz_svn with path-based authz. |
|
7 |
# |
|
8 |
# In the same directory, a 'right to read' dominates a 'deny' |
|
9 |
# For initialisation, the paths to the authz file of the repo |
|
10 |
# and the user have to be specified! |
|
11 |
# |
|
12 |
# root_url is different that url if the svn should just |
|
13 |
# access a subdir! |
|
14 |
# |
|
15 |
# TODO |
|
16 |
# |
|
17 |
# -wrap it in begin.rescue.end blocks |
|
18 |
# -allow aliases |
|
19 |
# -logging instead of puts using STDERR.puts "error" ? |
|
20 |
# |
|
21 |
# Last edited: 13.10.14 13:37 |
|
22 |
# |
|
23 |
################################################## |
|
24 | ||
25 |
class SVNCheck |
|
26 |
def initialize(url, rooturl, user) |
|
27 |
puts "Started SVNCheck with:\n " + url + "\n " + rooturl + "\n " + user |
|
28 | ||
29 |
status = 0 |
|
30 |
currentpath = "" |
|
31 |
@user = user.dup |
|
32 |
@authzpath = rooturl.dup #"/opt/svn/systies_cp/conf/authz" |
|
33 |
if @authzpath.start_with?("file://") |
|
34 |
@authzpath.slice!("file://") #remove beginning (we need absolut path) |
|
35 |
end |
|
36 |
@authzpath = @authzpath.chomp("/") + "/conf/authz" |
|
37 | ||
38 |
usergroups = [] #all groups the user is in, groups have to be specified before beeing used |
|
39 |
@ap = [] #paths with allowed access |
|
40 |
@dp = [] #paths with denied access |
|
41 | ||
42 |
#set prefix path |
|
43 |
@urlprefix = "" #if repository is a svn subdirectory, we need a prefix to match paths from authz file |
|
44 | ||
45 |
#catch if rooturl.nil? (when repo is just created!) Add/Change your name below to be able to browse the svn for the first time!!!! |
|
46 |
if ((rooturl.size == 0) && !(user.eql?("haegdl") || user.eql?("admin"))) |
|
47 |
puts "ERROR during SVNCheck, rooturl is nil, please access the repo from admin/haegdl account to activate it!" |
|
48 |
else |
|
49 |
#set prefix if needed |
|
50 |
if url.length > rooturl.length |
|
51 |
@urlprefix = url.sub(rooturl, "") |
|
52 |
end |
|
53 |
|
|
54 |
File.open(@authzpath, "r") do |f| |
|
55 |
f.each_line do |line| |
|
56 |
line.gsub!(/\s+/, "") #.downcase! removes whitespace; lowercasing disabled! |
|
57 |
if !(line.empty? || (line[0,1] == "#") || (line[0,9] == "[aliases]")) #comments or empty lines shall not be processed |
|
58 |
nchanged = true #not changed; used to ignore section lines |
|
59 |
|
|
60 |
#section check |
|
61 |
if line[0,8] == '[groups]' then |
|
62 |
status = 1 #1=> group declaration |
|
63 |
nchanged = false |
|
64 |
elsif line[0,2] == '[/' then |
|
65 |
status = 2 # path check mode |
|
66 |
nchanged = false |
|
67 |
end |
|
68 |
|
|
69 |
#PLACE FOR STRING OPERATION |
|
70 |
case status |
|
71 |
when 1 #check for groups |
|
72 |
parts = line.split("=") |
|
73 |
if ( !(parts.empty?) && (parts.size == 2) && nchanged) |
|
74 |
if parts[1].split(",").include? user |
|
75 |
usergroups << "@" + parts[0] |
|
76 |
else |
|
77 |
#allow groups in group creation |
|
78 |
parts[1].split(",") do |x| |
|
79 |
if usergroups.include? x |
|
80 |
usergroups << parts[0] |
|
81 |
break |
|
82 |
end |
|
83 |
end |
|
84 |
end |
|
85 |
end |
|
86 |
when 2 |
|
87 |
if !(nchanged) |
|
88 |
#this line specifies path |
|
89 |
currentpath = line.gsub!(/[\[\]]/, "") |
|
90 |
else |
|
91 |
#3 checks: first: groups_allowed?; second: userallowed |
|
92 |
parts = line.split("=") |
|
93 |
if (!(parts.empty?) && (parts.size == 2)) |
|
94 |
#check groups |
|
95 |
if (usergroups.include? parts[0]) #name matches a group name the user is in |
|
96 |
case parts[1] |
|
97 |
when "rw", "wr", "r" |
|
98 |
@ap << currentpath |
|
99 |
when "w" |
|
100 |
puts "NOTE: just write-access, doing nothing!" |
|
101 |
else |
|
102 |
puts "ERROR, 2nd part could not be interpreted" + parts[1] |
|
103 |
end |
|
104 |
end |
|
105 |
#check explicit mentioned user |
|
106 |
if (parts[0].eql? user) #if username is mentiend |
|
107 |
case parts[1] |
|
108 |
when "rw", "wr", "r" |
|
109 |
@ap << currentpath |
|
110 |
when "w" |
|
111 |
puts "NOTE: just write-access, not implemented yet, doing nothing!" |
|
112 |
else |
|
113 |
puts "ERROR, 2nd Part could not be interpreited" + "###" + parts[1] + "###" |
|
114 |
end |
|
115 |
end |
|
116 |
#*= all user |
|
117 |
if (parts[0].eql? "*") |
|
118 |
case parts[1] |
|
119 |
when "rw", "wr", "r" |
|
120 |
@ap << currentpath |
|
121 |
when "w" |
|
122 |
puts "ERROR, not implemented yet!" |
|
123 |
else |
|
124 |
puts "ERROR, second part could not be interpreted" |
|
125 |
end |
|
126 |
end |
|
127 |
end |
|
128 |
#interpret denied access |
|
129 |
if (parts.size == 1) |
|
130 |
if ((parts[0].eql? user)|| (usergroups.include? parts[0]) || (parts[0].eql? "*") ) |
|
131 |
@dp << currentpath |
|
132 |
end |
|
133 |
end |
|
134 |
end |
|
135 |
else |
|
136 |
puts "ERROR!" |
|
137 |
end |
|
138 |
end |
|
139 |
end |
|
140 |
end |
|
141 |
end |
|
142 |
end |
|
143 |
|
|
144 |
# Erklaerung: |
|
145 |
# |
|
146 |
# Suche alle Pfade für die Richtlinien existieren, welche ein Teil des zu ueberpruefenden Pfades |
|
147 |
# sind und gleichzeitig fuer den Benutzer gelten (andere werden ignoriert!) |
|
148 |
# Bestimme den laengsten uebereinstimmenden Pfad fuer den es eine Regel gibt und wende sie an. |
|
149 | ||
150 |
def chk(chkurl) |
|
151 |
chkp = chkurl#.sub("/","") # @urlprefix + ... |
|
152 |
puts "PATH TO CHECK: " + chkp + " PREFIX IS: " + @urlprefix |
|
153 | ||
154 |
ap = @ap.dup |
|
155 |
dp = @dp.dup |
|
156 |
#remove tailing '/' |
|
157 |
(ap + dp).each do |s| |
|
158 |
if s.length > 1 |
|
159 |
s.chomp!("/") |
|
160 |
end |
|
161 |
end |
|
162 |
if chkp.length > 1 |
|
163 |
chkp.chomp!("/") |
|
164 |
end |
|
165 |
#just keep paths matching to the path we have to check |
|
166 |
dp.delete_if { |x| !dirorsubdir(chkp,x) } |
|
167 |
ap.delete_if { |x| !dirorsubdir(chkp,x) } |
|
168 |
puts "Authz rules found for following paths:" |
|
169 |
puts (ap + dp) |
|
170 |
path = (ap + dp).sort_by(&:length).reverse.first |
|
171 |
puts "Winner Path = " + path unless path.nil? |
|
172 |
|
|
173 |
if (path.nil? || path.eql?("")) |
|
174 |
puts "ACCESS DENIED! Checked path: " + chkp + " There is no rule for this person in the conf file!" |
|
175 |
return false |
|
176 |
else |
|
177 |
if ap.include?(path) |
|
178 |
#access granted! |
|
179 |
puts "ACCESS GRANTED! Checked path: " + chkp + " Allowed by read-rule in: "+ path |
|
180 |
return true |
|
181 |
end |
|
182 |
if dp.include?(path) |
|
183 |
#access denied! |
|
184 |
puts "ACCESS DENIED! Checked path: " + chkp + " Denied by rule in: " + path |
|
185 |
return false |
|
186 |
end |
|
187 |
end |
|
188 |
end |
|
189 | ||
190 |
def dirorsubdir(chkp, x) |
|
191 |
if chkp.start_with?(x) |
|
192 |
if ((chkp.length > x.length) && (chkp[x.length,1] == "/" )) |
|
193 |
#chkp is in directory x or one of its subdirs (recursiv) |
|
194 |
return true |
|
195 |
elsif chkp == x |
|
196 |
# path that was asked for |
|
197 |
return true |
|
198 |
elsif x == "/" |
|
199 |
#is always valid (check if other paths match better is solved by sorting in chk |
|
200 |
return true |
|
201 |
else |
|
202 |
#deny all other |
|
203 |
return false |
|
204 |
end |
|
205 |
else |
|
206 |
return false |
|
207 |
end |
|
208 |
end |
|
209 | ||
210 |
#resolve revisions to paths |
|
211 |
def chkrev(csetid) |
|
212 |
puts 'SVN-Request for Revision: ' + Changeset.find(csetid).revision |
|
213 |
changes = Change.where(changeset_id: csetid) |
|
214 |
changes.each do |x| |
|
215 |
if !(chk(x.path)) |
|
216 |
puts 'SVN-Request DENIED for ' + User.current.login |
|
217 |
return false |
|
218 |
end |
|
219 |
end |
|
220 |
#didnt returned false before -> no request denied |
|
221 |
puts 'SVN-Request ALLOWED for ' + User.current.login |
|
222 |
return true |
|
223 |
end |
|
224 | ||
225 |
def chkurl(url) |
|
226 |
#add prefix if svn-subdir (not needed @revisions) |
|
227 |
return chk(@urlprefix.chomp("/") + url) |
|
228 |
end |
|
229 | ||
230 |
end |
- « Previous
- 1
- …
- 4
- 5
- 6
- Next »