Commit c43b289612b2420bc7e3c5faaf014b527ccace04

Authored by Dmitriy Zaporozhets
2 parents f1fc1ae6 92ef845f

Merge branch '6-0-dev' of /home/git/repositories/gitlab/gitlabhq

Showing 639 changed files with 7110 additions and 9282 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 639 files displayed.

CHANGELOG
  1 +v 6.0.0
  2 + - Epic: Replace teams with group membership
  3 + - Add project filter on dashboard
  4 + - cache project graph
  5 + - Drop support of root namespaces
  6 + - Redesign project settings navigation
  7 + - Restlyed login screen
  8 + - Default theme is classic now
  9 + - Cache result of methods like authorize_projects, project.team.members etc
  10 + - Remove $.ready events
  11 + - Fix onclick events being double binded
  12 + - Add notification level to group membership
  13 + - Move all project controllers/views under Projects:: module
  14 + - Move all profile controllers/views under Profiles:: module
  15 + - Redesign ssh keys page
  16 + - Generate fingerprint for ssh keys
  17 + - You an use arrows to navigate at tree view
  18 + - Apply user project limit only for personal projects
  19 +
1 20 v 5.4.0
2 21 - Ability to edit own comments
3 22 - Documentation improvements
... ...
Capfile.example
... ... @@ -1,4 +0,0 @@
1   -load 'deploy'
2   -load 'deploy/assets'
3   -require 'bundler/capistrano'
4   -load 'config/deploy'
Gemfile
... ... @@ -23,7 +23,7 @@ gem 'omniauth-github'
23 23  
24 24 # Extracting information from a git repository
25 25 # Provide access to Gitlab::Git library
26   -gem 'gitlab_git', '~> 1.3.0'
  26 +gem 'gitlab_git', '~> 1.4.1'
27 27  
28 28 # Ruby/Rack Git Smart-HTTP Server Handler
29 29 gem 'gitlab-grack', '~> 1.0.1', require: 'grack'
... ... @@ -35,7 +35,7 @@ gem 'gitlab_omniauth-ldap', '1.0.3', require: "omniauth-ldap"
35 35 gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
36 36  
37 37 # Git Wiki
38   -gem "gitlab-gollum-lib", "~> 1.0.0", require: 'gollum-lib'
  38 +gem "gitlab-gollum-lib", "~> 1.0.1", require: 'gollum-lib'
39 39  
40 40 # Language detection
41 41 gem "github-linguist", require: "linguist"
... ... @@ -173,7 +173,7 @@ group :development, :test do
173 173 gem 'factory_girl_rails'
174 174  
175 175 # Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
176   - gem 'minitest'
  176 + gem 'minitest', '~> 4.7.0'
177 177  
178 178 # Generate Fake data
179 179 gem "ffaker"
... ... @@ -203,5 +203,5 @@ group :test do
203 203 end
204 204  
205 205 group :production do
206   - gem "gitlab_meta", '5.0'
  206 + gem "gitlab_meta", '6.0'
207 207 end
... ...
Gemfile.lock
1 1 GIT
2 2 remote: https://github.com/ctran/annotate_models.git
3   - revision: 8bd159c7a484093fde84beaa9e6398f25ddacf09
  3 + revision: 18a4e2eb77c8f3ef695b563e4a7ca45dfede819b
4 4 specs:
5   - annotate (2.6.0.beta1)
  5 + annotate (2.6.0.beta2)
6 6 activerecord (>= 2.3.0)
7 7 rake (>= 0.8.7)
8 8  
... ... @@ -42,20 +42,20 @@ GEM
42 42 activesupport (3.2.13)
43 43 i18n (= 0.6.1)
44 44 multi_json (~> 1.0)
45   - acts-as-taggable-on (2.4.0)
46   - rails (~> 3.0)
  45 + acts-as-taggable-on (2.4.1)
  46 + rails (>= 3, < 5)
47 47 addressable (2.3.4)
48 48 arel (3.0.2)
49 49 asciidoctor (0.1.3)
50 50 awesome_print (1.1.0)
51   - backports (2.6.7)
  51 + backports (3.3.2)
52 52 bcrypt-ruby (3.0.1)
53   - better_errors (0.8.0)
  53 + better_errors (0.9.0)
54 54 coderay (>= 1.0.0)
55 55 erubis (>= 2.6.6)
56   - binding_of_caller (0.7.1)
  56 + binding_of_caller (0.7.2)
57 57 debug_inspector (>= 0.0.1)
58   - bootstrap-sass (2.3.1.0)
  58 + bootstrap-sass (2.3.2.0)
59 59 sass (~> 3.2)
60 60 builder (3.0.4)
61 61 capybara (2.1.0)
... ... @@ -67,7 +67,7 @@ GEM
67 67 carrierwave (0.8.0)
68 68 activemodel (>= 3.2.0)
69 69 activesupport (>= 3.2.0)
70   - celluloid (0.14.0)
  70 + celluloid (0.14.1)
71 71 timers (>= 1.0.0)
72 72 charlock_holmes (0.6.9.4)
73 73 childprocess (0.3.9)
... ... @@ -75,7 +75,7 @@ GEM
75 75 chosen-rails (0.9.8)
76 76 railties (~> 3.0)
77 77 thor (~> 0.14)
78   - code_analyzer (0.3.1)
  78 + code_analyzer (0.3.2)
79 79 sexp_processor
80 80 coderay (1.0.9)
81 81 coffee-rails (3.2.2)
... ... @@ -87,15 +87,16 @@ GEM
87 87 coffee-script-source (1.6.2)
88 88 colored (1.2)
89 89 colorize (0.5.8)
90   - connection_pool (1.0.0)
  90 + connection_pool (1.1.0)
91 91 coveralls (0.6.7)
92 92 colorize
93 93 multi_json (~> 1.3)
94 94 rest-client
95 95 simplecov (>= 0.7)
96 96 thor
97   - crack (0.3.2)
98   - d3_rails (3.1.4)
  97 + crack (0.4.0)
  98 + safe_yaml (~> 0.9.0)
  99 + d3_rails (3.1.10)
99 100 railties (>= 3.1.0)
100 101 daemons (1.1.9)
101 102 database_cleaner (1.0.1)
... ... @@ -107,11 +108,11 @@ GEM
107 108 railties (~> 3.1)
108 109 warden (~> 1.2.1)
109 110 diff-lcs (1.2.4)
110   - dotenv (0.7.0)
  111 + dotenv (0.8.0)
111 112 email_spec (1.4.0)
112 113 launchy (~> 2.1)
113 114 mail (~> 2.2)
114   - enumerize (0.5.1)
  115 + enumerize (0.6.1)
115 116 activesupport (>= 3.2)
116 117 erubis (2.7.0)
117 118 escape_utils (0.2.4)
... ... @@ -130,8 +131,8 @@ GEM
130 131 faraday (>= 0.7.4, < 0.9)
131 132 faye-websocket (0.4.7)
132 133 eventmachine (>= 0.12.0)
133   - ffaker (1.16.0)
134   - ffi (1.8.1)
  134 + ffaker (1.16.1)
  135 + ffi (1.9.0)
135 136 fog (1.3.1)
136 137 builder
137 138 excon (~> 0.13.0)
... ... @@ -157,17 +158,17 @@ GEM
157 158 pygments.rb (>= 0.2.13)
158 159 github-markdown (0.5.3)
159 160 github-markup (0.7.5)
160   - gitlab-gollum-lib (1.0.0)
  161 + gitlab-gollum-lib (1.0.1)
161 162 github-markdown (~> 0.5.3)
162 163 github-markup (>= 0.7.5, < 1.0.0)
163   - gitlab-grit (~> 2.5.1)
  164 + gitlab-grit (>= 2.5.1)
164 165 nokogiri (~> 1.5.9)
165 166 pygments.rb (~> 0.4.2)
166 167 sanitize (~> 2.0.3)
167 168 stringex (~> 1.5.1)
168 169 gitlab-grack (1.0.1)
169 170 rack (~> 1.4.1)
170   - gitlab-grit (2.5.1)
  171 + gitlab-grit (2.6.0)
171 172 charlock_holmes (~> 0.6.9)
172 173 diff-lcs (~> 1.1)
173 174 mime-types (~> 1.15)
... ... @@ -175,17 +176,17 @@ GEM
175 176 gitlab-pygments.rb (0.3.2)
176 177 posix-spawn (~> 0.3.6)
177 178 yajl-ruby (~> 1.1.0)
178   - gitlab_git (1.3.0)
  179 + gitlab_git (1.4.1)
179 180 activesupport (~> 3.2.13)
180 181 github-linguist (~> 2.3.4)
181   - gitlab-grit (~> 2.5.1)
182   - gitlab_meta (5.0)
  182 + gitlab-grit (~> 2.6.0)
  183 + gitlab_meta (6.0)
183 184 gitlab_omniauth-ldap (1.0.3)
184 185 net-ldap (~> 0.3.1)
185 186 omniauth (~> 1.0)
186 187 pyu-ruby-sasl (~> 0.0.3.1)
187 188 rubyntlm (~> 0.1.1)
188   - gon (4.1.0)
  189 + gon (4.1.1)
189 190 actionpack (>= 2.3.0)
190 191 json
191 192 grape (0.4.1)
... ... @@ -202,19 +203,19 @@ GEM
202 203 activesupport
203 204 multi_json (>= 1.3.2)
204 205 growl (1.0.3)
205   - guard (1.8.0)
  206 + guard (1.8.1)
206 207 formatador (>= 0.2.4)
207 208 listen (>= 1.0.0)
208 209 lumberjack (>= 1.0.2)
209 210 pry (>= 0.9.10)
210 211 thor (>= 0.14.6)
211   - guard-rspec (3.0.0)
  212 + guard-rspec (3.0.2)
212 213 guard (>= 1.8)
213 214 rspec (~> 2.13)
214 215 guard-spinach (0.0.2)
215 216 guard (>= 1.1)
216 217 spinach
217   - haml (4.0.2)
  218 + haml (4.0.3)
218 219 tilt
219 220 haml-rails (0.4)
220 221 actionpack (>= 3.1, < 4.1)
... ... @@ -222,9 +223,10 @@ GEM
222 223 haml (>= 3.1, < 4.1)
223 224 railties (>= 3.1, < 4.1)
224 225 hashie (1.2.0)
225   - hike (1.2.2)
  226 + hike (1.2.3)
226 227 hipchat (0.9.0)
227 228 httparty
  229 + httparty
228 230 http_parser.rb (0.5.3)
229 231 httparty (0.11.0)
230 232 multi_json (~> 1.0)
... ... @@ -255,18 +257,17 @@ GEM
255 257 actionpack (>= 3.0.0)
256 258 activesupport (>= 3.0.0)
257 259 kgio (2.8.0)
258   - launchy (2.2.0)
  260 + launchy (2.3.0)
259 261 addressable (~> 2.3)
260   - letter_opener (1.1.0)
261   - launchy (~> 2.2.0)
  262 + letter_opener (1.1.1)
  263 + launchy (~> 2.2)
262 264 libv8 (3.11.8.17)
263   - listen (1.1.3)
  265 + listen (1.2.2)
264 266 rb-fsevent (>= 0.9.3)
265 267 rb-inotify (>= 0.9)
266 268 rb-kqueue (>= 0.2)
267 269 lumberjack (1.0.3)
268   - mail (2.5.3)
269   - i18n (>= 0.4.0)
  270 + mail (2.5.4)
270 271 mime-types (~> 1.16)
271 272 treetop (~> 1.4.8)
272 273 method_source (0.8.1)
... ... @@ -274,15 +275,15 @@ GEM
274 275 minitest (4.7.4)
275 276 modernizr (2.6.2)
276 277 sprockets (~> 2.0)
277   - multi_json (1.7.3)
278   - multi_xml (0.5.3)
  278 + multi_json (1.7.7)
  279 + multi_xml (0.5.4)
279 280 multipart-post (1.2.0)
280 281 mysql2 (0.3.11)
281 282 net-ldap (0.3.1)
282 283 net-scp (1.0.4)
283 284 net-ssh (>= 1.99.1)
284 285 net-ssh (2.6.8)
285   - nokogiri (1.5.9)
  286 + nokogiri (1.5.10)
286 287 oauth (0.4.7)
287 288 oauth2 (0.8.1)
288 289 faraday (~> 0.8)
... ... @@ -296,7 +297,7 @@ GEM
296 297 omniauth-github (1.1.0)
297 298 omniauth (~> 1.0)
298 299 omniauth-oauth2 (~> 1.1)
299   - omniauth-google-oauth2 (0.1.17)
  300 + omniauth-google-oauth2 (0.1.19)
300 301 omniauth (~> 1.0)
301 302 omniauth-oauth2
302 303 omniauth-oauth (1.0.1)
... ... @@ -305,7 +306,7 @@ GEM
305 306 omniauth-oauth2 (1.1.1)
306 307 oauth2 (~> 0.8.0)
307 308 omniauth (~> 1.0)
308   - omniauth-twitter (0.0.16)
  309 + omniauth-twitter (0.0.17)
309 310 multi_json (~> 1.3)
310 311 omniauth-oauth (~> 1.0)
311 312 orm_adapter (0.4.0)
... ... @@ -354,7 +355,7 @@ GEM
354 355 rails-dev-tweaks (0.6.1)
355 356 actionpack (~> 3.1)
356 357 railties (~> 3.1)
357   - rails_best_practices (1.13.4)
  358 + rails_best_practices (1.13.8)
358 359 activesupport
359 360 awesome_print
360 361 code_analyzer
... ... @@ -370,7 +371,7 @@ GEM
370 371 rdoc (~> 3.4)
371 372 thor (>= 0.14.6, < 2.0)
372 373 raindrops (0.11.0)
373   - rake (10.0.4)
  374 + rake (10.1.0)
374 375 rb-fsevent (0.9.3)
375 376 rb-inotify (0.9.0)
376 377 ffi (>= 0.5.0)
... ... @@ -398,7 +399,7 @@ GEM
398 399 redis-store (~> 1.1.0)
399 400 redis-store (1.1.3)
400 401 redis (>= 2.2.0)
401   - ref (1.0.4)
  402 + ref (1.0.5)
402 403 rest-client (1.6.7)
403 404 mime-types (>= 1.16)
404 405 rspec (2.13.0)
... ... @@ -409,7 +410,7 @@ GEM
409 410 rspec-expectations (2.13.0)
410 411 diff-lcs (>= 1.1.3, < 2.0)
411 412 rspec-mocks (2.13.1)
412   - rspec-rails (2.13.1)
  413 + rspec-rails (2.13.2)
413 414 actionpack (>= 3.0)
414 415 activesupport (>= 3.0)
415 416 railties (>= 3.0)
... ... @@ -417,9 +418,10 @@ GEM
417 418 rspec-expectations (~> 2.13.0)
418 419 rspec-mocks (~> 2.13.0)
419 420 ruby-hmac (0.4.0)
420   - ruby-progressbar (1.0.2)
  421 + ruby-progressbar (1.1.1)
421 422 rubyntlm (0.1.1)
422 423 rubyzip (0.9.9)
  424 + safe_yaml (0.9.3)
423 425 sanitize (2.0.3)
424 426 nokogiri (>= 1.4.4, < 1.6)
425 427 sass (3.2.9)
... ... @@ -433,10 +435,10 @@ GEM
433 435 seed-fu (2.2.0)
434 436 activerecord (~> 3.1)
435 437 activesupport (~> 3.1)
436   - select2-rails (3.3.1)
437   - sass-rails (>= 3.2)
  438 + select2-rails (3.4.2)
  439 + sass-rails
438 440 thor (~> 0.14)
439   - selenium-webdriver (2.32.1)
  441 + selenium-webdriver (2.33.0)
440 442 childprocess (>= 0.2.5)
441 443 multi_json (~> 1.0)
442 444 rubyzip
... ... @@ -445,8 +447,8 @@ GEM
445 447 sexp_processor (4.2.1)
446 448 shoulda-matchers (2.1.0)
447 449 activesupport (>= 3.0.0)
448   - sidekiq (2.12.0)
449   - celluloid (>= 0.14.0)
  450 + sidekiq (2.12.4)
  451 + celluloid (>= 0.14.1)
450 452 connection_pool (>= 1.0.0)
451 453 json
452 454 redis (>= 3.0)
... ... @@ -456,23 +458,23 @@ GEM
456 458 multi_json (~> 1.0)
457 459 simplecov-html (~> 0.7.1)
458 460 simplecov-html (0.7.1)
459   - sinatra (1.3.6)
  461 + sinatra (1.4.3)
460 462 rack (~> 1.4)
461   - rack-protection (~> 1.3)
462   - tilt (~> 1.3, >= 1.3.3)
  463 + rack-protection (~> 1.4)
  464 + tilt (~> 1.3, >= 1.3.4)
