diff options
34 files changed, 337 insertions, 237 deletions
@@ -16,6 +16,7 @@ gem "pg", group: :postgres # Auth gem "devise", '~> 2.2' +gem "devise-async" gem 'omniauth', "~> 1.1.3" gem 'omniauth-google-oauth2' gem 'omniauth-twitter' diff --git a/Gemfile.lock b/Gemfile.lock index ce3aeb7994b..667ea9f1299 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,6 +106,8 @@ GEM orm_adapter (~> 0.1) railties (~> 3.1) warden (~> 1.2.1) + devise-async (0.8.0) + devise (>= 2.2, < 3.2) diff-lcs (1.2.4) dotenv (0.8.0) email_spec (1.4.0) @@ -564,6 +566,7 @@ DEPENDENCIES d3_rails (~> 3.1.4) database_cleaner devise (~> 2.2) + devise-async email_spec enumerize factory_girl_rails diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 1572227ec3a..a3156ec10fc 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -270,27 +270,6 @@ li.note { } } -.oauth_select_holder { - padding: 20px; - img { - padding: 5px; - margin-right: 10px; - } - .active { - img { - border: 1px solid #ccc; - background: $hover; - @include border-radius(5px); - } - } -} - -.btn-build-token { - float: left; - padding: 6px 20px; - margin-right: 12px; -} - .gitlab-promo { a { color: #aaa; diff --git a/app/assets/stylesheets/sections/profile.scss b/app/assets/stylesheets/sections/profile.scss index 5c7516ce6f9..21f4ed0577d 100644 --- a/app/assets/stylesheets/sections/profile.scss +++ b/app/assets/stylesheets/sections/profile.scss @@ -4,3 +4,41 @@ margin-bottom: 0; } } + +.account-page { + fieldset { + margin-bottom: 15px; + border-bottom: 1px dashed #ddd; + padding-bottom: 15px; + + &:last-child { + border: none; + } + + legend { + border: none; + margin: 0; + } + } +} + +.oauth_select_holder { + img { + padding: 2px; + margin-right: 10px; + } + .active { + img { + border: 1px solid #4BD; + background: $hover; + @include border-radius(5px); + } + } +} + +.btn-build-token { + float: left; + padding: 6px 20px; + margin-right: 12px; +} + diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb new file mode 100644 index 00000000000..fe121691a10 --- /dev/null +++ b/app/controllers/profiles/accounts_controller.rb @@ -0,0 +1,7 @@ +class Profiles::AccountsController < ApplicationController + layout "profile" + + def show + @user = current_user + end +end diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb index 432899f857d..df6954554ea 100644 --- a/app/controllers/profiles/passwords_controller.rb +++ b/app/controllers/profiles/passwords_controller.rb @@ -1,10 +1,11 @@ class Profiles::PasswordsController < ApplicationController - layout 'navless' + layout :determine_layout - skip_before_filter :check_password_expiration + skip_before_filter :check_password_expiration, only: [:new, :create] before_filter :set_user before_filter :set_title + before_filter :authorize_change_password! def new end @@ -26,6 +27,32 @@ class Profiles::PasswordsController < ApplicationController end end + def edit + end + + def update + password_attributes = params[:user].select do |key, value| + %w(password password_confirmation).include?(key.to_s) + end + + unless @user.valid_password?(params[:user][:current_password]) + redirect_to edit_profile_password_path, alert: 'You must provide a valid current password' + return + end + + if @user.update_attributes(password_attributes) + flash[:notice] = "Password was successfully updated. Please login with it" + redirect_to new_user_session_path + else + render 'edit' + end + end + + def reset + current_user.send_reset_password_instructions + redirect_to edit_profile_password_path, notice: 'We sent you an email with reset password instructions' + end + private def set_user @@ -35,4 +62,16 @@ class Profiles::PasswordsController < ApplicationController def set_title @title = "New password" end + + def determine_layout + if [:new, :create].include?(action_name.to_sym) + 'navless' + else + 'profile' + end + end + + def authorize_change_password! + return render_404 if @user.ldap_user? + end end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 75f12f8a6af..47cfc5e63f5 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -2,7 +2,6 @@ class ProfilesController < ApplicationController include ActionView::Helpers::SanitizeHelper before_filter :user - before_filter :authorize_change_password!, only: :update_password before_filter :authorize_change_username!, only: :update_username layout 'profile' @@ -13,9 +12,6 @@ class ProfilesController < ApplicationController def design end - def account - end - def update if @user.update_attributes(params[:user]) flash[:notice] = "Profile was successfully updated" @@ -29,33 +25,12 @@ class ProfilesController < ApplicationController end end - def token - end - - def update_password - password_attributes = params[:user].select do |key, value| - %w(password password_confirmation).include?(key.to_s) - end - - unless @user.valid_password?(params[:user][:current_password]) - redirect_to account_profile_path, alert: 'You must provide a valid current password' - return - end - - if @user.update_attributes(password_attributes) - flash[:notice] = "Password was successfully updated. Please login with it" - redirect_to new_user_session_path - else - render 'account' - end - end - def reset_private_token if current_user.reset_authentication_token! flash[:notice] = "Token was successfully updated" end - redirect_to account_profile_path + redirect_to profile_account_path end def history @@ -76,10 +51,6 @@ class ProfilesController < ApplicationController @user = current_user end - def authorize_change_password! - return render_404 if @user.ldap_user? - end - def authorize_change_username! return render_404 unless @user.can_change_username? end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 254b7351d98..0e48889ebf8 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -105,7 +105,7 @@ module ApplicationHelper groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } } default_nav = [ - { label: "My Profile", url: profile_path }, + { label: "My Profile settings", url: profile_path }, { label: "My SSH Keys", url: profile_keys_path }, { label: "My Dashboard", url: root_path }, { label: "Admin Section", url: admin_root_path }, diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index cd3a262cddd..d4f1a8f741f 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -5,10 +5,10 @@ module ProjectsHelper def link_to_project project link_to project do - title = content_tag(:strong, project.name) + title = content_tag(:span, project.name, class: 'projet-name') if project.namespace - namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'tiny') + namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'namespace-name') title = namespace + title end @@ -131,4 +131,13 @@ module ProjectsHelper "your@email.com" end end + + def repository_size + "#{@project.repository.size} MB" + rescue + # In order to prevent 500 error + # when application cannot allocate memory + # to calculate repo size - just show 'Unknown' + 'unknown' + end end diff --git a/app/models/user.rb b/app/models/user.rb index 5d742578c42..29c53b88331 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -42,7 +42,7 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class User < ActiveRecord::Base - devise :database_authenticatable, :token_authenticatable, :lockable, + devise :database_authenticatable, :token_authenticatable, :lockable, :async, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :registerable attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, @@ -398,4 +398,4 @@ class User < ActiveRecord::Base self end -end +end
\ No newline at end of file diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb index acbb719b69a..b82e7d9a03f 100644 --- a/app/observers/project_observer.rb +++ b/app/observers/project_observer.rb @@ -14,6 +14,11 @@ class ProjectObserver < BaseObserver log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") end + + if project.wiki_enabled? + # force the creation of a wiki, + GollumWiki.new(project, project.owner).wiki + end end def after_update(project) diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 05a524278a2..df9fc687478 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -117,11 +117,7 @@ - tm = project.team.find_tm(@user.id) %li.users_project = link_to admin_project_path(project), class: dom_class(project) do - - if project.namespace - = project.namespace.human_name - \/ - %strong.well-title - = truncate(project.name, length: 45) + = project.name_with_namespace - if tm .pull-right diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index adba9a5f619..f181df23eb4 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -7,7 +7,7 @@ = link_to project_commits_path(event.project, event.ref_name) do %strong= truncate(event.ref_name, length: 30) at - %strong= link_to_project event.project + = link_to_project event.project - if event.push_with_commits? - project = event.project diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index aeb6aba1ad8..80c42fe6387 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -30,11 +30,11 @@ = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do %i.icon-plus %li - = link_to profile_path, title: "My profile", class: 'has_bottom_tooltip', 'data-original-title' => 'My profile' do + = link_to profile_path, title: "Profile settings", class: 'has_bottom_tooltip', 'data-original-title' => 'Profile settings"' do %i.icon-user %li = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do %i.icon-signout %li = link_to current_user, class: "profile-pic", id: 'profile-pic' do - = image_tag avatar_icon(current_user.email, 26), alt: '' + = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 7c3acfc398a..d44cb975ea5 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -2,8 +2,11 @@ = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: "Profile" do %i.icon-home - = nav_link(path: 'profiles#account') do - = link_to "Account", account_profile_path + = nav_link(controller: :accounts) do + = link_to "Account", profile_account_path + - unless current_user.ldap_user? + = nav_link(controller: :passwords) do + = link_to "Password", edit_profile_password_path = nav_link(controller: :notifications) do = link_to "Notifications", profile_notifications_path = nav_link(controller: :keys) do diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml deleted file mode 100644 index 42c7ec051cb..00000000000 --- a/app/views/profiles/account.html.haml +++ /dev/null @@ -1,141 +0,0 @@ -%h3.page-title - Account settings -%p.light - You can change your password, username and private token here. - - if current_user.ldap_user? - Some options are unavailable for LDAP accounts -%hr - - -.row - .span2 - %ul.nav.nav-pills.nav-stacked.nav-stacked-menu - %li.active - = link_to '#tab-token', 'data-toggle' => 'tab' do - Private Token - %li - = link_to '#tab-password', 'data-toggle' => 'tab' do - Password - - - if show_profile_social_tab? - %li - = link_to '#tab-social', 'data-toggle' => 'tab' do - Social Accounts - - - if show_profile_username_tab? - %li - = link_to '#tab-username', 'data-toggle' => 'tab' do - Change Username - - - if show_profile_remove_tab? - %li - = link_to '#tab-remove', 'data-toggle' => 'tab' do - Remove Account - .span10 - .tab-content - .tab-pane.active#tab-token - %fieldset.update-token - %legend - Private token - %span.cred.pull-right - keep it secret! - %div - = form_for @user, url: reset_private_token_profile_path, method: :put do |f| - .data - %p.slead - Your private token is used to access application resources without authentication. - %br - It can be used for atom feeds or the API. - %p.cgray - - if current_user.private_token - = text_field_tag "token", current_user.private_token, class: "input-xxlarge large_text input-xpadding" - = f.submit 'Reset', confirm: "Are you sure?", class: "btn btn-primary btn-build-token" - - else - %span You don`t have one yet. Click generate to fix it. - = f.submit 'Generate', class: "btn success btn-build-token" - - .tab-pane#tab-password - %fieldset.update-password - %legend Password - - if current_user.ldap_user? - %h3.nothing_here_message Not available for LDAP user - - else - = form_for @user, url: update_password_profile_path, method: :put do |f| - %div - %p.slead - You must provide current password in order to change it. - %br - After a successful password update you will be redirected to login page where you should login with your new password - -if @user.errors.any? - .alert.alert-error - %ul - - @user.errors.full_messages.each do |msg| - %li= msg - .control-group - = f.label :current_password, class: 'cgreen' - .controls= f.password_field :current_password, required: true - .control-group - = f.label :password, 'New password' - .controls= f.password_field :password, required: true - .control-group - = f.label :password_confirmation - .controls - = f.password_field :password_confirmation, required: true - .control-group - .controls - = f.submit 'Save password', class: "btn btn-save" - - - if show_profile_social_tab? - .tab-pane#tab-social - %fieldset - %legend Social Accounts - .oauth_select_holder - %p.hint Tip: Click on icon to activate signin with one of the following services - - enabled_social_providers.each do |provider| - %span{class: oauth_active_class(provider) } - = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider) - - - if show_profile_username_tab? - .tab-pane#tab-username - %fieldset.update-username - %legend - Username - %small.cred.pull-right - Changing your username can have unintended side effects! - = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| - %div - .control-group - = f.label :username - .controls - = f.text_field :username, required: true - - %span.loading-gif.hide= image_tag "ajax_loader.gif" - %span.update-success.cgreen.hide - %i.icon-ok - Saved - %span.update-failed.cred.hide - %i.icon-remove - Failed - %ul.cred - %li This will change the web URL for personal projects. - %li This will change the git path to repositories for personal projects. - .controls - = f.submit 'Save username', class: "btn btn-save" - - - if show_profile_remove_tab? - .tab-pane#tab-remove - %fieldset.remove-account - %legend - Remove account - %div - %p Deleting an account has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = current_user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored - - if current_user.solo_owned_groups.present? - %li - Next groups will be abandoned. You should transfer or remove them: - %strong #{current_user.solo_owned_groups.map(&:name).join(', ')} - = link_to 'Delete account', user_registration_path, confirm: "REMOVE #{current_user.name}? Are you sure?", method: :delete, class: "btn btn-remove" diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml new file mode 100644 index 00000000000..453ef8b60db --- /dev/null +++ b/app/views/profiles/accounts/show.html.haml @@ -0,0 +1,73 @@ +%h3.page-title + Account settings +%p.light + You can change your username and private token here. + - if current_user.ldap_user? + Some options are unavailable for LDAP accounts +%hr + + +.account-page + %fieldset.update-token + %legend + Private token + %div + = form_for @user, url: reset_private_token_profile_path, method: :put do |f| + .data + %p + Your private token is used to access application resources without authentication. + %br + It can be used for atom feeds or the API. + %span.cred + Keep it secret! + + %p.cgray + - if current_user.private_token + = text_field_tag "token", current_user.private_token, class: "input-xlarge input-xpadding pull-left" + = f.submit 'Reset', confirm: "Are you sure?", class: "btn btn-primary btn-build-token prepend-left-10" + - else + %span You don`t have one yet. Click generate to fix it. + = f.submit 'Generate', class: "btn success btn-build-token" + + + - if show_profile_social_tab? + %fieldset + %legend Social Accounts + .oauth_select_holder.append-bottom-10 + %p Click on icon to activate signin with one of the following services + - enabled_social_providers.each do |provider| + %span{class: oauth_active_class(provider) } + = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider) + + - if show_profile_username_tab? + %fieldset.update-username + %legend + Username + = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| + %p + Changing your username will change path to all personl projects! + %div + = f.text_field :username, required: true, class: 'input-xlarge input-xpadding' + + %span.loading-gif.hide= image_tag "ajax_loader.gif" + %p.light + = user_url(@user) + %div + = f.submit 'Save username', class: "btn btn-save" + + - if show_profile_remove_tab? + %fieldset.remove-account + %legend + Remove account + %div + %p Deleting an account has the following effects: + %ul + %li All user content like authored issues, snippets, comments will be removed + - rp = current_user.personal_projects.count + - unless rp.zero? + %li #{pluralize rp, 'personal project'} will be removed and cannot be restored + - if current_user.solo_owned_groups.present? + %li + Next groups will be abandoned. You should transfer or remove them: + %strong #{current_user.solo_owned_groups.map(&:name).join(', ')} + = link_to 'Delete account', user_registration_path, confirm: "REMOVE #{current_user.name}? Are you sure?", method: :delete, class: "btn btn-remove" diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml new file mode 100644 index 00000000000..a5fa6e7f186 --- /dev/null +++ b/app/views/profiles/passwords/edit.html.haml @@ -0,0 +1,32 @@ +%h3.page-title Password +%p.light + Change your password or recover your current one. +%hr +.update-password + = form_for @user, url: profile_password_path, method: :put do |f| + %div + %p.slead + You must provide current password in order to change it. + %br + After a successful password update you will be redirected to login page where you should login with your new password + -if @user.errors.any? + .alert.alert-error + %ul + - @user.errors.full_messages.each do |msg| + %li= msg + .control-group + = f.label :current_password + .controls + = f.password_field :current_password, required: true + %div + = link_to "Forgot your password?", reset_profile_password_path, method: :put + + .control-group + = f.label :password, 'New password' + .controls= f.password_field :password, required: true + .control-group + = f.label :password_confirmation + .controls + = f.password_field :password_confirmation, required: true + .form-actions + = f.submit 'Save password', class: "btn btn-save" diff --git a/app/views/profiles/update_username.js.haml b/app/views/profiles/update_username.js.haml index abd90269c93..249680bcab6 100644 --- a/app/views/profiles/update_username.js.haml +++ b/app/views/profiles/update_username.js.haml @@ -1,6 +1,6 @@ - if @user.valid? :plain - $('.update-username .update-success').show(); + new Flash("Username sucessfully changed", "notice") - else :plain - $('.update-username .update-failed').show(); + new Flash("Username change failed - #{@user.errors.full_messages.first}", "alert") diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 06ca5169dff..aefcd833952 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -17,7 +17,7 @@ %p %p %span.light Repo size is - #{@project.repository.size} MB + = repository_size %p %span.light Created at #{@project.created_at.stamp('Aug 22, 2013')} diff --git a/app/views/users/_projects.html.haml b/app/views/users/_projects.html.haml index f1b2c8dd7f7..a61c6ba5b86 100644 --- a/app/views/users/_projects.html.haml +++ b/app/views/users/_projects.html.haml @@ -3,9 +3,4 @@ %ul.well-list - @projects.each do |project| %li - = link_to project_path(project), class: dom_class(project) do - - if project.namespace - = project.namespace.human_name - \/ - %strong.well-title - = truncate(project.name, length: 45) + = link_to_project project diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 801081bb30d..53a0a9232a4 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -7,7 +7,7 @@ .pull-right = link_to profile_path, class: 'btn' do %i.icon-edit - Edit Profile + Edit Profile settings %br %small #{@user.username} %br diff --git a/config/initializers/devise_async.rb b/config/initializers/devise_async.rb new file mode 100644 index 00000000000..05a1852cdbd --- /dev/null +++ b/config/initializers/devise_async.rb @@ -0,0 +1 @@ +Devise::Async.backend = :sidekiq diff --git a/config/routes.rb b/config/routes.rb index 612a7327ec5..6d7358608ea 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -99,19 +99,21 @@ Gitlab::Application.routes.draw do # resource :profile, only: [:show, :update] do member do - get :account get :history - get :token get :design - put :update_password put :reset_private_token put :update_username end scope module: :profiles do + resource :account, only: [:show, :update] resource :notifications, only: [:show, :update] - resource :password, only: [:new, :create] + resource :password, only: [:new, :create, :edit, :update] do + member do + put :reset + end + end resources :keys resources :groups, only: [:index] do member do diff --git a/doc/api/repositories.md b/doc/api/repositories.md index cb0626972e5..2769c22d6aa 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -356,3 +356,16 @@ Parameters: + `id` (required) - The ID of a project + `sha` (required) - The commit or branch name + `filepath` (required) - The path the file + + +## Get file archive + +Get a an archive of the repository + +``` +GET /projects/:id/repository/archive +``` + +Parameters: ++ `id` (required) - The ID of a project ++ `sha` (optional) - The commit sha to download defaults to the tip of the default branch
\ No newline at end of file diff --git a/features/profile/profile.feature b/features/profile/profile.feature index 6d210fb4df7..6198fd2b306 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -12,13 +12,13 @@ Feature: Profile And I should see new contact info Scenario: I change my password without old one - Given I visit profile account page + Given I visit profile password page When I try change my password w/o old one Then I should see a missing password error message - And I should be redirected to account page + And I should be redirected to password page Scenario: I change my password - Given I visit profile account page + Given I visit profile password page Then I change my password And I should be redirected to sign in page @@ -30,13 +30,13 @@ Feature: Profile Scenario: My password is expired Given my password is expired And I am not an ldap user - And I visit profile account page + Given I visit profile password page Then I redirected to expired password page And I submit new password And I redirected to sign in page Scenario: I unsuccessfully change my password - Given I visit profile account page + Given I visit profile password page When I unsuccessfully change my password Then I should see a password error message diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index ea7550a6f22..753e2c19bcb 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -133,8 +133,12 @@ class Profile < Spinach::FeatureSteps current_path.should == new_user_session_path end + step 'I should be redirected to password page' do + current_path.should == edit_profile_password_path + end + step 'I should be redirected to account page' do - current_path.should == account_profile_path + current_path.should == profile_account_path end step 'I click on my profile picture' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index c30eccce1c5..156fa5bab4e 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -65,8 +65,12 @@ module SharedPaths visit profile_path end + step 'I visit profile password page' do + visit edit_profile_password_path + end + step 'I visit profile account page' do - visit account_profile_path + visit profile_account_path end step 'I visit profile SSH keys page' do diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 1a911eae2bb..c9422fdb165 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -144,7 +144,7 @@ module API trees = [] %w(trees blobs submodules).each do |type| - trees += tree.send(type).map { |t| { name: t.name, type: type.singularize, mode: t.mode, id: t.id } } + trees += tree.send(type).map { |t| {name: t.name, type: type.singularize, mode: t.mode, id: t.id} } end trees @@ -176,6 +176,34 @@ module API content_type blob.mime_type present blob.data end + + # Get a an archive of the repository + # + # Parameters: + # id (required) - The ID of a project + # sha (optional) - the commit sha to download defaults to the tip of the default branch + # Example Request: + # GET /projects/:id/repository/archive + get ":id/repository/archive" do + authorize! :download_code, user_project + repo = user_project.repository + ref = params[:sha] + storage_path = Rails.root.join("tmp", "repositories") + + file_path = repo.archive_repo(ref, storage_path) + if file_path && File.exists?(file_path) + data = File.open(file_path, 'rb').read + + header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\"" + content_type 'application/x-gzip' + + env['api.format'] = :binary + + present data + else + not_found! + end + end end end end diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 80c9f5d7f14..b67ce3c67f1 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -12,7 +12,7 @@ describe "Profile account page" do describe "when signup is enabled" do before do Gitlab.config.gitlab.stub(:signup_enabled).and_return(true) - visit account_profile_path + visit profile_account_path end it { page.should have_content("Remove account") } @@ -26,12 +26,12 @@ describe "Profile account page" do describe "when signup is disabled" do before do Gitlab.config.gitlab.stub(:signup_enabled).and_return(false) - visit account_profile_path + visit profile_account_path end it "should not have option to remove account" do page.should_not have_content("Remove account") - current_path.should == account_profile_path + current_path.should == profile_account_path end end end diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb index 7754b28347a..078c257538f 100644 --- a/spec/features/security/profile_access_spec.rb +++ b/spec/features/security/profile_access_spec.rb @@ -29,7 +29,7 @@ describe "Users Security" do end describe "GET /profile/account" do - subject { account_profile_path } + subject { profile_account_path } it { should be_allowed_for @u1 } it { should be_allowed_for :admin } diff --git a/spec/observers/users_project_observer_spec.rb b/spec/observers/users_project_observer_spec.rb index e33d8cc50fd..e7c624fce59 100644 --- a/spec/observers/users_project_observer_spec.rb +++ b/spec/observers/users_project_observer_spec.rb @@ -65,4 +65,30 @@ describe UsersProjectObserver do @users_project.destroy end end -end + + describe "#after_create" do + context 'wiki_enabled creates repository directory' do + context 'wiki_enabled true creates wiki repository directory' do + before do + @project = create(:project, wiki_enabled: true) + @path = GollumWiki.new(@project, user).send(:path_to_repo) + end + + after do + FileUtils.rm_rf(@path) + end + + it { File.exists?(@path).should be_true } + end + + context 'wiki_enabled false does not create wiki repository directory' do + before do + @project = create(:project, wiki_enabled: false) + @path = GollumWiki.new(@project, user).send(:path_to_repo) + end + + it { File.exists?(@path).should be_false } + end + end + end +end
\ No newline at end of file diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index 2e509ea2933..9649c4d09c8 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -225,4 +225,16 @@ describe API::API do end end + describe "GET /projects/:id/repository/archive/:sha" do + it "should get the archive" do + get api("/projects/#{project.id}/repository/archive", user) + response.status.should == 200 + response.content_type.should == 'application/x-gzip' + end + + it "should return 404 for invalid sha" do + get api("/projects/#{project.id}/repository/archive/?sha=xxx", user) + response.status.should == 404 + end + end end diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 946ef7c28cb..1b1d19d26b1 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -128,7 +128,7 @@ end # profile_update PUT /profile/update(.:format) profile#update describe ProfilesController, "routing" do it "to #account" do - get("/profile/account").should route_to('profiles#account') + get("/profile/account").should route_to('profiles/accounts#show') end it "to #history" do |
