Commit 3bb8c17cc33fa1c3f7929c83ff114d0e0fbfb56b

Authored by Dmitriy Zaporozhets
2 parents 7fab63b4 2876f5d5

Merge branch 'master' of https://github.com/gitlabhq/gitlabhq

CONTRIBUTING.md
... ... @@ -107,9 +107,10 @@ For examples of feedback on merge requests please look at already [closed merge
107 107  
108 108 ## Style guides
109 109 1. [Ruby](https://github.com/bbatsov/ruby-style-guide)
110   -2. [Rails](https://github.com/bbatsov/rails-style-guide)
111   -3. [Formatting](https://github.com/thoughtbot/guides/tree/master/style#formatting)
112   -4. [Naming](https://github.com/thoughtbot/guides/tree/master/style#naming)
113   -8. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
114   -7. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
115   -9. [Shell commands](doc/development/shell_commands.md)
  110 +1. [Rails](https://github.com/bbatsov/rails-style-guide)
  111 +1. [Formatting](https://github.com/thoughtbot/guides/tree/master/style#formatting)
  112 +1. [Naming](https://github.com/thoughtbot/guides/tree/master/style#naming)
  113 +1. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
  114 +1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
  115 +1. [Shell commands](doc/development/shell_commands.md)
  116 +1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
... ...
app/assets/stylesheets/application.scss
... ... @@ -12,10 +12,7 @@
12 12 *= require nprogress-bootstrap
13 13 */
14 14  
15   -@import "main/variables.scss";
16   -@import "main/mixins.scss";
17   -@import "main/fonts.scss";
18   -@import "main/layout.scss";
  15 +@import "main/*";
19 16  
20 17 /**
21 18 * Customized Twitter bootstrap
... ... @@ -31,64 +28,22 @@
31 28 /**
32 29 * Generic css (forms, nav etc):
33 30 */
34   -@import "generic/avatar.scss";
35   -@import "generic/common.scss";
36   -@import "generic/typography.scss";
37   -@import "generic/buttons.scss";
38   -@import "generic/blocks.scss";
39   -@import "generic/ui_box.scss";
40   -@import "generic/issue_box.scss";
41   -@import "generic/files.scss";
42   -@import "generic/lists.scss";
43   -@import "generic/flash.scss";
44   -@import "generic/forms.scss";
45   -@import "generic/selects.scss";
46   -@import "generic/highlight.scss";
47   -@import "generic/jquery.scss";
  31 +@import "generic/*";
48 32  
49 33 /**
50 34 * Page specific styles (issues, projects etc):
51 35 */
52   -@import "sections/header.scss";
53   -@import "sections/nav.scss";
54   -@import "sections/commits.scss";
55   -@import "sections/diff.scss";
56   -@import "sections/issues.scss";
57   -@import "sections/projects.scss";
58   -@import "sections/snippets.scss";
59   -@import "sections/votes.scss";
60   -@import "sections/merge_requests.scss";
61   -@import "sections/graph.scss";
62   -@import "sections/events.scss";
63   -@import "sections/themes.scss";
64   -@import "sections/tree.scss";
65   -@import "sections/notes.scss";
66   -@import "sections/profile.scss";
67   -@import "sections/login.scss";
68   -@import "sections/editor.scss";
69   -@import "sections/admin.scss";
70   -@import "sections/wiki.scss";
71   -@import "sections/wall.scss";
72   -@import "sections/dashboard.scss";
73   -@import "sections/stat_graph.scss";
74   -@import "sections/groups.scss";
  36 +@import "sections/*";
75 37  
76 38 /**
77 39 * Code highlight
78 40 */
79   -@import "highlight/white.scss";
80   -@import "highlight/dark.scss";
81   -@import "highlight/solarized_dark.scss";
82   -@import "highlight/monokai.scss";
  41 +@import "highlight/*";
83 42  
84 43 /**
85 44 * UI themes:
86 45 */
87   -@import "themes/ui_basic.scss";
88   -@import "themes/ui_mars.scss";
89   -@import "themes/ui_modern.scss";
90   -@import "themes/ui_gray.scss";
91   -@import "themes/ui_color.scss";
  46 +@import "themes/*";
92 47  
93 48 /**
94 49 * Styles for JS behaviors.
... ...
config/gitlab.yml.example
... ... @@ -19,6 +19,11 @@ production: &base
19 19 port: 80
20 20 https: false
21 21  
  22 + # Uncommment this line below if your ssh host is different from HTTP/HTTPS one
  23 + # (you'd obviously need to replace ssh.host_example.com with your own host).
  24 + # Otherwise, ssh host will be set to the `host:` value above
  25 + # ssh_host: ssh.host_example.com
  26 +
22 27 # Uncomment and customize the last line to run in a non-root path
23 28 # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
24 29 # Note that four settings need to be changed for this to work.
... ...
config/initializers/1_settings.rb
... ... @@ -117,7 +117,7 @@ Settings.gitlab_shell['hooks_path'] ||= Settings.gitlab['user_home'] + '/gitla
117 117 Settings.gitlab_shell['receive_pack'] = true if Settings.gitlab_shell['receive_pack'].nil?
118 118 Settings.gitlab_shell['upload_pack'] = true if Settings.gitlab_shell['upload_pack'].nil?
119 119 Settings.gitlab_shell['repos_path'] ||= Settings.gitlab['user_home'] + '/repositories/'
120   -Settings.gitlab_shell['ssh_host'] ||= (Settings.gitlab.host || 'localhost')
  120 +Settings.gitlab_shell['ssh_host'] ||= (Settings.gitlab.ssh_host || Settings.gitlab.host || 'localhost')
121 121 Settings.gitlab_shell['ssh_port'] ||= 22
122 122 Settings.gitlab_shell['ssh_user'] ||= Settings.gitlab.user
123 123 Settings.gitlab_shell['owner_group'] ||= Settings.gitlab.user
... ...
doc/api/merge_requests.md
... ... @@ -105,10 +105,11 @@ POST /projects/:id/merge_requests
105 105 Parameters:
106 106  
107 107 + `id` (required) - The ID of a project
108   -+ `source_branch` (required) - The source branch
109   -+ `target_branch` (required) - The target branch
110   -+ `assignee_id` (optional) - Assignee user ID
111   -+ `title` (required) - Title of MR
  108 ++ `source_branch` (required) - The source branch
  109 ++ `target_branch` (required) - The target branch
  110 ++ `assignee_id` (optional) - Assignee user ID
  111 ++ `title` (required) - Title of MR
  112 ++ `target_project_id` (optional) - The target project (numeric id)
112 113  
113 114 ```json
114 115 {
... ...
doc/api/users.md
... ... @@ -220,6 +220,18 @@ Parameters:
220 220  
221 221 + **none**
222 222  
  223 +## List SSH keys for user
  224 +
  225 +Get a list of a specified user's SSH keys. Available only for admin
  226 +
  227 +```
  228 +GET /users/:uid/keys
  229 +```
  230 +
  231 +Parameters:
  232 +
  233 ++ `uid` (required) - id of specified user
  234 +
223 235  
224 236 ## Single SSH key
225 237  
... ... @@ -286,3 +298,18 @@ Parameters:
286 298  
287 299 + `id` (required) - SSH key ID
288 300  
  301 +## Delete SSH key
  302 +
  303 +Deletes key owned by a specified user. Available only for admin.
  304 +
  305 +```
  306 +DELETE /users/:uid/keys/:id
  307 +```
  308 +
  309 +Parameters:
  310 +
  311 ++ `uid` (required) - id of specified user
  312 ++ `id` (required) - SSH key ID
  313 +
  314 +Will return `200 Ok` on success, or `404 Not found` if either user or key cannot be found.
  315 +
... ...
doc/update/upgrader.md
... ... @@ -46,4 +46,8 @@ If all items are green, then congratulations upgrade is complete!
46 46  
47 47 You've read through the entire guide, and probably did all the steps manually. Here is a one liner for convenience, the next time you upgrade:
48 48  
49   - cd /home/git/gitlab; sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; sudo service gitlab stop; sudo -u git -H ruby script/upgrade.rb -y; sudo service gitlab start; sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
  49 +```bash
  50 +cd /home/git/gitlab; sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \
  51 + sudo service gitlab stop; sudo -u git -H ruby script/upgrade.rb -y; sudo service gitlab start; \
  52 + sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
  53 +```
... ...
lib/api/users.rb
... ... @@ -113,6 +113,45 @@ module API
113 113 end
114 114 end
115 115  
  116 + # Get ssh keys of a specified user. Only available to admin users.
  117 + #
  118 + # Parameters:
  119 + # uid (required) - The ID of a user
  120 + # Example Request:
  121 + # GET /users/:uid/keys
  122 + get ':uid/keys' do
  123 + authenticated_as_admin!
  124 + user = User.find_by(id: params[:uid])
  125 + if user
  126 + present user.keys, with: Entities::SSHKey
  127 + else
  128 + not_found!
  129 + end
  130 + end
  131 +
  132 + # Delete existing ssh key of a specified user. Only available to admin
  133 + # users.
  134 + #
  135 + # Parameters:
  136 + # uid (required) - The ID of a user
  137 + # id (required) - SSH Key ID
  138 + # Example Request:
  139 + # DELETE /users/:uid/keys/:id
  140 + delete ':uid/keys/:id' do
  141 + authenticated_as_admin!
  142 + user = User.find_by(id: params[:uid])
  143 + if user
  144 + begin
  145 + key = user.keys.find params[:id]
  146 + key.destroy
  147 + rescue ActiveRecord::RecordNotFound
  148 + not_found!
  149 + end
  150 + else
  151 + not_found!
  152 + end
  153 + end
  154 +
116 155 # Delete user. Available only for admin
117 156 #
118 157 # Example Request:
... ...
spec/requests/api/users_spec.rb
... ... @@ -242,6 +242,67 @@ describe API::API, api: true do
242 242 end
243 243 end
244 244  
  245 + describe 'GET /user/:uid/keys' do
  246 + before { admin }
  247 +
  248 + context 'when unauthenticated' do
  249 + it 'should return authentication error' do
  250 + get api("/users/#{user.id}/keys")
  251 + response.status.should == 401
  252 + end
  253 + end
  254 +
  255 + context 'when authenticated' do
  256 + it 'should return 404 for non-existing user' do
  257 + get api('/users/999999/keys', admin)
  258 + response.status.should == 404
  259 + end
  260 +
  261 + it 'should return array of ssh keys' do
  262 + user.keys << key
  263 + user.save
  264 + get api("/users/#{user.id}/keys", admin)
  265 + response.status.should == 200
  266 + json_response.should be_an Array
  267 + json_response.first['title'].should == key.title
  268 + end
  269 + end
  270 + end
  271 +
  272 + describe 'DELETE /user/:uid/keys/:id' do
  273 + before { admin }
  274 +
  275 + context 'when unauthenticated' do
  276 + it 'should return authentication error' do
  277 + delete api("/users/#{user.id}/keys/42")
  278 + response.status.should == 401
  279 + end
  280 + end
  281 +
  282 + context 'when authenticated' do
  283 + it 'should delete existing key' do
  284 + user.keys << key
  285 + user.save
  286 + expect {
  287 + delete api("/users/#{user.id}/keys/#{key.id}", admin)
  288 + }.to change { user.keys.count }.by(-1)
  289 + response.status.should == 200
  290 + end
  291 +
  292 + it 'should return 404 error if user not found' do
  293 + user.keys << key
  294 + user.save
  295 + delete api("/users/999999/keys/#{key.id}", admin)
  296 + response.status.should == 404
  297 + end
  298 +
  299 + it 'should return 404 error if key not foud' do
  300 + delete api("/users/#{user.id}/keys/42", admin)
  301 + response.status.should == 404
  302 + end
  303 + end
  304 + end
  305 +
245 306 describe "DELETE /users/:id" do
246 307 before { admin }
247 308  
... ...