463 465 six (0.2.0)
464   - slim (1.3.8)
465   - temple (~> 0.6.3)
466   - tilt (~> 1.3.3)
  466 + slim (2.0.0)
  467 + temple (~> 0.6.5)
  468 + tilt (~> 1.3, >= 1.3.3)
467 469 slop (3.4.5)
468   - spinach (0.8.2)
  470 + spinach (0.8.3)
469 471 colorize (= 0.5.8)
470 472 gherkin-ruby (~> 0.3.0)
471 473 spinach-rails (0.2.1)
472 474 capybara (>= 2.0.0)
473 475 railties (>= 3)
474 476 spinach (>= 0.4)
475   - spork (1.0.0rc3)
  477 + spork (1.0.0rc2)
476 478 sprockets (2.2.2)
477 479 hike (~> 1.2)
478 480 multi_json (~> 1.0)
... ... @@ -481,7 +483,7 @@ GEM
481 483 stamp (0.5.0)
482 484 state_machine (1.2.0)
483 485 stringex (1.5.1)
484   - temple (0.6.4)
  486 + temple (0.6.5)
485 487 test_after_commit (0.2.0)
486 488 therubyracer (0.11.4)
487 489 libv8 (~> 3.11.8.12)
... ... @@ -491,7 +493,7 @@ GEM
491 493 eventmachine (>= 0.12.6)
492 494 rack (>= 1.0.0)
493 495 thor (0.18.1)
494   - tilt (1.3.7)
  496 + tilt (1.4.1)
495 497 timers (1.1.0)
496 498 tinder (1.9.2)
497 499 eventmachine (~> 1.0)
... ... @@ -502,17 +504,17 @@ GEM
502 504 mime-types (~> 1.19)
503 505 multi_json (~> 1.5)
504 506 twitter-stream (~> 0.1)
505   - treetop (1.4.12)
  507 + treetop (1.4.14)
506 508 polyglot
507 509 polyglot (>= 0.3.1)
508   - turbolinks (1.1.1)
  510 + turbolinks (1.2.0)
509 511 coffee-rails
510 512 twitter-stream (0.1.16)
511 513 eventmachine (>= 0.12.8)
512 514 http_parser.rb (~> 0.5.1)
513 515 simple_oauth (~> 0.1.4)
514 516 tzinfo (0.3.37)
515   - uglifier (2.0.1)
  517 + uglifier (2.1.1)
516 518 execjs (>= 0.3.0)
517 519 multi_json (~> 1.0, >= 1.0.2)
518 520 underscore-rails (1.4.4)
... ... @@ -520,8 +522,8 @@ GEM
520 522 kgio (~> 2.6)
521 523 rack
522 524 raindrops (~> 0.7)
523   - virtus (0.5.4)
524   - backports (~> 2.6.1)
  525 + virtus (0.5.5)
  526 + backports (~> 3.3)
525 527 descendants_tracker (~> 0.0.1)
526 528 warden (1.2.1)
527 529 rack (>= 1.0)
... ... @@ -563,11 +565,11 @@ DEPENDENCIES
563 565 gemoji (~> 1.2.1)
564 566 github-linguist
565 567 github-markup (~> 0.7.4)
566   - gitlab-gollum-lib (~> 1.0.0)
  568 + gitlab-gollum-lib (~> 1.0.1)
567 569 gitlab-grack (~> 1.0.1)
568 570 gitlab-pygments.rb (~> 0.3.2)
569   - gitlab_git (~> 1.3.0)
570   - gitlab_meta (= 5.0)
  571 + gitlab_git (~> 1.4.1)
  572 + gitlab_meta (= 6.0)
571 573 gitlab_omniauth-ldap (= 1.0.3)
572 574 gon
573 575 grape (~> 0.4.1)
... ... @@ -586,7 +588,7 @@ DEPENDENCIES
586 588 kaminari (~> 0.14.1)
587 589 launchy
588 590 letter_opener
589   - minitest
  591 + minitest (~> 4.7.0)
590 592 modernizr (= 2.6.2)
591 593 mysql2
592 594 omniauth (~> 1.1.3)
... ...
Procfile
1   -web: bundle exec puma -p $PORT
  1 +web: bundle exec unicorn_rails -p $PORT -E development
2 2 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
... ...
VERSION
1   -5.4.0.rc1
  1 +6.0.0.pre
... ...
app/assets/images/login-logo.png

1.4 KB | W: | H:

9.97 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
app/assets/javascripts/blob.js.coffee 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +class BlobView
  2 + constructor: ->
  3 + # See if there are lines selected
  4 + # "#L12" and "#L34-56" supported
  5 + highlightBlobLines = ->
  6 + if window.location.hash isnt ""
  7 + matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
  8 + first_line = parseInt(matches?[1])
  9 + last_line = parseInt(matches?[3])
  10 +
  11 + unless isNaN first_line
  12 + last_line = first_line if isNaN(last_line)
  13 + $("#tree-content-holder .highlight .line").removeClass("hll")
  14 + $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
  15 + $("#L#{first_line}").ScrollTo()
  16 +
  17 + # Highlight the correct lines on load
  18 + highlightBlobLines()
  19 +
  20 + # Highlight the correct lines when the hash part of the URL changes
  21 + $(window).on 'hashchange', highlightBlobLines
  22 +
  23 +
  24 +@BlobView = BlobView
... ...
app/assets/javascripts/dashboard.js.coffee
... ... @@ -8,6 +8,22 @@ class Dashboard
8 8 @toggleFilter($(event.currentTarget))
9 9 @reloadActivities()
10 10  
  11 + $(".dash-filter").keyup ->
  12 + terms = $(this).val()
  13 + uiBox = $(this).parents('.ui-box').first()
  14 + if terms == "" || terms == undefined
  15 + uiBox.find(".dash-list li").show()
  16 + else
  17 + uiBox.find(".dash-list li").each (index) ->
  18 + name = $(this).find(".well-title").text()
  19 +
  20 + if name.toLowerCase().search(terms.toLowerCase()) == -1
  21 + $(this).hide()
  22 + else
  23 + $(this).show()
  24 +
  25 +
  26 +
11 27 reloadActivities: ->
12 28 $(".content_list").html ''
13 29 Pager.init 20, true
... ...
app/assets/javascripts/dispatcher.js.coffee
... ... @@ -16,20 +16,26 @@ class Dispatcher
16 16 path = page.split(':')
17 17  
18 18 switch page
19   - when 'issues:index'
  19 + when 'projects:issues:index'
20 20 Issues.init()
21 21 when 'dashboard:show'
22 22 new Dashboard()
23   - when 'commit:show'
  23 + when 'projects:commit:show'
24 24 new Commit()
25   - when 'groups:show', 'teams:show', 'projects:show'
  25 + when 'groups:show', 'projects:show'
26 26 Pager.init(20, true)
27 27 when 'projects:new', 'projects:edit'
28 28 new Project()
29   - when 'walls:show'
  29 + when 'projects:walls:show'
30 30 new Wall(project_id)
31   - when 'teams:members:index'
  31 + when 'projects:teams:members:index'
32 32 new TeamMembers()
  33 + when 'groups:people'
  34 + new GroupMembers()
  35 + when 'projects:tree:show'
  36 + new TreeView()
  37 + when 'projects:blob:show'
  38 + new BlobView()
33 39  
34 40 switch path.first()
35 41 when 'admin' then new Admin()
... ...
app/assets/javascripts/groups.js.coffee 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +class GroupMembers
  2 + constructor: ->
  3 + $('li.users_group').bind 'ajax:success', ->
  4 + $(this).fadeOut()
  5 +
  6 +@GroupMembers = GroupMembers
... ...
app/assets/javascripts/main.js.coffee
... ... @@ -50,11 +50,12 @@ window.startSpinner = -&gt;
50 50 window.stopSpinner = ->
51 51 $('.turbolink-spinner').fadeOut()
52 52  
53   -window.stopEndlessScroll = ->
  53 +window.unbindEvents = ->
54 54 $(document).unbind('scroll')
  55 + $(document).off('scroll')
55 56  
56 57 document.addEventListener("page:fetch", startSpinner)
57   -document.addEventListener("page:fetch", stopEndlessScroll)
  58 +document.addEventListener("page:fetch", unbindEvents)
58 59 document.addEventListener("page:receive", stopSpinner)
59 60  
60 61 $ ->
... ... @@ -66,7 +67,6 @@ $ -&gt;
66 67 $('.appear-data').fadeIn()
67 68 e.preventDefault()
68 69  
69   -
70 70 # Initialize chosen selects
71 71 $('select.chosen').chosen()
72 72  
... ... @@ -110,6 +110,10 @@ $ -&gt;
110 110 when 115
111 111 $("#search").focus()
112 112 e.preventDefault()
  113 + when 63
  114 + new Shortcuts()
  115 + e.preventDefault()
  116 +
113 117  
114 118 # Commit show suppressed diff
115 119 $(".supp_diff_link").bind "click", ->
... ...
app/assets/javascripts/notes.js
1 1 var NoteList = {
2   -
  2 + id: null,
3 3 notes_path: null,
4 4 target_params: null,
5 5 target_id: 0,
... ... @@ -16,6 +16,22 @@ var NoteList = {
16 16 // get initial set of notes
17 17 NoteList.getContent();
18 18  
  19 + // Unbind events to prevent firing twice
  20 + $(document).off("click", ".js-add-diff-note-button");
  21 + $(document).off("click", ".js-discussion-reply-button");
  22 + $(document).off("click", ".js-note-preview-button");
  23 + $(document).off("click", ".js-note-attachment-input");
  24 + $(document).off("click", ".js-close-discussion-note-form");
  25 + $(document).off("click", ".js-note-delete");
  26 + $(document).off("click", ".js-note-edit");
  27 + $(document).off("click", ".js-note-edit-cancel");
  28 + $(document).off("click", ".js-note-attachment-delete");
  29 + $(document).off("click", ".js-choose-note-attachment-button");
  30 + $(document).off("click", ".js-show-outdated-discussion");
  31 +
  32 + $(document).off("ajax:complete", ".js-main-target-form");
  33 +
  34 +
19 35 // add a new diff note
20 36 $(document).on("click",
21 37 ".js-add-diff-note-button",
... ...
app/assets/javascripts/shortcuts.js.coffee 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class Shortcuts
  2 + constructor: ->
  3 + if $('#modal-shortcuts').length > 0
  4 + $('#modal-shortcuts').modal('show')
  5 + else
  6 + $.ajax(
  7 + url: '/help/shortcuts',
  8 + dataType: "script"
  9 + )
  10 +
  11 +@Shortcuts = Shortcuts
... ...
app/assets/javascripts/stat_graph_contributors.js.coffee
... ... @@ -12,14 +12,35 @@ class window.ContributorsStatGraph
12 12 @master_graph.draw()
13 13 add_authors_graph: (author_data) ->
14 14 @authors = []
15   - _.each(author_data, (d) =>
  15 + limited_author_data = author_data.slice(0, 100)
  16 + _.each(limited_author_data, (d) =>
16 17 author_header = @create_author_header(d)
17 18 $(".contributors-list").append(author_header)
18 19 @authors[d.author] = author_graph = new ContributorsAuthorGraph(d.dates)
19 20 author_graph.draw()
20 21 )
21 22 format_author_commit_info: (author) ->
22   - author.commits + " commits " + author.additions + " ++ / " + author.deletions + " --"
  23 + commits = $('<span/>', {
  24 + class: 'graph-author-commits-count'
  25 + })
  26 + commits.text(author.commits + " commits")
  27 +
  28 + additions = $('<span/>', {
  29 + class: 'graph-additions'
  30 + })
  31 + additions.text(author.additions + " ++")
  32 +
  33 + deletions = $('<span/>', {
  34 + class: 'graph-deletions'
  35 + })
  36 + deletions.text(author.deletions + " --")
  37 +
  38 + $('<span/>').append(commits)
  39 + .append(" / ")
  40 + .append(additions)
  41 + .append(" / ")
  42 + .append(deletions)
  43 +
23 44 create_author_header: (author) ->
24 45 list_item = $('<li/>', {
25 46 class: 'person'
... ... @@ -30,7 +51,7 @@ class window.ContributorsStatGraph
30 51 class: 'commits'
31 52 })
32 53 author_commit_info = @format_author_commit_info(author)
33   - author_commit_info_span.text(author_commit_info)
  54 + author_commit_info_span.html(author_commit_info)
34 55 list_item.append(author_name)
35 56 list_item.append(author_commit_info_span)
36 57 list_item
... ... @@ -52,10 +73,10 @@ class window.ContributorsStatGraph
52 73 @field = field
53 74 change_date_header: ->
54 75 x_domain = ContributorsGraph.prototype.x_domain
55   - print_date_format = d3.time.format("%B %e %Y");
56   - print = print_date_format(x_domain[0]) + " - " + print_date_format(x_domain[1]);
57   - $("#date_header").text(print);
  76 + print_date_format = d3.time.format("%B %e %Y")
  77 + print = print_date_format(x_domain[0]) + " - " + print_date_format(x_domain[1])
  78 + $("#date_header").text(print)
58 79 redraw_author_commit_info: (author) ->
59 80 author_list_item = $(@authors[author.author].list_item)
60 81 author_commit_info = @format_author_commit_info(author)
61   - author_list_item.find("span").text(author_commit_info)
62 82 \ No newline at end of file
  83 + author_list_item.find("span").html(author_commit_info)
... ...
app/assets/javascripts/stat_graph_contributors_graph.js.coffee
... ... @@ -71,7 +71,7 @@ class window.ContributorsMasterGraph extends ContributorsGraph
71 71 super @width, @height
72 72 create_axes: ->
73 73 @x_axis = d3.svg.axis().scale(@x).orient("bottom")
74   - @y_axis = d3.svg.axis().scale(@y).orient("left")
  74 + @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5)
75 75 create_svg: ->
76 76 @svg = d3.select("#contributors-master").append("svg")
77 77 .attr("width", @width + @MARGIN.left + @MARGIN.right)
... ... @@ -130,8 +130,8 @@ class window.ContributorsAuthorGraph extends ContributorsGraph
130 130 create_scale: ->
131 131 super @width, @height
132 132 create_axes: ->
133   - @x_axis = d3.svg.axis().scale(@x).orient("bottom").tickFormat(d3.time.format("%m/%d"));
134   - @y_axis = d3.svg.axis().scale(@y).orient("left")
  133 + @x_axis = d3.svg.axis().scale(@x).orient("bottom").ticks(8)
  134 + @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5)
135 135 create_area: (x, y) ->
136 136 @area = d3.svg.area().x((d) ->
137 137 parseDate = d3.time.format("%Y-%m-%d").parse
... ... @@ -148,7 +148,7 @@ class window.ContributorsAuthorGraph extends ContributorsGraph
148 148 .append("g")
149 149 .attr("transform", "translate(" + @MARGIN.left + "," + @MARGIN.top + ")")
150 150 draw_path: (data) ->
151   - @svg.append("path").datum(data).attr("class", "area-contributor").attr("d", @area);
  151 + @svg.append("path").datum(data).attr("class", "area-contributor").attr("d", @area)
152 152 draw: ->
153 153 @create_scale()
154 154 @create_axes()
... ...
app/assets/javascripts/tree.js.coffee
1   -# Code browser tree slider
2   -# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
3   -$(".tree-content-holder .tree-item").live 'click', (e) ->
4   - if (e.target.nodeName != "A")
5   - path = $('.tree-item-file-name a', this).attr('href')
6   - Turbolinks.visit(path)
  1 +class TreeView
  2 + constructor: ->
  3 + @initKeyNav()
7 4  
8   -$ ->
9   - # Show the "Loading commit data" for only the first element
10   - $('span.log_loading:first').removeClass('hide')
  5 + # Code browser tree slider
  6 + # Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
  7 + $(".tree-content-holder .tree-item").on 'click', (e) ->
  8 + if (e.target.nodeName != "A")
  9 + path = $('.tree-item-file-name a', this).attr('href')
  10 + Turbolinks.visit(path)
11 11  
12   - # See if there are lines selected
13   - # "#L12" and "#L34-56" supported
14   - highlightBlobLines = ->
15   - if window.location.hash isnt ""
16   - matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
17   - first_line = parseInt(matches?[1])
18   - last_line = parseInt(matches?[3])
  12 + # Show the "Loading commit data" for only the first element
  13 + $('span.log_loading:first').removeClass('hide')
19 14  
20   - unless isNaN first_line
21   - last_line = first_line if isNaN(last_line)
22   - $("#tree-content-holder .highlight .line").removeClass("hll")
23   - $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
24   - $("#L#{first_line}").ScrollTo()
  15 + initKeyNav: ->
  16 + li = $("tr.tree-item")
  17 + liSelected = null
  18 + $('body').keydown (e) ->
  19 + if e.which is 40
  20 + if liSelected
  21 + next = liSelected.next()
  22 + if next.length > 0
  23 + liSelected.removeClass "selected"
  24 + liSelected = next.addClass("selected")
  25 + else
  26 + liSelected = li.eq(0).addClass("selected")
25 27  
26   - # Highlight the correct lines on load
27   - highlightBlobLines()
28   - # Highlight the correct lines when the hash part of the URL changes
29   - $(window).on 'hashchange', highlightBlobLines
  28 + $(liSelected).focus()
  29 + else if e.which is 38
  30 + if liSelected
  31 + next = liSelected.prev()
  32 + if next.length > 0
  33 + liSelected.removeClass "selected"
  34 + liSelected = next.addClass("selected")
  35 + else
  36 + liSelected = li.last().addClass("selected")
  37 +
  38 + $(liSelected).focus()
  39 + else if e.which is 13
  40 + path = $('.tree-item.selected .tree-item-file-name a').attr('href')
  41 + Turbolinks.visit(path)
  42 +
  43 +@TreeView = TreeView
... ...
app/assets/stylesheets/common.scss
... ... @@ -206,17 +206,6 @@ p.time {
206 206 }
207 207 }
208 208  
209   -.arrow{
210   - background: #E3E5EA;
211   - padding: 5px;
212   - margin-top: 5px;
213   - @include border-radius(5px);
214   - text-shadow: none;
215   - color: #999;
216   - line-height: 16px;
217   - font-weight: bold;
218   -}
219   -
220 209 .thin_area{
221 210 height: 150px;
222 211 }
... ... @@ -311,14 +300,17 @@ li.note {
311 300 }
312 301 }
313 302  
314   -.error_message {
315   - @extend .cred;
316   - border-left: 4px solid #E99;
  303 +.error-message {
317 304 padding: 10px;
318   - margin-bottom: 10px;
319   - background: #FEE;
  305 + background: #C67;
320 306 padding-left: 20px;
  307 + margin: 0;
  308 + color: #FFF;
321 309  
  310 + a {
  311 + color: #fff;
  312 + text-decoration: underline;
  313 + }
322 314 &.centered {
323 315 text-align: center;
324 316 }
... ...
app/assets/stylesheets/gitlab_bootstrap/common.scss
... ... @@ -87,3 +87,10 @@ fieldset legend { font-size: 17px; }
87 87 color: #333;
88 88 text-shadow: 0 1px 1px #FFF;
89 89 }
  90 +
  91 +pre.well-pre {
  92 + border: 1px solid #EEE;
  93 + background: #f9f9f9;
  94 + border-radius: 0;
  95 + color: #555;
  96 +}
... ...
app/assets/stylesheets/gitlab_bootstrap/lists.scss
... ... @@ -16,6 +16,12 @@
16 16 color: #888;
17 17 }
18 18  
  19 + &.unstyled {
  20 + &:hover {
  21 + background: none;
  22 + }
  23 + }
  24 +
19 25 &.smoke { background-color: #f5f5f5; }
20 26  
21 27 &:hover {
... ...
app/assets/stylesheets/gitlab_bootstrap/nav.scss
... ... @@ -22,6 +22,13 @@
22 22 color: $style_color;
23 23 font-weight: bold;
24 24 }
  25 +
  26 + &.nav-stacked-menu {
  27 + background: #FAFAFA;
  28 + li > a {
  29 + padding: 20px;
  30 + }
  31 + }
25 32 }
26 33 }
27 34  
... ...
app/assets/stylesheets/sections/dashboard.scss
... ... @@ -7,28 +7,13 @@
7 7 @extend .pull-right;
8 8  
9 9 .ui-box {
10   - margin: 3px;
  10 + margin: 0px;
  11 + box-shadow: none;
  12 +
11 13 > .title {
12 14 padding: 2px 15px;
13 15 }
14 16 .nav-projects-tabs li { padding: 0; }
15   - .well-list {
16   - li { padding: 15px; }
17   - .arrow {
18   - float: right;
19   - padding: 10px;
20   - margin: 0;
21   - }
22   - .last_activity {
23   - padding-top: 5px;
24   - display: block;
25   - span, strong {
26   - font-size: 12px;
27   - color: #666;
28   - }
29   - }
30   - }
31   - @extend .ui-box;
32 17 }
33 18 }
34 19 }
... ... @@ -46,3 +31,72 @@
46 31 }
47 32 }
48 33  
  34 +.dashboard {
  35 + .dash-filter {
  36 + margin: 0;
  37 + padding: 4px 6px;
  38 + width: 202px;
  39 + float: left;
  40 + margin-top: 3px;
  41 + margin-left: -2px;
  42 + }
  43 +}
  44 +
  45 +@media (max-width: 1200px) {
  46 + .dashboard .dash-filter {
  47 + width: 132px;
  48 + }
  49 +}
  50 +
  51 +.dash-sidebar-tabs {
  52 + margin-bottom: 2px;
  53 + border: none;
  54 + margin: 0;
  55 +
  56 + li {
  57 + &.active {
  58 + a {
  59 + @include linear-gradient(#f5f5f5, #eee);
  60 + border-bottom: 1px solid #EEE !important;
  61 + &:hover {
  62 + background: #eee;
  63 + }
  64 + }
  65 + }
  66 +
  67 + a {
  68 + border-color: #CCC !important;
  69 + }
  70 + }
  71 +}
  72 +
  73 +.project-row, .group-row {
  74 + padding: 15px !important;
  75 +
  76 + .namespace-name {
  77 + color: #666;
  78 + font-weight: bold;
  79 + }
  80 +
  81 + .project-name, .group-name {
  82 + font-size: 16px;
  83 + }
  84 +
  85 +
  86 + .arrow {
  87 + float: right;
  88 + padding: 10px 5px;
  89 + margin: 0;
  90 + font-size: 20px;
  91 + color: #666;
  92 + }
  93 +
  94 + .last-activity, .owner-info {
  95 + color: #AAA;
  96 + display: block;
  97 + margin-top: 5px;
  98 + .date, .owner {
  99 + color: #777;
  100 + }
  101 + }
  102 +}
... ...
app/assets/stylesheets/sections/events.scss
... ... @@ -41,6 +41,8 @@
41 41 }
42 42 }
43 43 .event-body {
  44 + margin-left: 35px;
  45 +
44 46 .commit p {
45 47 color: #666;
46 48 padding-top: 5px;
... ... @@ -51,7 +53,6 @@
51 53 .event-note {
52 54 color: #555;
53 55 margin-top: 5px;
54   - margin-left: 40px;
55 56  
56 57 pre {
57 58 border: none;
... ... @@ -77,10 +78,6 @@
77 78 margin-right: 5px;
78 79 }
79 80 }
80   - .avatar {
81   - position: relative;
82   - top: -3px;
83   - }
84 81 .event_icon {
85 82 position: relative;
86 83 float: right;
... ... @@ -95,11 +92,10 @@
95 92 }
96 93 }
97 94 ul {
98   - margin-left: 50px;
99 95 margin-bottom: 5px;
100 96 .avatar {
101 97 width: 18px;
102   - margin-top: 3px;
  98 + margin: 2px 4px;
103 99 }
104 100 }
105 101  
... ... @@ -118,7 +114,12 @@
118 114 }
119 115 &.commits-stat {
120 116 display: block;
121   - margin-top: 5px;
  117 + padding: 3px;
  118 + margin-top: 3px;
  119 +
  120 + &:hover {
  121 + background: none;
  122 + }
122 123 }
123 124 }
124 125 }
... ...
app/assets/stylesheets/sections/graph.scss
1   -.graph_holder {
  1 +.graph_holder {
2 2 border: 1px solid #aaa;
3 3 padding: 1px;
4 4  
5 5  
6   - h4 {
  6 + h4 {
7 7 padding: 0 10px;
8 8 border-bottom: 1px solid #bbb;
9 9 @include bg-gray-gradient;
10 10 }
11 11  
12   - .graph {
  12 + .graph {
13 13 background: #f1f1f1;
14 14 height: 500px;
15 15 overflow-y: scroll;
... ... @@ -17,3 +17,16 @@
17 17 }
18 18 }
19 19  
  20 +.graphs {
  21 + .graph-author-commits-count {
  22 + }
  23 +
  24 + .graph-additions {
  25 + color: #4a2;
  26 + }
  27 +
  28 + .graph-deletions {
  29 + color: #d12f19;
  30 + }
  31 +}
  32 +
... ...
app/assets/stylesheets/sections/header.scss
... ... @@ -120,7 +120,7 @@ header {
120 120 border-bottom: 1px solid #AAA;
121 121  
122 122 .nav > li > a {
123   - color: #DDD;
  123 + color: #AAA;
124 124 text-shadow: 0 1px 0 #444;
125 125  
126 126 &:hover {
... ... @@ -130,6 +130,10 @@ header {
130 130 }
131 131 }
132 132  
  133 + .turbolink-spinner {
  134 + color: #FFF;
  135 + }
  136 +
133 137 .search {
134 138 .search-input {
135 139 background-color: #D2D5DA;
... ... @@ -156,7 +160,10 @@ header {
156 160 }
157 161 .project_name {
158 162 a {
159   - color: #FFF;
  163 + color: #DDD;
  164 + &:hover {
  165 + color: #FFF;
  166 + }
160 167 }
161 168 color: #fff;
162 169 text-shadow: 0 1px 1px #444;
... ...
app/assets/stylesheets/sections/login.scss
1 1 /* Login Page */
2 2 body.login-page{
3   - background: #EEE;
  3 + background: #474D57;
4 4 .container .content { padding-top: 5%; }
5 5 }
6 6  
... ...
app/assets/stylesheets/sections/nav.scss
1 1 .main-nav {
  2 + background: #f5f5f5;
2 3 margin: 30px 0;
3   - margin-top: 10px;
  4 + margin-top: 0;
  5 + padding-top: 4px;
4 6 border-bottom: 1px solid #E1E1E1;
5 7  
6 8 ul {
7 9 margin: auto;
8   - height: 39px;
9   - position: relative;
10   - top: 3px;
  10 + height: 40px;
11 11 overflow: hidden;
12 12 .count {
13 13 font-weight: normal;
... ... @@ -33,10 +33,29 @@
33 33 display: table-cell;
34 34 width: 1%;
35 35 &.active {
36   - border-bottom: 3px solid #777;
37 36 a {
38 37 color: $style_color;
39 38 font-weight: bolder;
  39 +
  40 + &:after {
  41 + content: '';
  42 + display: block;
  43 + position: relative;
  44 + bottom: 8px;
  45 + left: 50%;
  46 + width: 0;
  47 + height: 0;
  48 + border-color: transparent transparent #777 transparent;
  49 + border-style: solid;
  50 + border-width: 6px;
  51 + margin-left: -6px;
  52 + }
  53 + }
  54 + }
  55 +
  56 + &:hover {
  57 + a {
  58 + color: $style_color;
40 59 }
41 60 }
42 61  
... ... @@ -54,11 +73,13 @@
54 73 display: block;
55 74 text-align: center;
56 75 font-weight: normal;
57   - height: 36px;
  76 + height: 38px;
58 77 line-height: 34px;
59 78 color: #777;
60 79 text-shadow: 0 1px 1px white;
61 80 padding: 0 10px;
  81 + text-decoration: none;
  82 + padding-top: 2px;
62 83 }
63 84 }
64 85 }
... ...
app/assets/stylesheets/sections/themes.scss
... ... @@ -27,15 +27,15 @@
27 27 }
28 28  
29 29 &.modern {
30   - background: #567;
  30 + background: #345;
31 31 }
32 32  
33 33 &.gray {
34   - background: #708090;
  34 + background: #373737;
35 35 }
36 36  
37 37 &.violet {
38   - background: #657;
  38 + background: #547;
39 39 }
40 40 }
41 41 }
... ...
app/assets/stylesheets/sections/tree.scss
... ... @@ -23,6 +23,14 @@
23 23 }
24 24 cursor: pointer;
25 25 }
  26 +
  27 + &.selected {
  28 + td {
  29 + background: $hover;
  30 + border-top: 1px solid #ADF;
  31 + border-bottom: 1px solid #ADF;
  32 + }
  33 + }
26 34 }
27 35 }
28 36  
... ...
app/assets/stylesheets/themes/ui_basic.scss
... ... @@ -8,4 +8,8 @@
8 8 background: #F9F9F9;
9 9 border-left: 1px solid #DDD;
10 10 }
  11 +
  12 + .main-nav {
  13 + background: #FFF;
  14 + }
11 15 }
... ...
app/assets/stylesheets/themes/ui_color.scss
... ... @@ -16,15 +16,15 @@
16 16 @extend .header-dark;
17 17 &.navbar-gitlab {
18 18 .navbar-inner {
19   - background: #657;
  19 + background: #547;
20 20 .app_logo {
21 21 &:hover {
22   - background-color: #6A5A7A;
  22 + background-color: #435;
23 23 }
24 24 }
25 25 .separator {
26   - background: #546;
27   - border-left: 1px solid #706080;
  26 + background: #435;
  27 + border-left: 1px solid #658;
28 28 }
29 29 }
30 30 }
... ...
app/assets/stylesheets/themes/ui_gray.scss
... ... @@ -16,15 +16,15 @@
16 16 @extend .header-dark;
17 17 &.navbar-gitlab {
18 18 .navbar-inner {
19   - background: #708090;
  19 + background: #373737;
20 20 .app_logo {
21 21 &:hover {
22   - background-color: #6A7A8A;
  22 + background-color: #272727;
23 23 }
24 24 }
25 25 .separator {
26   - background: #607080;
27   - border-left: 1px solid #8090A0;
  26 + background: #272727;
  27 + border-left: 1px solid #474747;
28 28 }
29 29 }
30 30 }
... ...
app/assets/stylesheets/themes/ui_modern.scss
... ... @@ -16,15 +16,15 @@
16 16 @extend .header-dark;
17 17 &.navbar-gitlab {
18 18 .navbar-inner {
19   - background: #567;
  19 + background: #345;
20 20 .app_logo {
21 21 &:hover {
22   - background-color: #516171;
  22 + background-color: #234;
23 23 }
24 24 }
25 25 .separator {
26   - background: #456;
27   - border-left: 1px solid #678;
  26 + background: #234;
  27 + border-left: 1px solid #456;
28 28 }
29 29 }
30 30 }
... ...
app/contexts/projects/create_context.rb
... ... @@ -33,7 +33,7 @@ module Projects
33 33 # Find matching namespace and check if it allowed
34 34 # for current user if namespace_id passed.
35 35 if allowed_namespace?(current_user, namespace_id)
36   - @project.namespace_id = namespace_id unless namespace_id == Namespace.global_id
  36 + @project.namespace_id = namespace_id
37 37 else
38 38 deny_namespace
39 39 return @project
... ... @@ -48,6 +48,7 @@ module Projects
48 48 # Import project from cloneable resource
49 49 if @project.valid? && @project.import_url.present?
50 50 shell = Gitlab::Shell.new
  51 +
51 52 if shell.import_repository(@project.path_with_namespace, @project.import_url)
52 53 # We should create satellite for imported repo
53 54 @project.satellite.create unless @project.satellite.exists?
... ... @@ -59,7 +60,11 @@ module Projects
59 60 end
60 61  
61 62 if @project.save
62   - @project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
  63 + unless @project.group
  64 + @project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
  65 + end
  66 +
  67 + @project.discover_default_branch
63 68 end
64 69  
65 70 @project
... ... @@ -75,12 +80,8 @@ module Projects
75 80 end
76 81  
77 82 def allowed_namespace?(user, namespace_id)
78   - if namespace_id == Namespace.global_id
79   - return user.admin
80   - else
81   - namespace = Namespace.find_by_id(namespace_id)
82   - current_user.can?(:manage_namespace, namespace)
83   - end
  83 + namespace = Namespace.find_by_id(namespace_id)
  84 + current_user.can?(:manage_namespace, namespace)
84 85 end
85 86 end
86 87 end
... ...
app/contexts/projects/transfer_context.rb
... ... @@ -5,12 +5,7 @@ module Projects
5 5 allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
6 6  
7 7 if allowed_transfer && namespace_id.present?
8   - if namespace_id == Namespace.global_id
9   - if project.namespace.present?
10   - # Transfer to global namespace from anyone
11   - project.transfer(nil)
12   - end
13   - elsif namespace_id.to_i != project.namespace_id
  8 + if namespace_id.to_i != project.namespace_id
14 9 # Transfer to someone namespace
15 10 namespace = Namespace.find(namespace_id)
16 11 project.transfer(namespace)
... ...
app/controllers/admin/groups_controller.rb
... ... @@ -25,7 +25,7 @@ class Admin::GroupsController &lt; Admin::ApplicationController
25 25 if @group.save
26 26 redirect_to [:admin, @group], notice: 'Group was successfully created.'
27 27 else
28   - render action: "new"
  28 + render "new"
29 29 end
30 30 end
31 31  
... ... @@ -34,42 +34,23 @@ class Admin::GroupsController &lt; Admin::ApplicationController
34 34 owner_id =group_params.delete(:owner_id)
35 35  
36 36 if owner_id
37   - @group.owner = User.find(owner_id)
  37 + @group.change_owner(User.find(owner_id))
38 38 end
39 39  
40 40 if @group.update_attributes(group_params)
41 41 redirect_to [:admin, @group], notice: 'Group was successfully updated.'
42 42 else
43   - render action: "edit"
  43 + render "edit"
44 44 end
45 45 end
46 46  
47   - def project_update
48   - project_ids = params[:project_ids]
49   -
50   - Project.where(id: project_ids).each do |project|
51   - project.transfer(@group)
52   - end
53   -
54   - redirect_to :back, notice: 'Group was successfully updated.'
55   - end
56   -
57   - def remove_project
58   - @project = Project.find(params[:project_id])
59   - @project.transfer(nil)
60   -
61   - redirect_to :back, notice: 'Group was successfully updated.'
62   - end
63   -
64 47 def project_teams_update
65   - @group.add_users_to_project_teams(params[:user_ids].split(','), params[:project_access])
  48 + @group.add_users(params[:user_ids].split(','), params[:group_access])
66 49  
67 50 redirect_to [:admin, @group], notice: 'Users were successfully added.'
68 51 end
69 52  
70 53 def destroy
71   - @group.truncate_teams
72   -
73 54 @group.destroy
74 55  
75 56 redirect_to admin_groups_path, notice: 'Group was successfully deleted.'
... ...
app/controllers/admin/members_controller.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class Admin::MembersController < Admin::ApplicationController
  2 + def destroy
  3 + user = User.find_by_username(params[:id])
  4 + project = Project.find_with_namespace(params[:project_id])
  5 + project.users_projects.where(user_id: user).first.destroy
  6 +
  7 + redirect_to :back
  8 + end
  9 +end
... ...
app/controllers/admin/projects/application_controller.rb
... ... @@ -1,11 +0,0 @@
1   -# Provides a base class for Admin controllers to subclass
2   -#
3   -# Automatically sets the layout and ensures an administrator is logged in
4   -class Admin::Projects::ApplicationController < Admin::ApplicationController
5   -
6   - protected
7   -
8   - def project
9   - @project ||= Project.find_with_namespace(params[:project_id])
10   - end
11   -end
app/controllers/admin/projects/members_controller.rb
... ... @@ -1,32 +0,0 @@
1   -class Admin::Projects::MembersController < Admin::Projects::ApplicationController
2   - def edit
3   - @member = team_member
4   - @project = project
5   - @team_member_relation = team_member_relation
6   - end
7   -
8   - def update
9   - if team_member_relation.update_attributes(params[:team_member])
10   - redirect_to [:admin, project], notice: 'Project Access was successfully updated.'
11   - else
12   - render action: "edit"
13   - end
14   - end
15   -
16   - def destroy
17   - team_member_relation.destroy
18   -
19   - redirect_to :back
20   - end
21   -
22   - private
23   -
24   - def team_member
25   - @member ||= project.users.find_by_username(params[:id])
26   - end
27   -
28   - def team_member_relation
29   - team_member.users_projects.find_by_project_id(project)
30   - end
31   -
32   -end
app/controllers/admin/projects_controller.rb
... ... @@ -9,13 +9,13 @@ class Admin::ProjectsController &lt; Admin::ApplicationController
9 9 @projects = @projects.where(public: true) if params[:public_only].present?
10 10 @projects = @projects.with_push if params[:with_push].present?
11 11 @projects = @projects.abandoned if params[:abandoned].present?
12   - @projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id
13 12 @projects = @projects.search(params[:name]) if params[:name].present?
14 13 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
15 14 end
16 15  
17 16 def show
18 17 @repository = @project.repository
  18 + @group = @project.group
19 19 end
20 20  
21 21 protected
... ...
app/controllers/admin/teams/application_controller.rb
... ... @@ -1,11 +0,0 @@
1   -# Provides a base class for Admin controllers to subclass
2   -#
3   -# Automatically sets the layout and ensures an administrator is logged in
4   -class Admin::Teams::ApplicationController < Admin::ApplicationController
5   -
6   - private
7   -
8   - def user_team
9   - @team = UserTeam.find_by_path(params[:team_id])
10   - end
11   -end
app/controllers/admin/teams/members_controller.rb
... ... @@ -1,40 +0,0 @@
1   -class Admin::Teams::MembersController < Admin::Teams::ApplicationController
2   - def new
3   - @users = User.potential_team_members(user_team)
4   - end
5   -
6   - def create
7   - unless params[:user_ids].blank?
8   - user_ids = params[:user_ids]
9   - access = params[:default_project_access]
10   - is_admin = params[:group_admin]
11   - user_team.add_members(user_ids, access, is_admin)
12   - end
13   -
14   - redirect_to admin_team_path(user_team), notice: 'Members were successfully added into Team of users.'
15   - end
16   -
17   - def edit
18   - team_member
19   - end
20   -
21   - def update
22   - options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]}
23   - if user_team.update_membership(team_member, options)
24   - redirect_to admin_team_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
25   - else
26   - render :edit
27   - end
28   - end
29   -
30   - def destroy
31   - user_team.remove_member(team_member)
32   - redirect_to admin_team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users."
33   - end
34   -
35   - protected
36   -
37   - def team_member
38   - @member ||= user_team.members.find_by_username(params[:id])
39   - end
40   -end
app/controllers/admin/teams/projects_controller.rb
... ... @@ -1,41 +0,0 @@
1   -class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController
2   - def new
3   - @projects = Project.scoped
4   - @projects = @projects.without_team(user_team) if user_team.projects.any?
5   - #@projects.reject!(&:empty_repo?)
6   - end
7   -
8   - def create
9   - unless params[:project_ids].blank?
10   - project_ids = params[:project_ids]
11   - access = params[:greatest_project_access]
12   - user_team.assign_to_projects(project_ids, access)
13   - end
14   -
15   - redirect_to admin_team_path(user_team), notice: 'Team of users was successfully assigned to projects.'
16   - end
17   -
18   - def edit
19   - team_project
20   - end
21   -
22   - def update
23   - if user_team.update_project_access(team_project, params[:greatest_project_access])
24   - redirect_to admin_team_path(user_team), notice: 'Access was successfully updated.'
25   - else
26   - render :edit
27   - end
28   - end
29   -
30   - def destroy
31   - user_team.resign_from_project(team_project)
32   - redirect_to admin_team_path(user_team), notice: 'Team of users was successfully reassigned from project.'
33   - end
34   -
35   - protected
36   -
37   - def team_project
38   - @project ||= user_team.projects.find_with_namespace(params[:id])
39   - end
40   -
41   -end
app/controllers/admin/teams_controller.rb
... ... @@ -1,59 +0,0 @@
1   -class Admin::TeamsController < Admin::ApplicationController
2   - def index
3   - @teams = UserTeam.order('name ASC')
4   - @teams = @teams.search(params[:name]) if params[:name].present?
5   - @teams = @teams.page(params[:page]).per(20)
6   - end
7   -
8   - def show
9   - user_team
10   - end
11   -
12   - def new
13   - @team = UserTeam.new
14   - end
15   -
16   - def edit
17   - user_team
18   - end
19   -
20   - def create
21   - @team = UserTeam.new(params[:user_team])
22   - @team.path = @team.name.dup.parameterize if @team.name
23   - @team.owner = current_user
24   -
25   - if @team.save
26   - redirect_to admin_team_path(@team), notice: 'Team of users was successfully created.'
27   - else
28   - render action: "new"
29   - end
30   - end
31   -
32   - def update
33   - user_team_params = params[:user_team].dup
34   - owner_id = user_team_params.delete(:owner_id)
35   -
36   - if owner_id
37   - user_team.owner = User.find(owner_id)
38   - end
39   -
40   - if user_team.update_attributes(user_team_params)
41   - redirect_to admin_team_path(user_team), notice: 'Team of users was successfully updated.'
42   - else
43   - render action: "edit"
44   - end
45   - end
46   -
47   - def destroy
48   - user_team.destroy
49   -
50   - redirect_to admin_teams_path, notice: 'Team of users was successfully deleted.'
51   - end
52   -
53   - protected
54   -
55   - def user_team
56   - @team ||= UserTeam.find_by_path(params[:id])
57   - end
58   -
59   -end
app/controllers/admin/users_controller.rb
1 1 class Admin::UsersController < Admin::ApplicationController
2   - before_filter :admin_user, only: [:show, :edit, :update, :destroy]
  2 + before_filter :user, only: [:show, :edit, :update, :destroy]
3 3  
4 4 def index
5   - @admin_users = User.scoped
6   - @admin_users = @admin_users.filter(params[:filter])
7   - @admin_users = @admin_users.search(params[:name]) if params[:name].present?
8   - @admin_users = @admin_users.alphabetically.page(params[:page])
  5 + @users = User.scoped
  6 + @users = @users.filter(params[:filter])
  7 + @users = @users.search(params[:name]) if params[:name].present?
  8 + @users = @users.alphabetically.page(params[:page])
9 9 end
10 10  
11 11 def show
12   - # Projects user can be added to
13   - @not_in_projects = Project.scoped
14   - @not_in_projects = @not_in_projects.without_user(admin_user) if admin_user.authorized_projects.present?
15   -
16   - # Projects he already own or joined
17   - @projects = admin_user.authorized_projects
  12 + @projects = user.authorized_projects
18 13 end
19 14  
20   - def team_update
21   - UsersProject.add_users_into_projects(
22   - params[:project_ids],
23   - [admin_user.id],
24   - params[:project_access]
25   - )
26   -
27   - redirect_to [:admin, admin_user], notice: 'Teams were successfully updated.'
28   - end
29   -
30   -
31 15 def new
32   - @admin_user = User.new.with_defaults
  16 + @user = User.new.with_defaults
33 17 end
34 18  
35 19 def edit
36   - admin_user
  20 + user
37 21 end
38 22  
39 23 def block
40   - if admin_user.block
  24 + if user.block
41 25 redirect_to :back, alert: "Successfully blocked"
42 26 else
43 27 redirect_to :back, alert: "Error occured. User was not blocked"
... ... @@ -45,7 +29,7 @@ class Admin::UsersController &lt; Admin::ApplicationController
45 29 end
46 30  
47 31 def unblock
48   - if admin_user.activate
  32 + if user.activate
49 33 redirect_to :back, alert: "Successfully unblocked"
50 34 else
51 35 redirect_to :back, alert: "Error occured. User was not unblocked"
... ... @@ -60,17 +44,17 @@ class Admin::UsersController &lt; Admin::ApplicationController
60 44 password_expires_at: Time.now
61 45 }
62 46  
63   - @admin_user = User.new(params[:user].merge(opts), as: :admin)
64   - @admin_user.admin = (admin && admin.to_i > 0)
65   - @admin_user.created_by_id = current_user.id
  47 + @user = User.new(params[:user].merge(opts), as: :admin)
  48 + @user.admin = (admin && admin.to_i > 0)
  49 + @user.created_by_id = current_user.id
66 50  
67 51 respond_to do |format|
68   - if @admin_user.save
69   - format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully created.' }
70   - format.json { render json: @admin_user, status: :created, location: @admin_user }
  52 + if @user.save
  53 + format.html { redirect_to [:admin, @user], notice: 'User was successfully created.' }
  54 + format.json { render json: @user, status: :created, location: @user }
71 55 else
72   - format.html { render action: "new" }
73   - format.json { render json: @admin_user.errors, status: :unprocessable_entity }
  56 + format.html { render "new" }
  57 + format.json { render json: @user.errors, status: :unprocessable_entity }
74 58 end
75 59 end
76 60 end
... ... @@ -83,26 +67,26 @@ class Admin::UsersController &lt; Admin::ApplicationController
83 67 params[:user].delete(:password_confirmation)
84 68 end
85 69  
86   - admin_user.admin = (admin && admin.to_i > 0)
  70 + user.admin = (admin && admin.to_i > 0)
87 71  
88 72 respond_to do |format|
89   - if admin_user.update_attributes(params[:user], as: :admin)
90   - format.html { redirect_to [:admin, admin_user], notice: 'User was successfully updated.' }
  73 + if user.update_attributes(params[:user], as: :admin)
  74 + format.html { redirect_to [:admin, user], notice: 'User was successfully updated.' }
91 75 format.json { head :ok }
92 76 else
93 77 # restore username to keep form action url.
94   - admin_user.username = params[:id]
95   - format.html { render action: "edit" }
96   - format.json { render json: admin_user.errors, status: :unprocessable_entity }
  78 + user.username = params[:id]
  79 + format.html { render "edit" }
  80 + format.json { render json: user.errors, status: :unprocessable_entity }
97 81 end
98 82 end
99 83 end
100 84  
101 85 def destroy
102   - if admin_user.personal_projects.count > 0
  86 + if user.personal_projects.count > 0
103 87 redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return
104 88 end
105   - admin_user.destroy
  89 + user.destroy
106 90  
107 91 respond_to do |format|
108 92 format.html { redirect_to admin_users_path }
... ... @@ -112,7 +96,7 @@ class Admin::UsersController &lt; Admin::ApplicationController
112 96  
113 97 protected
114 98  
115   - def admin_user
116   - @admin_user ||= User.find_by_username!(params[:id])
  99 + def user
  100 + @user ||= User.find_by_username!(params[:id])
117 101 end
118 102 end
... ...
app/controllers/application_controller.rb
... ... @@ -95,14 +95,6 @@ class ApplicationController &lt; ActionController::Base
95 95 return access_denied! unless can?(current_user, :create_team, nil)
96 96 end
97 97  
98   - def authorize_manage_user_team!
99   - return access_denied! unless user_team.present? && can?(current_user, :manage_user_team, user_team)
100   - end
101   -
102   - def authorize_admin_user_team!
103   - return access_denied! unless user_team.present? && can?(current_user, :admin_user_team, user_team)
104   - end
105   -
106 98 def access_denied!
107 99 render "errors/access_denied", layout: "errors", status: 404
108 100 end
... ...
app/controllers/blame_controller.rb
... ... @@ -1,14 +0,0 @@
1   -# Controller for viewing a file's blame
2   -class BlameController < ProjectResourceController
3   - include ExtractsPath
4   -
5   - # Authorize
6   - before_filter :authorize_read_project!
7   - before_filter :authorize_code_access!
8   - before_filter :require_non_empty_project
9   -
10   - def show
11   - @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
12   - @blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path)
13   - end
14   -end
app/controllers/blob_controller.rb
... ... @@ -1,13 +0,0 @@
1   -# Controller for viewing a file's blame
2   -class BlobController < ProjectResourceController
3   - include ExtractsPath
4   -
5   - # Authorize
6   - before_filter :authorize_read_project!
7   - before_filter :authorize_code_access!
8   - before_filter :require_non_empty_project
9   -
10   - def show
11   - @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
12   - end
13   -end
app/controllers/commit_controller.rb
... ... @@ -1,43 +0,0 @@
1   -# Controller for a specific Commit
2   -#
3   -# Not to be confused with CommitsController, plural.
4   -class CommitController < ProjectResourceController
5   - # Authorize
6   - before_filter :authorize_read_project!
7   - before_filter :authorize_code_access!
8   - before_filter :require_non_empty_project
9   -
10   - def show
11   - result = CommitLoadContext.new(project, current_user, params).execute
12   -
13   - @commit = result[:commit]
14   -
15   - if @commit.nil?
16   - git_not_found!
17   - return
18   - end
19   -
20   - @suppress_diff = result[:suppress_diff]
21   -
22   - @note = result[:note]
23   - @line_notes = result[:line_notes]
24   - @notes_count = result[:notes_count]
25   - @target_type = :commit
26   - @target_id = @commit.id
27   -
28   - @comments_allowed = @reply_allowed = true
29   - @comments_target = { noteable_type: 'Commit',
30   - commit_id: @commit.id }
31   -
32   - respond_to do |format|
33   - format.html do
34   - if result[:status] == :huge_commit
35   - render "huge_commit" and return
36   - end
37   - end
38   -
39   - format.diff { render text: @commit.to_diff }
40   - format.patch { render text: @commit.to_patch }
41   - end
42   - end
43   -end
app/controllers/commits_controller.rb
... ... @@ -1,23 +0,0 @@
1   -require "base64"
2   -
3   -class CommitsController < ProjectResourceController
4   - include ExtractsPath
5   -
6   - # Authorize
7   - before_filter :authorize_read_project!
8   - before_filter :authorize_code_access!
9   - before_filter :require_non_empty_project
10   -
11   - def show
12   - @repo = @project.repository
13   - @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
14   -
15   - @commits = @repo.commits(@ref, @path, @limit, @offset)
16   -
17   - respond_to do |format|
18   - format.html # index.html.erb
19   - format.js
20   - format.atom { render layout: false }
21   - end
22   - end
23   -end
app/controllers/compare_controller.rb
... ... @@ -1,23 +0,0 @@
1   -class CompareController < ProjectResourceController
2   - # Authorize
3   - before_filter :authorize_read_project!
4   - before_filter :authorize_code_access!
5   - before_filter :require_non_empty_project
6   -
7   - def index
8   - end
9   -
10   - def show
11   - compare = Gitlab::Git::Compare.new(project.repository, params[:from], params[:to])
12   -
13   - @commits = compare.commits
14   - @commit = compare.commit
15   - @diffs = compare.diffs
16   - @refs_are_same = compare.same
17   - @line_notes = []
18   - end
19   -
20   - def create
21   - redirect_to project_compare_path(@project, params[:from], params[:to])
22   - end
23   -end
app/controllers/dashboard_controller.rb
1 1 class DashboardController < ApplicationController
2 2 respond_to :html
3 3  
4   - before_filter :load_projects
  4 + before_filter :load_projects, except: [:projects]
5 5 before_filter :event_filter, only: :show
6 6  
7 7 def show
8 8 @groups = current_user.authorized_groups.sort_by(&:human_name)
9 9 @has_authorized_projects = @projects.count > 0
10   - @teams = current_user.authorized_teams
11 10 @projects_count = @projects.count
12 11 @projects = @projects.limit(20)
13 12  
... ... @@ -27,18 +26,21 @@ class DashboardController &lt; ApplicationController
27 26 def projects
28 27 @projects = case params[:scope]
29 28 when 'personal' then
30   - @projects.personal(current_user)
  29 + current_user.namespace.projects
31 30 when 'joined' then
32   - @projects.joined(current_user)
  31 + current_user.authorized_projects.joined(current_user)
  32 + when 'owned' then
  33 + current_user.owned_projects
33 34 else
34   - @projects
35   - end
  35 + current_user.authorized_projects
  36 + end.sorted_by_activity
36 37  
37   - @projects = @projects.tagged_with(params[:label]) if params[:label].present?
38 38 @projects = @projects.search(params[:search]) if params[:search].present?
39   - @projects = @projects.page(params[:page]).per(30)
40 39  
41   - @labels = Project.where(id: @projects.map(&:id)).tags_on(:labels)
  40 + @labels = current_user.authorized_projects.tags_on(:labels)
  41 +
  42 + @projects = @projects.tagged_with(params[:label]) if params[:label].present?
  43 + @projects = @projects.page(params[:page]).per(30)
42 44 end
43 45  
44 46 # Get authored or assigned open merge requests
... ...
app/controllers/deploy_keys_controller.rb
... ... @@ -1,59 +0,0 @@
1   -class DeployKeysController < ProjectResourceController
2   - respond_to :html
3   -
4   - # Authorize
5   - before_filter :authorize_admin_project!
6   -
7   - def index
8   - @enabled_keys = @project.deploy_keys.all
9   - @available_keys = available_keys - @enabled_keys
10   - end
11   -
12   - def show
13   - @key = @project.deploy_keys.find(params[:id])
14   - end
15   -
16   - def new
17   - @key = @project.deploy_keys.new
18   -
19   - respond_with(@key)
20   - end
21   -
22   - def create
23   - @key = DeployKey.new(params[:deploy_key])
24   -
25   - if @key.valid? && @project.deploy_keys << @key
26   - redirect_to project_deploy_keys_path(@project)
27   - else
28   - render "new"
29   - end
30   - end
31   -
32   - def destroy
33   - @key = @project.deploy_keys.find(params[:id])
34   - @key.destroy
35   -
36   - respond_to do |format|
37   - format.html { redirect_to project_deploy_keys_url }
38   - format.js { render nothing: true }
39   - end
40   - end
41   -
42   - def enable
43   - project.deploy_keys << available_keys.find(params[:id])
44   -
45   - redirect_to project_deploy_keys_path(@project)
46   - end
47   -
48   - def disable
49   - @project.deploy_keys_projects.where(deploy_key_id: params[:id]).last.destroy
50   -
51   - redirect_to project_deploy_keys_path(@project)
52   - end
53   -
54   - protected
55   -
56   - def available_keys
57   - @available_keys ||= current_user.accessible_deploy_keys
58   - end
59   -end
app/controllers/edit_tree_controller.rb
... ... @@ -1,49 +0,0 @@
1   -# Controller for edit a repository's file
2   -class EditTreeController < ProjectResourceController
3   - include ExtractsPath
4   -
5   - # Authorize
6   - before_filter :authorize_read_project!
7   - before_filter :authorize_code_access!
8   - before_filter :require_non_empty_project
9   -
10   - before_filter :edit_requirements, only: [:show, :update]
11   -
12   - def show
13   - @last_commit = @project.repository.last_commit_for(@ref, @path).sha
14   - end
15   -
16   - def update
17   - edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
18   - updated_successfully = edit_file_action.commit!(
19   - params[:content],
20   - params[:commit_message],
21   - params[:last_commit]
22   - )
23   -
24   - if updated_successfully
25   - redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
26   - else
27   - flash[:notice] = "Your changes could not be commited, because the file has been changed"
28   - render :show
29   - end
30   - end
31   -
32   - private
33   -
34   - def edit_requirements
35   - @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
36   -
37   - unless @blob.exists? && @blob.text?
38   - redirect_to project_blob_path(@project, @id), notice: "You can only edit text files"
39   - end
40   -
41   - allowed = if project.protected_branch? @ref
42   - can?(current_user, :push_code_to_protected_branches, project)
43   - else
44   - can?(current_user, :push_code, project)
45   - end
46   -
47   - return access_denied! unless allowed
48   - end
49   -end
app/controllers/graphs_controller.rb
... ... @@ -1,17 +0,0 @@
1   -class GraphsController < ProjectResourceController
2   - # Authorize
3   - before_filter :authorize_read_project!
4   - before_filter :authorize_code_access!
5   - before_filter :require_non_empty_project
6   -
7   - def show
8   - respond_to do |format|
9   - format.html
10   - format.js do
11   - @repo = @project.repository
12   - @stats = Gitlab::Git::GitStats.new(@repo.raw, @repo.root_ref)
13   - @log = @stats.parsed_log.to_json
14   - end
15   - end
16   - end
17   -end
app/controllers/groups_controller.rb
... ... @@ -63,19 +63,8 @@ class GroupsController &lt; ApplicationController
63 63  
64 64 def people
65 65 @project = group.projects.find(params[:project_id]) if params[:project_id]
66   - @users = @project ? @project.users : group.users
67   - @users.sort_by!(&:name)
68   -
69   - if @project
70   - @team_member = @project.users_projects.new
71   - else
72   - @team_member = UsersProject.new
73   - end
74   - end
75   -
76   - def team_members
77   - @group.add_users_to_project_teams(params[:user_ids].split(','), params[:project_access])
78   - redirect_to people_group_path(@group), notice: 'Users were successfully added.'
  66 + @members = group.users_groups.order('group_access DESC')
  67 + @users_group = UsersGroup.new
79 68 end
80 69  
81 70 def edit
... ... @@ -83,7 +72,7 @@ class GroupsController &lt; ApplicationController
83 72  
84 73 def update
85 74 group_params = params[:group].dup
86   - owner_id =group_params.delete(:owner_id)
  75 + owner_id = group_params.delete(:owner_id)
87 76  
88 77 if owner_id
89 78 @group.owner = User.find(owner_id)
... ...
app/controllers/help_controller.rb
... ... @@ -12,4 +12,7 @@ class HelpController &lt; ApplicationController
12 12 not_found!
13 13 end
14 14 end
  15 +
  16 + def shortcuts
  17 + end
15 18 end
... ...
app/controllers/hooks_controller.rb
... ... @@ -1,37 +0,0 @@
1   -class HooksController < ProjectResourceController
2   - # Authorize
3   - before_filter :authorize_read_project!
4   - before_filter :authorize_admin_project!, only: [:new, :create, :destroy]
5   -
6   - respond_to :html
7   -
8   - def index
9   - @hooks = @project.hooks.all
10   - @hook = ProjectHook.new
11   - end
12   -
13   - def create
14   - @hook = @project.hooks.new(params[:hook])
15   - @hook.save
16   -
17   - if @hook.valid?
18   - redirect_to project_hooks_path(@project)
19   - else
20   - @hooks = @project.hooks.all
21   - render :index
22   - end
23   - end
24   -
25   - def test
26   - TestHookContext.new(project, current_user, params).execute
27   -
28   - redirect_to :back
29   - end
30   -
31   - def destroy
32   - @hook = @project.hooks.find(params[:id])
33   - @hook.destroy
34   -
35   - redirect_to project_hooks_path(@project)
36   - end
37   -end
app/controllers/issues_controller.rb
... ... @@ -1,114 +0,0 @@
1   -class IssuesController < ProjectResourceController
2   - before_filter :module_enabled
3   - before_filter :issue, only: [:edit, :update, :show]
4   -
5   - # Allow read any issue
6   - before_filter :authorize_read_issue!
7   -
8   - # Allow write(create) issue
9   - before_filter :authorize_write_issue!, only: [:new, :create]
10   -
11   - # Allow modify issue
12   - before_filter :authorize_modify_issue!, only: [:edit, :update]
13   -
14   - respond_to :js, :html
15   -
16   - def index
17   - terms = params['issue_search']
18   -
19   - @issues = issues_filtered
20   - @issues = @issues.where("title LIKE ?", "%#{terms}%") if terms.present?
21   - @issues = @issues.page(params[:page]).per(20)
22   -
23   -
24   - assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
25   -
26   - @assignee = @project.users.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
27   - @milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
28   -
29   - respond_to do |format|
30   - format.html # index.html.erb
31   - format.js
32   - format.atom { render layout: false }
33   - end
34   - end
35   -
36   - def new
37   - @issue = @project.issues.new(params[:issue])
38   - respond_with(@issue)
39   - end
40   -
41   - def edit
42   - respond_with(@issue)
43   - end
44   -
45   - def show
46   - @note = @project.notes.new(noteable: @issue)
47   - @target_type = :issue
48   - @target_id = @issue.id
49   -
50   - respond_to do |format|
51   - format.html
52   - format.js
53   - end
54   - end
55   -
56   - def create
57   - @issue = @project.issues.new(params[:issue])
58   - @issue.author = current_user
59   - @issue.save
60   -
61   - respond_to do |format|
62   - format.html do
63   - if @issue.valid?
64   - redirect_to project_issue_path(@project, @issue)
65   - else
66   - render :new
67   - end
68   - end
69   - format.js
70   - end
71   - end
72   -
73   - def update
74   - @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
75   -
76   - respond_to do |format|
77   - format.js
78   - format.html do
79   - if @issue.valid?
80   - redirect_to [@project, @issue]
81   - else
82   - render :edit
83   - end
84   - end
85   - end
86   - end
87   -
88   - def bulk_update
89   - result = Issues::BulkUpdateContext.new(project, current_user, params).execute
90   - redirect_to :back, notice: "#{result[:count]} issues updated"
91   - end
92   -
93   - protected
94   -
95   - def issue
96   - @issue ||= @project.issues.find(params[:id])
97   - end
98   -
99   - def authorize_modify_issue!
100   - return render_404 unless can?(current_user, :modify_issue, @issue)
101   - end
102   -
103   - def authorize_admin_issue!
104   - return render_404 unless can?(current_user, :admin_issue, @issue)
105   - end
106   -
107   - def module_enabled
108   - return render_404 unless @project.issues_enabled
109   - end
110   -
111   - def issues_filtered
112   - @issues = Issues::ListContext.new(project, current_user, params).execute
113   - end
114   -end
app/controllers/keys_controller.rb
... ... @@ -1,35 +0,0 @@
1   -class KeysController < ApplicationController
2   - layout "profile"
3   - respond_to :js, :html
4   -
5   - def index
6   - @keys = current_user.keys.all
7   - end
8   -
9   - def show
10   - @key = current_user.keys.find(params[:id])
11   - end
12   -
13   - def new
14   - @key = current_user.keys.new
15   -
16   - respond_with(@key)
17   - end
18   -
19   - def create
20   - @key = current_user.keys.new(params[:key])
21   - @key.save
22   -
23   - respond_with(@key)
24   - end
25   -
26   - def destroy
27   - @key = current_user.keys.find(params[:id])
28   - @key.destroy
29   -
30   - respond_to do |format|
31   - format.html { redirect_to keys_url }
32   - format.js { render nothing: true }
33   - end
34   - end
35   -end
app/controllers/labels_controller.rb
... ... @@ -1,24 +0,0 @@
1   -class LabelsController < ProjectResourceController
2   - before_filter :module_enabled
3   -
4   - # Allow read any issue
5   - before_filter :authorize_read_issue!
6   -
7   - respond_to :js, :html
8   -
9   - def index
10   - @labels = @project.issues_labels
11   - end
12   -
13   - def generate
14   - Gitlab::IssuesLabels.generate(@project)
15   -
16   - redirect_to project_labels_path(@project)
17   - end
18   -
19   - protected
20   -
21   - def module_enabled
22   - return render_404 unless @project.issues_enabled
23   - end
24   -end
app/controllers/merge_requests_controller.rb
... ... @@ -1,163 +0,0 @@
1   -require 'gitlab/satellite/satellite'
2   -
3   -class MergeRequestsController < ProjectResourceController
4   - before_filter :module_enabled
5   - before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
6   - before_filter :validates_merge_request, only: [:show, :diffs]
7   - before_filter :define_show_vars, only: [:show, :diffs]
8   -
9   - # Allow read any merge_request
10   - before_filter :authorize_read_merge_request!
11   -
12   - # Allow write(create) merge_request
13   - before_filter :authorize_write_merge_request!, only: [:new, :create]
14   -
15   - # Allow modify merge_request
16   - before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
17   -
18   - def index
19   - @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
20   - end
21   -
22   - def show
23   - respond_to do |format|
24   - format.html
25   - format.js
26   -
27   - format.diff { render text: @merge_request.to_diff }
28   - format.patch { render text: @merge_request.to_patch }
29   - end
30   - end
31   -
32   - def diffs
33   - @diffs = @merge_request.diffs
34   - @commit = @merge_request.last_commit
35   -
36   - @comments_allowed = @reply_allowed = true
37   - @comments_target = { noteable_type: 'MergeRequest',
38   - noteable_id: @merge_request.id }
39   - @line_notes = @merge_request.notes.where("line_code is not null")
40   - end
41   -
42   - def new
43   - @merge_request = @project.merge_requests.new(params[:merge_request])
44   - end
45   -
46   - def edit
47   - end
48   -
49   - def create
50   - @merge_request = @project.merge_requests.new(params[:merge_request])
51   - @merge_request.author = current_user
52   -
53   - if @merge_request.save
54   - @merge_request.reload_code
55   - redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.'
56   - else
57   - render action: "new"
58   - end
59   - end
60   -
61   - def update
62   - if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
63   - @merge_request.reload_code
64   - @merge_request.mark_as_unchecked
65   - redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.'
66   - else
67   - render action: "edit"
68   - end
69   - end
70   -
71   - def automerge_check
72   - if @merge_request.unchecked?
73   - @merge_request.check_if_can_be_merged
74   - end
75   - render json: {merge_status: @merge_request.merge_status_name}
76   - rescue Gitlab::SatelliteNotExistError
77   - render json: {merge_status: :no_satellite}
78   - end
79   -
80   - def automerge
81   - return access_denied! unless allowed_to_merge?
82   -
83   - if @merge_request.opened? && @merge_request.can_be_merged?
84   - @merge_request.should_remove_source_branch = params[:should_remove_source_branch]
85   - @merge_request.automerge!(current_user)
86   - @status = true
87   - else
88   - @status = false
89   - end
90   - end
91   -
92   - def branch_from
93   - @commit = @repository.commit(params[:ref])
94   - end
95   -
96   - def branch_to
97   - @commit = @repository.commit(params[:ref])
98   - end
99   -
100   - def ci_status
101   - status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
102   - response = { status: status }
103   -
104   - render json: response
105   - end
106   -
107   - protected
108   -
109   - def merge_request
110   - @merge_request ||= @project.merge_requests.find(params[:id])
111   - end
112   -
113   - def authorize_modify_merge_request!
114   - return render_404 unless can?(current_user, :modify_merge_request, @merge_request)
115   - end
116   -
117   - def authorize_admin_merge_request!
118   - return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
119   - end
120   -
121   - def module_enabled
122   - return render_404 unless @project.merge_requests_enabled
123   - end
124   -
125   - def validates_merge_request
126   - # Show git not found page if target branch doesn't exist
127   - return invalid_mr unless @project.repository.branch_names.include?(@merge_request.target_branch)
128   -
129   - # Show git not found page if source branch doesn't exist
130   - # and there is no saved commits between source & target branch
131   - return invalid_mr if !@project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
132   - end
133   -
134   - def define_show_vars
135   - # Build a note object for comment form
136   - @note = @project.notes.new(noteable: @merge_request)
137   -
138   - # Get commits from repository
139   - # or from cache if already merged
140   - @commits = @merge_request.commits
141   -
142   - @allowed_to_merge = allowed_to_merge?
143   - @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
144   -
145   - @target_type = :merge_request
146   - @target_id = @merge_request.id
147   - end
148   -
149   - def allowed_to_merge?
150   - action = if project.protected_branch?(@merge_request.target_branch)
151   - :push_code_to_protected_branches
152   - else
153   - :push_code
154   - end
155   -
156   - can?(current_user, action, @project)
157   - end
158   -
159   - def invalid_mr
160   - # Render special view for MR with removed source or target branch
161   - render 'invalid'
162   - end
163   -end
app/controllers/milestones_controller.rb
... ... @@ -1,94 +0,0 @@
1   -class MilestonesController < ProjectResourceController
2   - before_filter :module_enabled
3   - before_filter :milestone, only: [:edit, :update, :destroy, :show]
4   -
5   - # Allow read any milestone
6   - before_filter :authorize_read_milestone!
7   -
8   - # Allow admin milestone
9   - before_filter :authorize_admin_milestone!, except: [:index, :show]
10   -
11   - respond_to :html
12   -
13   - def index
14   - @milestones = case params[:f]
15   - when 'all'; @project.milestones.order("state, due_date DESC")
16   - when 'closed'; @project.milestones.closed.order("due_date DESC")
17   - else @project.milestones.active.order("due_date DESC")
18   - end
19   -
20   - @milestones = @milestones.includes(:project)
21   - @milestones = @milestones.page(params[:page]).per(20)
22   - end
23   -
24   - def new
25   - @milestone = @project.milestones.new
26   - respond_with(@milestone)
27   - end
28   -
29   - def edit
30   - respond_with(@milestone)
31   - end
32   -
33   - def show
34   - @issues = @milestone.issues
35   - @users = @milestone.participants.uniq
36   - @merge_requests = @milestone.merge_requests
37   -
38   - respond_to do |format|
39   - format.html
40   - format.js
41   - end
42   - end
43   -
44   - def create
45   - @milestone = @project.milestones.new(params[:milestone])
46   - @milestone.author_id_of_changes = current_user.id
47   -
48   - if @milestone.save
49   - redirect_to project_milestone_path(@project, @milestone)
50   - else
51   - render "new"
52   - end
53   - end
54   -
55   - def update
56   - @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id))
57   -
58   - respond_to do |format|
59   - format.js
60   - format.html do
61   - if @milestone.valid?
62   - redirect_to [@project, @milestone]
63   - else
64   - render :edit
65   - end
66   - end
67   - end
68   - end
69   -
70   - def destroy
71   - return access_denied! unless can?(current_user, :admin_milestone, @milestone)
72   -
73   - @milestone.destroy
74   -
75   - respond_to do |format|
76   - format.html { redirect_to project_milestones_path }
77   - format.js { render nothing: true }
78   - end
79   - end
80   -
81   - protected
82   -
83   - def milestone
84   - @milestone ||= @project.milestones.find(params[:id])
85   - end
86   -
87   - def authorize_admin_milestone!
88   - return render_404 unless can?(current_user, :admin_milestone, @project)
89   - end
90   -
91   - def module_enabled
92   - return render_404 unless @project.issues_enabled
93   - end
94   -end
app/controllers/network_controller.rb
... ... @@ -1,23 +0,0 @@
1   -class NetworkController < ProjectResourceController
2   - include ExtractsPath
3   - include ApplicationHelper
4   -
5   - # Authorize
6   - before_filter :authorize_read_project!
7   - before_filter :authorize_code_access!
8   - before_filter :require_non_empty_project
9   -
10   - def show
11   - if @options[:q]
12   - @commit = @project.repository.commit(@options[:q]) || @commit
13   - end
14   -
15   - respond_to do |format|
16   - format.html
17   -
18   - format.json do
19   - @graph = Network::Graph.new(project, @ref, @commit, @options[:filter_ref])
20   - end
21   - end
22   - end
23   -end
app/controllers/notes_controller.rb
... ... @@ -1,102 +0,0 @@
1   -class NotesController < ProjectResourceController
2   - # Authorize
3   - before_filter :authorize_read_note!
4   - before_filter :authorize_write_note!, only: [:create]
5   -
6   - respond_to :js
7   -
8   - def index
9   - @notes = Notes::LoadContext.new(project, current_user, params).execute
10   - @target_type = params[:target_type].camelize
11   - @target_id = params[:target_id]
12   -
13   - if params[:target_type] == "merge_request"
14   - @discussions = discussions_from_notes
15   - end
16   -
17   - respond_with(@notes)
18   - end
19   -
20   - def create
21   - @note = Notes::CreateContext.new(project, current_user, params).execute
22   - @target_type = params[:target_type].camelize
23   - @target_id = params[:target_id]
24   -
25   - respond_to do |format|
26   - format.html {redirect_to :back}
27   - format.js
28   - end
29   - end
30   -
31   - def destroy
32   - @note = @project.notes.find(params[:id])
33   - return access_denied! unless can?(current_user, :admin_note, @note)
34   - @note.destroy
35   -
36   - respond_to do |format|
37   - format.js { render nothing: true }
38   - end
39   - end
40   -
41   - def update
42   - @note = @project.notes.find(params[:id])
43   - return access_denied! unless can?(current_user, :admin_note, @note)
44   -
45   - @note.update_attributes(params[:note])
46   -
47   - respond_to do |format|
48   - format.js do
49   - render js: { success: @note.valid?, id: @note.id, note: view_context.markdown(@note.note) }.to_json
50   - end
51   - format.html do
52   - redirect_to :back
53   - end
54   - end
55   - end
56   -
57   - def delete_attachment
58   - @note = @project.notes.find(params[:id])
59   - @note.remove_attachment!
60   - @note.update_attribute(:attachment, nil)
61   -
62   - respond_to do |format|
63   - format.js { render nothing: true }
64   - end
65   - end
66   -
67   - def preview
68   - render text: view_context.markdown(params[:note])
69   - end
70   -
71   - protected
72   -
73   - def discussion_notes_for(note)
74   - @notes.select do |other_note|
75   - note.discussion_id == other_note.discussion_id
76   - end
77   - end
78   -
79   - def discussions_from_notes
80   - discussion_ids = []
81   - discussions = []
82   -
83   - @notes.each do |note|
84   - next if discussion_ids.include?(note.discussion_id)
85   -
86   - # don't group notes for the main target
87   - if note_for_main_target?(note)
88   - discussions << [note]
89   - else
90   - discussions << discussion_notes_for(note)
91   - discussion_ids << note.discussion_id
92   - end
93   - end
94   -
95   - discussions
96   - end
97   -
98   - # Helps to distinguish e.g. commit notes in mr notes list
99   - def note_for_main_target?(note)
100   - (@target_type.camelize == note.noteable_type && !note.for_diff_line?)
101   - end
102   -end
app/controllers/notifications_controller.rb
... ... @@ -1,21 +0,0 @@
1   -class NotificationsController < ApplicationController
2   - layout 'profile'
3   -
4   - def show
5   - @notification = current_user.notification
6   - @users_projects = current_user.users_projects
7   - end
8   -
9   - def update
10   - type = params[:notification_type]
11   -
12   - @saved = if type == 'global'
13   - current_user.notification_level = params[:notification_level]
14   - current_user.save
15   - else
16   - users_project = current_user.users_projects.find(params[:notification_id])
17   - users_project.notification_level = params[:notification_level]
18   - users_project.save
19   - end
20   - end
21   -end
app/controllers/passwords_controller.rb
... ... @@ -1,38 +0,0 @@
1   -class PasswordsController < ApplicationController
2   - layout 'navless'
3   -
4   - skip_before_filter :check_password_expiration
5   -
6   - before_filter :set_user
7   - before_filter :set_title
8   -
9   - def new
10   - end
11   -
12   - def create
13   - new_password = params[:user][:password]
14   - new_password_confirmation = params[:user][:password_confirmation]
15   -
16   - result = @user.update_attributes(
17   - password: new_password,
18   - password_confirmation: new_password_confirmation
19   - )
20   -
21   - if result
22   - @user.update_attributes(password_expires_at: nil)
23   - redirect_to root_path, notice: 'Password successfully changed'
24   - else
25   - render :new
26   - end
27   - end
28   -
29   - private
30   -
31   - def set_user
32   - @user = current_user
33   - end
34   -
35   - def set_title
36   - @title = "New password"
37   - end
38   -end
app/controllers/profiles/keys_controller.rb 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +class Profiles::KeysController < ApplicationController
  2 + layout "profile"
  3 +
  4 + def index
  5 + @keys = current_user.keys.order('id DESC').all
  6 + end
  7 +
  8 + def show
  9 + @key = current_user.keys.find(params[:id])
  10 + end
  11 +
  12 + def new
  13 + @key = current_user.keys.new
  14 + end
  15 +
  16 + def create
  17 + @key = current_user.keys.new(params[:key])
  18 +
  19 + if @key.save
  20 + redirect_to profile_key_path(@key)
  21 + else
  22 + render 'new'
  23 + end
  24 + end
  25 +
  26 + def destroy
  27 + @key = current_user.keys.find(params[:id])
  28 + @key.destroy
  29 +
  30 + respond_to do |format|
  31 + format.html { redirect_to profile_keys_url }
  32 + format.js { render nothing: true }
  33 + end
  34 + end
  35 +end
... ...
app/controllers/profiles/notifications_controller.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +class Profiles::NotificationsController < ApplicationController
  2 + layout 'profile'
  3 +
  4 + def show
  5 + @notification = current_user.notification
  6 + @users_projects = current_user.users_projects
  7 + @users_groups = current_user.users_groups
  8 + end
  9 +
  10 + def update
  11 + type = params[:notification_type]
  12 +
  13 + @saved = if type == 'global'
  14 + current_user.notification_level = params[:notification_level]
  15 + current_user.save
  16 + elsif type == 'group'
  17 + users_group = current_user.users_groups.find(params[:notification_id])
  18 + users_group.notification_level = params[:notification_level]
  19 + users_group.save
  20 + else
  21 + users_project = current_user.users_projects.find(params[:notification_id])
  22 + users_project.notification_level = params[:notification_level]
  23 + users_project.save
  24 + end
  25 + end
  26 +end
... ...
app/controllers/profiles/passwords_controller.rb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +class Profiles::PasswordsController < ApplicationController
  2 + layout 'navless'
  3 +
  4 + skip_before_filter :check_password_expiration
  5 +
  6 + before_filter :set_user
  7 + before_filter :set_title
  8 +
  9 + def new
  10 + end
  11 +
  12 + def create
  13 + new_password = params[:user][:password]
  14 + new_password_confirmation = params[:user][:password_confirmation]
  15 +
  16 + result = @user.update_attributes(
  17 + password: new_password,
  18 + password_confirmation: new_password_confirmation
  19 + )
  20 +
  21 + if result
  22 + @user.update_attributes(password_expires_at: nil)
  23 + redirect_to root_path, notice: 'Password successfully changed'
  24 + else
  25 + render :new
  26 + end
  27 + end
  28 +
  29 + private
  30 +
  31 + def set_user
  32 + @user = current_user
  33 + end
  34 +
  35 + def set_title
  36 + @title = "New password"
  37 + end
  38 +end
... ...
app/controllers/project_resource_controller.rb
... ... @@ -1,4 +0,0 @@
1   -class ProjectResourceController < ApplicationController
2   - before_filter :project
3   - before_filter :repository
4   -end
app/controllers/projects/application_controller.rb
1 1 class Projects::ApplicationController < ApplicationController
2 2 before_filter :project
3 3 before_filter :repository
  4 + layout 'projects'
4 5 end
... ...
app/controllers/projects/blame_controller.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +# Controller for viewing a file's blame
  2 +class Projects::BlameController < Projects::ApplicationController
  3 + include ExtractsPath
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
  12 + @blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path)
  13 + end
  14 +end
... ...
app/controllers/projects/blob_controller.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +# Controller for viewing a file's blame
  2 +class Projects::BlobController < Projects::ApplicationController
  3 + include ExtractsPath
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
  12 + end
  13 +end
... ...
app/controllers/projects/commit_controller.rb 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +# Controller for a specific Commit
  2 +#
  3 +# Not to be confused with CommitsController, plural.
  4 +class Projects::CommitController < Projects::ApplicationController
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + result = CommitLoadContext.new(project, current_user, params).execute
  12 +
  13 + @commit = result[:commit]
  14 +
  15 + if @commit.nil?
  16 + git_not_found!
  17 + return
  18 + end
  19 +
  20 + @suppress_diff = result[:suppress_diff]
  21 +
  22 + @note = result[:note]
  23 + @line_notes = result[:line_notes]
  24 + @notes_count = result[:notes_count]
  25 + @target_type = :commit
  26 + @target_id = @commit.id
  27 +
  28 + @comments_allowed = @reply_allowed = true
  29 + @comments_target = { noteable_type: 'Commit',
  30 + commit_id: @commit.id }
  31 +
  32 + respond_to do |format|
  33 + format.html do
  34 + if result[:status] == :huge_commit
  35 + render "huge_commit" and return
  36 + end
  37 + end
  38 +
  39 + format.diff { render text: @commit.to_diff }
  40 + format.patch { render text: @commit.to_patch }
  41 + end
  42 + end
  43 +end
... ...
app/controllers/projects/commits_controller.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +require "base64"
  2 +
  3 +class Projects::CommitsController < Projects::ApplicationController
  4 + include ExtractsPath
  5 +
  6 + # Authorize
  7 + before_filter :authorize_read_project!
  8 + before_filter :authorize_code_access!
  9 + before_filter :require_non_empty_project
  10 +
  11 + def show
  12 + @repo = @project.repository
  13 + @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
  14 +
  15 + @commits = @repo.commits(@ref, @path, @limit, @offset)
  16 +
  17 + respond_to do |format|
  18 + format.html # index.html.erb
  19 + format.js
  20 + format.atom { render layout: false }
  21 + end
  22 + end
  23 +end
... ...
app/controllers/projects/compare_controller.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +class Projects::CompareController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :authorize_code_access!
  5 + before_filter :require_non_empty_project
  6 +
  7 + def index
  8 + end
  9 +
  10 + def show
  11 + compare = Gitlab::Git::Compare.new(project.repository, params[:from], params[:to])
  12 +
  13 + @commits = compare.commits
  14 + @commit = compare.commit
  15 + @diffs = compare.diffs
  16 + @refs_are_same = compare.same
  17 + @line_notes = []
  18 + end
  19 +
  20 + def create
  21 + redirect_to project_compare_path(@project, params[:from], params[:to])
  22 + end
  23 +end
... ...
app/controllers/projects/deploy_keys_controller.rb 0 → 100644
... ... @@ -0,0 +1,61 @@
  1 +class Projects::DeployKeysController < Projects::ApplicationController
  2 + respond_to :html
  3 +
  4 + # Authorize
  5 + before_filter :authorize_admin_project!
  6 +
  7 + layout "project_settings"
  8 +
  9 + def index
  10 + @enabled_keys = @project.deploy_keys.all
  11 + @available_keys = available_keys - @enabled_keys
  12 + end
  13 +
  14 + def show
  15 + @key = @project.deploy_keys.find(params[:id])
  16 + end
  17 +
  18 + def new
  19 + @key = @project.deploy_keys.new
  20 +
  21 + respond_with(@key)
  22 + end
  23 +
  24 + def create
  25 + @key = DeployKey.new(params[:deploy_key])
  26 +
  27 + if @key.valid? && @project.deploy_keys << @key
  28 + redirect_to project_deploy_keys_path(@project)
  29 + else
  30 + render "new"
  31 + end
  32 + end
  33 +
  34 + def destroy
  35 + @key = @project.deploy_keys.find(params[:id])
  36 + @key.destroy
  37 +
  38 + respond_to do |format|
  39 + format.html { redirect_to project_deploy_keys_url }
  40 + format.js { render nothing: true }
  41 + end
  42 + end
  43 +
  44 + def enable
  45 + project.deploy_keys << available_keys.find(params[:id])
  46 +
  47 + redirect_to project_deploy_keys_path(@project)
  48 + end
  49 +
  50 + def disable
  51 + @project.deploy_keys_projects.where(deploy_key_id: params[:id]).last.destroy
  52 +
  53 + redirect_to project_deploy_keys_path(@project)
  54 + end
  55 +
  56 + protected
  57 +
  58 + def available_keys
  59 + @available_keys ||= current_user.accessible_deploy_keys
  60 + end
  61 +end
... ...
app/controllers/projects/edit_tree_controller.rb 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +# Controller for edit a repository's file
  2 +class Projects::EditTreeController < Projects::ApplicationController
  3 + include ExtractsPath
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + before_filter :edit_requirements, only: [:show, :update]
  11 +
  12 + def show
  13 + @last_commit = @project.repository.last_commit_for(@ref, @path).sha
  14 + end
  15 +
  16 + def update
  17 + edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
  18 + updated_successfully = edit_file_action.commit!(
  19 + params[:content],
  20 + params[:commit_message],
  21 + params[:last_commit]
  22 + )
  23 +
  24 + if updated_successfully
  25 + redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
  26 + else
  27 + flash[:notice] = "Your changes could not be commited, because the file has been changed"
  28 + render :show
  29 + end
  30 + end
  31 +
  32 + private
  33 +
  34 + def edit_requirements
  35 + @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
  36 +
  37 + unless @blob.exists? && @blob.text?
  38 + redirect_to project_blob_path(@project, @id), notice: "You can only edit text files"
  39 + end
  40 +
  41 + allowed = if project.protected_branch? @ref
  42 + can?(current_user, :push_code_to_protected_branches, project)
  43 + else
  44 + can?(current_user, :push_code, project)
  45 + end
  46 +
  47 + return access_denied! unless allowed
  48 + end
  49 +end
... ...
app/controllers/projects/graphs_controller.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +class Projects::GraphsController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :authorize_code_access!
  5 + before_filter :require_non_empty_project
  6 +
  7 + def show
  8 + respond_to do |format|
  9 + format.html
  10 + format.js do
  11 + fetch_graph
  12 + end
  13 + end
  14 + end
  15 +
  16 + private
  17 +
  18 + def fetch_graph
  19 + @log = @project.repository.graph_log.to_json
  20 + @success = true
  21 + rescue => ex
  22 + @log = []
  23 + @success = false
  24 + end
  25 +end
... ...
app/controllers/projects/hooks_controller.rb 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +class Projects::HooksController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :authorize_admin_project!, only: [:new, :create, :destroy]
  5 +
  6 + respond_to :html
  7 +
  8 + layout "project_settings"
  9 +
  10 + def index
  11 + @hooks = @project.hooks.all
  12 + @hook = ProjectHook.new
  13 + end
  14 +
  15 + def create
  16 + @hook = @project.hooks.new(params[:hook])
  17 + @hook.save
  18 +
  19 + if @hook.valid?
  20 + redirect_to project_hooks_path(@project)
  21 + else
  22 + @hooks = @project.hooks.all
  23 + render :index
  24 + end
  25 + end
  26 +
  27 + def test
  28 + TestHookContext.new(project, current_user, params).execute
  29 +
  30 + redirect_to :back
  31 + end
  32 +
  33 + def destroy
  34 + @hook = @project.hooks.find(params[:id])
  35 + @hook.destroy
  36 +
  37 + redirect_to project_hooks_path(@project)
  38 + end
  39 +end
... ...
app/controllers/projects/issues_controller.rb 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +class Projects::IssuesController < Projects::ApplicationController
  2 + before_filter :module_enabled
  3 + before_filter :issue, only: [:edit, :update, :show]
  4 +
  5 + # Allow read any issue
  6 + before_filter :authorize_read_issue!
  7 +
  8 + # Allow write(create) issue
  9 + before_filter :authorize_write_issue!, only: [:new, :create]
  10 +
  11 + # Allow modify issue
  12 + before_filter :authorize_modify_issue!, only: [:edit, :update]
  13 +
  14 + respond_to :js, :html
  15 +
  16 + def index
  17 + terms = params['issue_search']
  18 +
  19 + @issues = issues_filtered
  20 + @issues = @issues.where("title LIKE ?", "%#{terms}%") if terms.present?
  21 + @issues = @issues.page(params[:page]).per(20)
  22 +
  23 +
  24 + assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
  25 +
  26 + @assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
  27 + @milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
  28 +
  29 + respond_to do |format|
  30 + format.html # index.html.erb
  31 + format.js
  32 + format.atom { render layout: false }
  33 + end
  34 + end
  35 +
  36 + def new
  37 + @issue = @project.issues.new(params[:issue])
  38 + respond_with(@issue)
  39 + end
  40 +
  41 + def edit
  42 + respond_with(@issue)
  43 + end
  44 +
  45 + def show
  46 + @note = @project.notes.new(noteable: @issue)
  47 + @target_type = :issue
  48 + @target_id = @issue.id
  49 +
  50 + respond_to do |format|
  51 + format.html
  52 + format.js
  53 + end
  54 + end
  55 +
  56 + def create
  57 + @issue = @project.issues.new(params[:issue])
  58 + @issue.author = current_user
  59 + @issue.save
  60 +
  61 + respond_to do |format|
  62 + format.html do
  63 + if @issue.valid?
  64 + redirect_to project_issue_path(@project, @issue)
  65 + else
  66 + render :new
  67 + end
  68 + end
  69 + format.js
  70 + end
  71 + end
  72 +
  73 + def update
  74 + @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
  75 +
  76 + respond_to do |format|
  77 + format.js
  78 + format.html do
  79 + if @issue.valid?
  80 + redirect_to [@project, @issue]
  81 + else
  82 + render :edit
  83 + end
  84 + end
  85 + end
  86 + end
  87 +
  88 + def bulk_update
  89 + result = Issues::BulkUpdateContext.new(project, current_user, params).execute
  90 + redirect_to :back, notice: "#{result[:count]} issues updated"
  91 + end
  92 +
  93 + protected
  94 +
  95 + def issue
  96 + @issue ||= @project.issues.find(params[:id])
  97 + end
  98 +
  99 + def authorize_modify_issue!
  100 + return render_404 unless can?(current_user, :modify_issue, @issue)
  101 + end
  102 +
  103 + def authorize_admin_issue!
  104 + return render_404 unless can?(current_user, :admin_issue, @issue)
  105 + end
  106 +
  107 + def module_enabled
  108 + return render_404 unless @project.issues_enabled
  109 + end
  110 +
  111 + def issues_filtered
  112 + @issues = Issues::ListContext.new(project, current_user, params).execute
  113 + end
  114 +end
... ...
app/controllers/projects/labels_controller.rb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +class Projects::LabelsController < Projects::ApplicationController
  2 + before_filter :module_enabled
  3 +
  4 + # Allow read any issue
  5 + before_filter :authorize_read_issue!
  6 +
  7 + respond_to :js, :html
  8 +
  9 + def index
  10 + @labels = @project.issues_labels
  11 + end
  12 +
  13 + def generate
  14 + Gitlab::IssuesLabels.generate(@project)
  15 +
  16 + redirect_to project_labels_path(@project)
  17 + end
  18 +
  19 + protected
  20 +
  21 + def module_enabled
  22 + return render_404 unless @project.issues_enabled
  23 + end
  24 +end
... ...
app/controllers/projects/merge_requests_controller.rb 0 → 100644
... ... @@ -0,0 +1,162 @@
  1 +require 'gitlab/satellite/satellite'
  2 +
  3 +class Projects::MergeRequestsController < Projects::ApplicationController
  4 + before_filter :module_enabled
  5 + before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
  6 + before_filter :validates_merge_request, only: [:show, :diffs]
  7 + before_filter :define_show_vars, only: [:show, :diffs]
  8 +
  9 + # Allow read any merge_request
  10 + before_filter :authorize_read_merge_request!
  11 +
  12 + # Allow write(create) merge_request
  13 + before_filter :authorize_write_merge_request!, only: [:new, :create]
  14 +
  15 + # Allow modify merge_request
  16 + before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
  17 +
  18 + def index
  19 + @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
  20 + end
  21 +
  22 + def show
  23 + respond_to do |format|
  24 + format.html
  25 + format.js
  26 +
  27 + format.diff { render text: @merge_request.to_diff }
  28 + format.patch { render text: @merge_request.to_patch }
  29 + end
  30 + end
  31 +
  32 + def diffs
  33 + @commit = @merge_request.last_commit
  34 +
  35 + @comments_allowed = @reply_allowed = true
  36 + @comments_target = { noteable_type: 'MergeRequest',
  37 + noteable_id: @merge_request.id }
  38 + @line_notes = @merge_request.notes.where("line_code is not null")
  39 + end
  40 +
  41 + def new
  42 + @merge_request = @project.merge_requests.new(params[:merge_request])
  43 + end
  44 +
  45 + def edit
  46 + end
  47 +
  48 + def create
  49 + @merge_request = @project.merge_requests.new(params[:merge_request])
  50 + @merge_request.author = current_user
  51 +
  52 + if @merge_request.save
  53 + @merge_request.reload_code
  54 + redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.'
  55 + else
  56 + render "new"
  57 + end
  58 + end
  59 +
  60 + def update
  61 + if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
  62 + @merge_request.reload_code
  63 + @merge_request.mark_as_unchecked
  64 + redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.'
  65 + else
  66 + render "edit"
  67 + end
  68 + end
  69 +
  70 + def automerge_check
  71 + if @merge_request.unchecked?
  72 + @merge_request.check_if_can_be_merged
  73 + end
  74 + render json: {merge_status: @merge_request.merge_status_name}
  75 + rescue Gitlab::SatelliteNotExistError
  76 + render json: {merge_status: :no_satellite}
  77 + end
  78 +
  79 + def automerge
  80 + return access_denied! unless allowed_to_merge?
  81 +
  82 + if @merge_request.opened? && @merge_request.can_be_merged?
  83 + @merge_request.should_remove_source_branch = params[:should_remove_source_branch]
  84 + @merge_request.automerge!(current_user)
  85 + @status = true
  86 + else
  87 + @status = false
  88 + end
  89 + end
  90 +
  91 + def branch_from
  92 + @commit = @repository.commit(params[:ref])
  93 + end
  94 +
  95 + def branch_to
  96 + @commit = @repository.commit(params[:ref])
  97 + end
  98 +
  99 + def ci_status
  100 + status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
  101 + response = { status: status }
  102 +
  103 + render json: response
  104 + end
  105 +
  106 + protected
  107 +
  108 + def merge_request
  109 + @merge_request ||= @project.merge_requests.find(params[:id])
  110 + end
  111 +
  112 + def authorize_modify_merge_request!
  113 + return render_404 unless can?(current_user, :modify_merge_request, @merge_request)
  114 + end
  115 +
  116 + def authorize_admin_merge_request!
  117 + return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
  118 + end
  119 +
  120 + def module_enabled
  121 + return render_404 unless @project.merge_requests_enabled
  122 + end
  123 +
  124 + def validates_merge_request
  125 + # Show git not found page if target branch doesn't exist
  126 + return invalid_mr unless @project.repository.branch_names.include?(@merge_request.target_branch)
  127 +
  128 + # Show git not found page if source branch doesn't exist
  129 + # and there is no saved commits between source & target branch
  130 + return invalid_mr if !@project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
  131 + end
  132 +
  133 + def define_show_vars
  134 + # Build a note object for comment form
  135 + @note = @project.notes.new(noteable: @merge_request)
  136 +
  137 + # Get commits from repository
  138 + # or from cache if already merged
  139 + @commits = @merge_request.commits
  140 +
  141 + @allowed_to_merge = allowed_to_merge?
  142 + @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
  143 +
  144 + @target_type = :merge_request
  145 + @target_id = @merge_request.id
  146 + end
  147 +
  148 + def allowed_to_merge?
  149 + action = if project.protected_branch?(@merge_request.target_branch)
  150 + :push_code_to_protected_branches
  151 + else
  152 + :push_code
  153 + end
  154 +
  155 + can?(current_user, action, @project)
  156 + end
  157 +
  158 + def invalid_mr
  159 + # Render special view for MR with removed source or target branch
  160 + render 'invalid'
  161 + end
  162 +end
... ...
app/controllers/projects/milestones_controller.rb 0 → 100644
... ... @@ -0,0 +1,94 @@
  1 +class Projects::MilestonesController < Projects::ApplicationController
  2 + before_filter :module_enabled
  3 + before_filter :milestone, only: [:edit, :update, :destroy, :show]
  4 +
  5 + # Allow read any milestone
  6 + before_filter :authorize_read_milestone!
  7 +
  8 + # Allow admin milestone
  9 + before_filter :authorize_admin_milestone!, except: [:index, :show]
  10 +
  11 + respond_to :html
  12 +
  13 + def index
  14 + @milestones = case params[:f]
  15 + when 'all'; @project.milestones.order("state, due_date DESC")
  16 + when 'closed'; @project.milestones.closed.order("due_date DESC")
  17 + else @project.milestones.active.order("due_date DESC")
  18 + end
  19 +
  20 + @milestones = @milestones.includes(:project)
  21 + @milestones = @milestones.page(params[:page]).per(20)
  22 + end
  23 +
  24 + def new
  25 + @milestone = @project.milestones.new
  26 + respond_with(@milestone)
  27 + end
  28 +
  29 + def edit
  30 + respond_with(@milestone)
  31 + end
  32 +
  33 + def show
  34 + @issues = @milestone.issues
  35 + @users = @milestone.participants.uniq
  36 + @merge_requests = @milestone.merge_requests
  37 +
  38 + respond_to do |format|
  39 + format.html
  40 + format.js
  41 + end
  42 + end
  43 +
  44 + def create
  45 + @milestone = @project.milestones.new(params[:milestone])
  46 + @milestone.author_id_of_changes = current_user.id
  47 +
  48 + if @milestone.save
  49 + redirect_to project_milestone_path(@project, @milestone)
  50 + else
  51 + render "new"
  52 + end
  53 + end
  54 +
  55 + def update
  56 + @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id))
  57 +
  58 + respond_to do |format|
  59 + format.js
  60 + format.html do
  61 + if @milestone.valid?
  62 + redirect_to [@project, @milestone]
  63 + else
  64 + render :edit
  65 + end
  66 + end
  67 + end
  68 + end
  69 +
  70 + def destroy
  71 + return access_denied! unless can?(current_user, :admin_milestone, @milestone)
  72 +
  73 + @milestone.destroy
  74 +
  75 + respond_to do |format|
  76 + format.html { redirect_to project_milestones_path }
  77 + format.js { render nothing: true }
  78 + end
  79 + end
  80 +
  81 + protected
  82 +
  83 + def milestone
  84 + @milestone ||= @project.milestones.find(params[:id])
  85 + end
  86 +
  87 + def authorize_admin_milestone!
  88 + return render_404 unless can?(current_user, :admin_milestone, @project)
  89 + end
  90 +
  91 + def module_enabled
  92 + return render_404 unless @project.issues_enabled
  93 + end
  94 +end
... ...
app/controllers/projects/network_controller.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +class Projects::NetworkController < Projects::ApplicationController
  2 + include ExtractsPath
  3 + include ApplicationHelper
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + if @options[:q]
  12 + @commit = @project.repository.commit(@options[:q]) || @commit
  13 + end
  14 +
  15 + respond_to do |format|
  16 + format.html
  17 +
  18 + format.json do
  19 + @graph = Network::Graph.new(project, @ref, @commit, @options[:filter_ref])
  20 + end
  21 + end
  22 + end
  23 +end
... ...
app/controllers/projects/notes_controller.rb 0 → 100644
... ... @@ -0,0 +1,102 @@
  1 +class Projects::NotesController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_note!
  4 + before_filter :authorize_write_note!, only: [:create]
  5 +
  6 + respond_to :js
  7 +
  8 + def index
  9 + @notes = Notes::LoadContext.new(project, current_user, params).execute
  10 + @target_type = params[:target_type].camelize
  11 + @target_id = params[:target_id]
  12 +
  13 + if params[:target_type] == "merge_request"
  14 + @discussions = discussions_from_notes
  15 + end
  16 +
  17 + respond_with(@notes)
  18 + end
  19 +
  20 + def create
  21 + @note = Notes::CreateContext.new(project, current_user, params).execute
  22 + @target_type = params[:target_type].camelize
  23 + @target_id = params[:target_id]
  24 +
  25 + respond_to do |format|
  26 + format.html {redirect_to :back}
  27 + format.js
  28 + end
  29 + end
  30 +
  31 + def destroy
  32 + @note = @project.notes.find(params[:id])
  33 + return access_denied! unless can?(current_user, :admin_note, @note)
  34 + @note.destroy
  35 +
  36 + respond_to do |format|
  37 + format.js { render nothing: true }
  38 + end
  39 + end
  40 +
  41 + def update
  42 + @note = @project.notes.find(params[:id])
  43 + return access_denied! unless can?(current_user, :admin_note, @note)
  44 +
  45 + @note.update_attributes(params[:note])
  46 +
  47 + respond_to do |format|
  48 + format.js do
  49 + render js: { success: @note.valid?, id: @note.id, note: view_context.markdown(@note.note) }.to_json
  50 + end
  51 + format.html do
  52 + redirect_to :back
  53 + end
  54 + end
  55 + end
  56 +
  57 + def delete_attachment
  58 + @note = @project.notes.find(params[:id])
  59 + @note.remove_attachment!
  60 + @note.update_attribute(:attachment, nil)
  61 +
  62 + respond_to do |format|
  63 + format.js { render nothing: true }
  64 + end
  65 + end
  66 +
  67 + def preview
  68 + render text: view_context.markdown(params[:note])
  69 + end
  70 +
  71 + protected
  72 +
  73 + def discussion_notes_for(note)
  74 + @notes.select do |other_note|
  75 + note.discussion_id == other_note.discussion_id
  76 + end
  77 + end
  78 +
  79 + def discussions_from_notes
  80 + discussion_ids = []
  81 + discussions = []
  82 +
  83 + @notes.each do |note|
  84 + next if discussion_ids.include?(note.discussion_id)
  85 +
  86 + # don't group notes for the main target
  87 + if note_for_main_target?(note)
  88 + discussions << [note]
  89 + else
  90 + discussions << discussion_notes_for(note)
  91 + discussion_ids << note.discussion_id
  92 + end
  93 + end
  94 +
  95 + discussions
  96 + end
  97 +
  98 + # Helps to distinguish e.g. commit notes in mr notes list
  99 + def note_for_main_target?(note)
  100 + (@target_type.camelize == note.noteable_type && !note.for_diff_line?)
  101 + end
  102 +end
... ...
app/controllers/projects/protected_branches_controller.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +class Projects::ProtectedBranchesController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :require_non_empty_project
  5 +
  6 + before_filter :authorize_admin_project!, only: [:destroy, :create]
  7 +
  8 + def index
  9 + @branches = @project.protected_branches.all
  10 + @protected_branch = @project.protected_branches.new
  11 + end
  12 +
  13 + def create
  14 + @project.protected_branches.create(params[:protected_branch])
  15 + redirect_to project_protected_branches_path(@project)
  16 + end
  17 +
  18 + def destroy
  19 + @project.protected_branches.find(params[:id]).destroy
  20 +
  21 + respond_to do |format|
  22 + format.html { redirect_to project_protected_branches_path }
  23 + format.js { render nothing: true }
  24 + end
  25 + end
  26 +end
... ...
app/controllers/projects/raw_controller.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +# Controller for viewing a file's raw
  2 +class Projects::RawController < Projects::ApplicationController
  3 + include ExtractsPath
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
  12 +
  13 + if @blob.exists?
  14 + send_data(
  15 + @blob.data,
  16 + type: @blob.mime_type,
  17 + disposition: 'inline',
  18 + filename: @blob.name
  19 + )
  20 + else
  21 + not_found!
  22 + end
  23 + end
  24 +end
  25 +
... ...
app/controllers/projects/refs_controller.rb 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +class Projects::RefsController < Projects::ApplicationController
  2 + include ExtractsPath
  3 +
  4 + # Authorize
  5 + before_filter :authorize_read_project!
  6 + before_filter :authorize_code_access!
  7 + before_filter :require_non_empty_project
  8 +
  9 + def switch
  10 + respond_to do |format|
  11 + format.html do
  12 + new_path = if params[:destination] == "tree"
  13 + project_tree_path(@project, (@id))
  14 + elsif params[:destination] == "blob"
  15 + project_blob_path(@project, (@id))
  16 + elsif params[:destination] == "graph"
  17 + project_network_path(@project, @id, @options)
  18 + else
  19 + project_commits_path(@project, @id)
  20 + end
  21 +
  22 + redirect_to new_path
  23 + end
  24 + format.js do
  25 + @ref = params[:ref]
  26 + define_tree_vars
  27 + render "tree"
  28 + end
  29 + end
  30 + end
  31 +
  32 + def logs_tree
  33 + contents = @tree.entries
  34 + @logs = contents.map do |content|
  35 + file = params[:path] ? File.join(params[:path], content.name) : content.name
  36 + last_commit = @repo.commits(@commit.id, file, 1).last
  37 + {
  38 + file_name: content.name,
  39 + commit: last_commit
  40 + }
  41 + end
  42 + end
  43 +end
... ...
app/controllers/projects/repositories_controller.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +class Projects::RepositoriesController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :authorize_code_access!
  5 + before_filter :require_non_empty_project
  6 +
  7 + def show
  8 + @activities = @repository.commits_with_refs(20)
  9 + end
  10 +
  11 + def branches
  12 + @branches = @repository.branches
  13 + end
  14 +
  15 + def tags
  16 + @tags = @repository.tags
  17 + end
  18 +
  19 + def stats
  20 + @stats = Gitlab::Git::Stats.new(@repository.raw, @repository.root_ref)
  21 + @graph = @stats.graph
  22 + end
  23 +
  24 + def archive
  25 + unless can?(current_user, :download_code, @project)
  26 + render_404 and return
  27 + end
  28 +
  29 +
  30 + storage_path = Rails.root.join("tmp", "repositories")
  31 +
  32 + file_path = @repository.archive_repo(params[:ref], storage_path)
  33 +
  34 + if file_path
  35 + # Send file to user
  36 + send_file file_path
  37 + else
  38 + render_404
  39 + end
  40 + end
  41 +end
... ...
app/controllers/projects/services_controller.rb 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +class Projects::ServicesController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_admin_project!
  4 + before_filter :service, only: [:edit, :update, :test]
  5 +
  6 + respond_to :html
  7 +
  8 + layout "project_settings"
  9 +
  10 + def index
  11 + @project.build_missing_services
  12 + @services = @project.services.reload
  13 + end
  14 +
  15 + def edit
  16 + end
  17 +
  18 + def update
  19 + if @service.update_attributes(params[:service])
  20 + redirect_to edit_project_service_path(@project, @service.to_param)
  21 + else
  22 + render 'edit'
  23 + end
  24 + end
  25 +
  26 + def test
  27 + data = GitPushService.new.sample_data(project, current_user)
  28 +
  29 + @service.execute(data)
  30 +
  31 + redirect_to :back
  32 + end
  33 +
  34 + private
  35 +
  36 + def service
  37 + @service ||= @project.services.find { |service| service.to_param == params[:id] }
  38 + end
  39 +end
... ...
app/controllers/projects/snippets_controller.rb
... ... @@ -14,7 +14,7 @@ class Projects::SnippetsController &lt; Projects::ApplicationController
14 14 # Allow destroy snippet
15 15 before_filter :authorize_admin_project_snippet!, only: [:destroy]
16 16  
17   - layout 'project_resource'
  17 + layout 'projects'
18 18  
19 19 respond_to :html
20 20  
... ...
app/controllers/projects/team_members_controller.rb 0 → 100644
... ... @@ -0,0 +1,62 @@
  1 +class Projects::TeamMembersController < Projects::ApplicationController
  2 + # Authorize
  3 + before_filter :authorize_read_project!
  4 + before_filter :authorize_admin_project!, except: [:index, :show]
  5 +
  6 + layout "project_settings"
  7 +
  8 + def index
  9 + @group = @project.group
  10 + @users_projects = @project.users_projects.order('project_access DESC')
  11 + end
  12 +
  13 + def new
  14 + @user_project_relation = project.users_projects.new
  15 + end
  16 +
  17 + def create
  18 + users = User.where(id: params[:user_ids].split(','))
  19 +
  20 + @project.team << [users, params[:project_access]]
  21 +
  22 + if params[:redirect_to]
  23 + redirect_to params[:redirect_to]
  24 + else
  25 + redirect_to project_team_index_path(@project)
  26 + end
  27 + end
  28 +
  29 + def update
  30 + @user_project_relation = project.users_projects.find_by_user_id(member)
  31 + @user_project_relation.update_attributes(params[:team_member])
  32 +
  33 + unless @user_project_relation.valid?
  34 + flash[:alert] = "User should have at least one role"
  35 + end
  36 + redirect_to project_team_index_path(@project)
  37 + end
  38 +
  39 + def destroy
  40 + @user_project_relation = project.users_projects.find_by_user_id(member)
  41 + @user_project_relation.destroy
  42 +
  43 + respond_to do |format|
  44 + format.html { redirect_to project_team_index_path(@project) }
  45 + format.js { render nothing: true }
  46 + end
  47 + end
  48 +
  49 + def apply_import
  50 + giver = Project.find(params[:source_project_id])
  51 + status = @project.team.import(giver)
  52 + notice = status ? "Succesfully imported" : "Import failed"
  53 +
  54 + redirect_to project_team_index_path(project), notice: notice
  55 + end
  56 +
  57 + protected
  58 +
  59 + def member
  60 + @member ||= User.find_by_username(params[:id])
  61 + end
  62 +end
... ...
app/controllers/projects/teams_controller.rb
... ... @@ -1,34 +0,0 @@
1   -class Projects::TeamsController < Projects::ApplicationController
2   -
3   - before_filter :authorize_admin_team_member!
4   -
5   - def available
6   - @teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
7   - @teams = @teams.without_project(project)
8   - unless @teams.any?
9   - redirect_to project_team_index_path(project), notice: "No available teams for assigment."
10   - end
11   - end
12   -
13   - def assign
14   - unless params[:team_id].blank?
15   - team = UserTeam.find(params[:team_id])
16   - access = params[:greatest_project_access]
17   - team.assign_to_project(project, access)
18   - end
19   - redirect_to project_team_index_path(project)
20   - end
21   -
22   - def resign
23   - team = project.user_teams.find_by_path(params[:id])
24   - team.resign_from_project(project)
25   -
26   - redirect_to project_team_index_path(project)
27   - end
28   -
29   - protected
30   -
31   - def user_team
32   - @team ||= UserTeam.find_by_path(params[:id])
33   - end
34   -end
app/controllers/projects/tree_controller.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +# Controller for viewing a repository's file structure
  2 +class Projects::TreeController < Projects::ApplicationController
  3 + include ExtractsPath
  4 +
  5 + # Authorize
  6 + before_filter :authorize_read_project!
  7 + before_filter :authorize_code_access!
  8 + before_filter :require_non_empty_project
  9 +
  10 + def show
  11 + respond_to do |format|
  12 + format.html
  13 + # Disable cache so browser history works
  14 + format.js { no_cache_headers }
  15 + end
  16 + end
  17 +end
... ...
app/controllers/projects/walls_controller.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +class Projects::WallsController < Projects::ApplicationController
  2 + before_filter :module_enabled
  3 +
  4 + respond_to :js, :html
  5 +
  6 + def show
  7 + @note = @project.notes.new
  8 +
  9 + respond_to do |format|
  10 + format.html
  11 + end
  12 + end
  13 +
  14 + protected
  15 +
  16 + def module_enabled
  17 + return render_404 unless @project.wall_enabled
  18 + end
  19 +end
  20 +
... ...
app/controllers/projects/wikis_controller.rb 0 → 100644
... ... @@ -0,0 +1,95 @@
  1 +class Projects::WikisController < Projects::ApplicationController
  2 + before_filter :authorize_read_wiki!
  3 + before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
  4 + before_filter :authorize_admin_wiki!, only: :destroy
  5 + before_filter :load_gollum_wiki
  6 +
  7 + def pages
  8 + @wiki_pages = @gollum_wiki.pages
  9 + end
  10 +
  11 + def show
  12 + @wiki = @gollum_wiki.find_page(params[:id], params[:version_id])
  13 +
  14 + if @wiki
  15 + render 'show'
  16 + else
  17 + return render('empty') unless can?(current_user, :write_wiki, @project)
  18 + @wiki = WikiPage.new(@gollum_wiki)
  19 + @wiki.title = params[:id]
  20 +
  21 + render 'edit'
  22 + end
  23 + end
  24 +
  25 + def edit
  26 + @wiki = @gollum_wiki.find_page(params[:id])
  27 + end
  28 +
  29 + def update
  30 + @wiki = @gollum_wiki.find_page(params[:id])
  31 +
  32 + return render('empty') unless can?(current_user, :write_wiki, @project)
  33 +
  34 + if @wiki.update(content, format, message)
  35 + redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.'
  36 + else
  37 + render 'edit'
  38 + end
  39 + end
  40 +
  41 + def create
  42 + @wiki = WikiPage.new(@gollum_wiki)
  43 +
  44 + if @wiki.create(wiki_params)
  45 + redirect_to project_wiki_path(@project, @wiki), notice: 'Wiki was successfully updated.'
  46 + else
  47 + render action: "edit"
  48 + end
  49 + end
  50 +
  51 + def history
  52 + @wiki = @gollum_wiki.find_page(params[:id])
  53 +
  54 + redirect_to(project_wiki_path(@project, :home), notice: "Page not found") unless @wiki
  55 + end
  56 +
  57 + def destroy
  58 + @wiki = @gollum_wiki.find_page(params[:id])
  59 + @wiki.delete if @wiki
  60 + redirect_to project_wiki_path(@project, :home), notice: "Page was successfully deleted"
  61 + end
  62 +
  63 + def git_access
  64 + end
  65 +
  66 + private
  67 +
  68 + def load_gollum_wiki
  69 + @gollum_wiki = GollumWiki.new(@project, current_user)
  70 +
  71 + # Call #wiki to make sure the Wiki Repo is initialized
  72 + @gollum_wiki.wiki
  73 + rescue GollumWiki::CouldNotCreateWikiError => ex
  74 + flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
  75 + redirect_to @project
  76 + return false
  77 + end
  78 +
  79 + def wiki_params
  80 + params[:wiki].slice(:title, :content, :format, :message)
  81 + end
  82 +
  83 + def content
  84 + params[:wiki][:content]
  85 + end
  86 +
  87 + def format
  88 + params[:wiki][:format]
  89 + end
  90 +
  91 + def message
  92 + params[:wiki][:message]
  93 + end
  94 +
  95 +end
... ...
app/controllers/projects_controller.rb
1   -class ProjectsController < ProjectResourceController
  1 +class ProjectsController < Projects::ApplicationController
2 2 skip_before_filter :project, only: [:new, :create]
3 3 skip_before_filter :repository, only: [:new, :create]
4 4  
... ... @@ -15,6 +15,7 @@ class ProjectsController &lt; ProjectResourceController
15 15 end
16 16  
17 17 def edit
  18 + render 'edit', layout: "project_settings"
18 19 end
19 20  
20 21 def create
... ... @@ -26,7 +27,7 @@ class ProjectsController &lt; ProjectResourceController
26 27 if @project.saved?
27 28 redirect_to @project
28 29 else
29   - render action: "new"
  30 + render "new"
30 31 end
31 32 end
32 33 format.js
... ... @@ -42,7 +43,7 @@ class ProjectsController &lt; ProjectResourceController
42 43 format.html { redirect_to edit_project_path(@project), notice: 'Project was successfully updated.' }
43 44 format.js
44 45 else
45   - format.html { render action: "edit" }
  46 + format.html { render "edit", layout: "project_settings" }
46 47 format.js
47 48 end
48 49 end
... ... @@ -89,7 +90,7 @@ class ProjectsController &lt; ProjectResourceController
89 90 redirect_to(@forked_project, notice: 'Project was successfully forked.')
90 91 else
91 92 @title = 'Fork project'
92   - render action: "fork"
  93 + render "fork"
93 94 end
94 95 end
95 96 format.js
... ... @@ -100,7 +101,7 @@ class ProjectsController &lt; ProjectResourceController
100 101 @suggestions = {
101 102 emojis: Emoji.names,
102 103 issues: @project.issues.select([:id, :title, :description]),
103   - members: @project.users.select([:username, :name]).order(:username)
  104 + members: @project.team.members.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
104 105 }
105 106  
106 107 respond_to do |format|
... ...
app/controllers/protected_branches_controller.rb
... ... @@ -1,26 +0,0 @@
1   -class ProtectedBranchesController < ProjectResourceController
2   - # Authorize
3   - before_filter :authorize_read_project!
4   - before_filter :require_non_empty_project
5   -
6   - before_filter :authorize_admin_project!, only: [:destroy, :create]
7   -
8   - def index
9   - @branches = @project.protected_branches.all
10   - @protected_branch = @project.protected_branches.new
11   - end
12   -
13   - def create
14   - @project.protected_branches.create(params[:protected_branch])
15   - redirect_to project_protected_branches_path(@project)
16   - end
17   -
18   - def destroy
19   - @project.protected_branches.find(params[:id]).destroy
20   -
21   - respond_to do |format|
22   - format.html { redirect_to project_protected_branches_path }
23   - format.js { render nothing: true }
24   - end
25   - end
26   -end