summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Garnier <guilherme.garnier@gmail.com>2015-10-03 11:46:29 -0500
committerGuilherme Garnier <guilherme.garnier@gmail.com>2015-10-03 11:46:29 -0500
commit1cfb48ddd005f599a453dcd9a4471fb003e6c222 (patch)
tree28037a6ffa676455ad64bdc3450d7d5099244a6c
parent848d7b2a2be28982d0f164d4e3a966c300e7c322 (diff)
parent662f8af497656754c7ad27c0250d2aae825b8545 (diff)
downloadgitlab-ce-1cfb48ddd005f599a453dcd9a4471fb003e6c222.tar.gz
Merge remote-tracking branch 'upstream/master'
-rw-r--r--CHANGELOG3
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock2
-rw-r--r--app/assets/stylesheets/base/layout.scss22
-rw-r--r--app/assets/stylesheets/generic/buttons.scss4
-rw-r--r--app/assets/stylesheets/generic/sidebar.scss11
-rw-r--r--app/assets/stylesheets/pages/projects.scss1
-rw-r--r--app/controllers/dashboard/projects_controller.rb1
-rw-r--r--app/controllers/passwords_controller.rb40
-rw-r--r--app/controllers/projects/services_controller.rb4
-rw-r--r--app/helpers/projects_helper.rb2
-rw-r--r--app/models/project.rb6
-rw-r--r--app/models/project_services/gitlab_ci_service.rb20
-rw-r--r--app/models/project_team.rb4
-rw-r--r--app/models/user.rb4
-rw-r--r--app/services/ci/create_project_service.rb30
-rw-r--r--app/services/git_push_service.rb2
-rw-r--r--app/services/projects/fork_service.rb8
-rw-r--r--app/views/dashboard/projects/starred.html.haml3
-rw-r--r--app/views/devise/passwords/new.html.haml2
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/notes/_note.html.haml6
-rw-r--r--app/views/shared/_field.html.haml7
-rw-r--r--config/locales/devise.en.yml104
-rw-r--r--doc/migrate_ci_to_ce/README.md9
-rw-r--r--features/project/service.feature1
-rw-r--r--features/steps/project/commits/commits.rb2
-rw-r--r--features/steps/project/services.rb4
-rw-r--r--features/steps/shared/project.rb2
-rw-r--r--spec/features/login_spec.rb2
-rw-r--r--spec/features/password_reset_spec.rb54
-rw-r--r--spec/helpers/projects_helper_spec.rb4
-rw-r--r--spec/models/project_services/gitlab_ci_service_spec.rb21
-rw-r--r--spec/models/project_spec.rb3
-rw-r--r--spec/models/project_team_spec.rb12
-rw-r--r--spec/models/user_spec.rb20
-rw-r--r--spec/services/ci/create_project_service_spec.rb37
-rw-r--r--spec/services/projects/fork_service_spec.rb12
39 files changed, 237 insertions, 238 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a8b43dd4608..ec23d0f1172 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.1.0 (unreleased)
+ - Fix bug where transferring a project would result in stale commit links (Stan Hu)
- Include full path of source and target branch names in New Merge Request page (Stan Hu)
- Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
- Add user preference to view activities as default dashboard (Stan Hu)
@@ -26,6 +27,8 @@ v 8.1.0 (unreleased)
- Show additions/deletions stats on merge request diff
- Remove footer text in emails (Zeger-Jan van de Weg)
- Ensure code blocks are properly highlighted after a note is updated
+ - Fix wrong access level badge on MR comments
+ - Hide password in the service settings form
v 8.0.3
- Fix URL shown in Slack notifications
diff --git a/Gemfile b/Gemfile
index f1674c560e2..4938cbf8b80 100644
--- a/Gemfile
+++ b/Gemfile
@@ -270,6 +270,8 @@ group :development, :test do
gem 'rubocop', '~> 0.28.0', require: false
gem 'coveralls', '~> 0.8.2', require: false
gem 'simplecov', '~> 0.10.0', require: false
+
+ gem 'benchmark-ips', require: false
end
group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 6472221bc54..1dd56cd9c8c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -66,6 +66,7 @@ GEM
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
bcrypt (3.1.10)
+ benchmark-ips (2.3.0)
better_errors (1.0.1)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
@@ -795,6 +796,7 @@ DEPENDENCIES
asciidoctor (~> 1.5.2)
attr_encrypted (~> 1.3.4)
awesome_print (~> 1.2.0)
+ benchmark-ips
better_errors (~> 1.0.1)
binding_of_caller (~> 0.7.2)
bootstrap-sass (~> 3.0)
diff --git a/app/assets/stylesheets/base/layout.scss b/app/assets/stylesheets/base/layout.scss
index b91c15d8910..f0569a5e673 100644
--- a/app/assets/stylesheets/base/layout.scss
+++ b/app/assets/stylesheets/base/layout.scss
@@ -1,18 +1,34 @@
html {
overflow-y: scroll;
+ height: 100%;
+ margin: 0;
&.touch .tooltip { display: none !important; }
body {
padding-top: $header-height;
+ height: 100%;
+ margin: 0;
}
}
.container {
padding-top: 0;
+ height: 100%;
+ width: 100%;
z-index: 5;
}
+.content {
+ height: 100%;
+ width: 100%;
+}
+
+.content section {
+ height: 100%;
+ display: table-row;
+}
+
.container .content {
margin: 0 0;
}
@@ -24,3 +40,9 @@ html {
.container-limited {
max-width: $fixed-layout-width;
}
+
+.max-height {
+ height: 100%;
+ display: table;
+ width: 100%;
+} \ No newline at end of file
diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss
index cf76f538e01..a5fe5890447 100644
--- a/app/assets/stylesheets/generic/buttons.scss
+++ b/app/assets/stylesheets/generic/buttons.scss
@@ -94,6 +94,7 @@ body {
@mixin btn-info {
@include border-radius(2px);
+ @include transition (all 0.2s ease 0s);
border-width: 1px;
border-style: solid;
@@ -116,6 +117,7 @@ body {
&:active {
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
+
border-width: 1px;
border-style: solid;
}
@@ -123,6 +125,7 @@ body {
@mixin btn-middle {
@include border-radius(2px);
+ @include transition (all 0.2s ease 0s);
border-width: 1px;
border-style: solid;
@@ -145,6 +148,7 @@ body {
&:active {
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
+
border-width: 1px;
border-style: solid;
}
diff --git a/app/assets/stylesheets/generic/sidebar.scss b/app/assets/stylesheets/generic/sidebar.scss
index c5ea3aca7ca..d30fc6e189d 100644
--- a/app/assets/stylesheets/generic/sidebar.scss
+++ b/app/assets/stylesheets/generic/sidebar.scss
@@ -1,4 +1,7 @@
.page-with-sidebar {
+ min-height: 100%;
+ height: 100%;
+
.sidebar-wrapper {
position: fixed;
top: 0;
@@ -18,15 +21,19 @@
}
.content-wrapper {
- min-height: 100vh;
+ min-height: 900px;
+ display: table;
width: 100%;
padding: 20px;
background: #EAEBEC;
+ height: 100%;
+ width: 100%;
.container-fluid {
background: #FFF;
padding: $gl-padding;
- min-height: 90vh;
+ height: 100%;
+ min-height: 100%;
&.container-blank {
background: none;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 818aa10aefe..b7d046e891a 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -510,4 +510,3 @@ pre.light-well {
.inline-form {
display: inline-block;
}
-
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index 467d0f81aca..58e9049f158 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -20,6 +20,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@projects = current_user.starred_projects
@projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.sort(@sort = params[:sort])
+ @last_push = current_user.recent_push
@groups = []
respond_to do |format|
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index edf43935f3c..2025158d065 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -1,20 +1,7 @@
class PasswordsController < Devise::PasswordsController
-
- def create
- email = resource_params[:email]
- resource_found = resource_class.find_by_email(email)
- if resource_found && resource_found.ldap_user?
- flash[:alert] = "Cannot reset password for LDAP user."
- respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) and return
- end
-
- self.resource = resource_class.send_reset_password_instructions(resource_params)
- if successfully_sent?(resource)
- respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name))
- else
- respond_with(resource)
- end
- end
+ before_action :resource_from_email, only: [:create]
+ before_action :prevent_ldap_reset, only: [:create]
+ before_action :throttle_reset, only: [:create]
def edit
super
@@ -35,4 +22,25 @@ class PasswordsController < Devise::PasswordsController
end
end
end
+
+ protected
+
+ def resource_from_email
+ email = resource_params[:email]
+ self.resource = resource_class.find_by_email(email)
+ end
+
+ def prevent_ldap_reset
+ return unless resource && resource.ldap_user?
+
+ redirect_to after_sending_reset_password_instructions_path_for(resource_name),
+ alert: "Cannot reset password for LDAP user."
+ end
+
+ def throttle_reset
+ return unless resource && resource.recently_sent_password_reset?
+
+ redirect_to new_password_path(resource_name),
+ alert: I18n.t('devise.passwords.recently_reset')
+ end
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 3a22ed832ac..3047ee8a1ff 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -58,6 +58,8 @@ class Projects::ServicesController < Projects::ApplicationController
end
def service_params
- params.require(:service).permit(ALLOWED_PARAMS)
+ service_params = params.require(:service).permit(ALLOWED_PARAMS)
+ service_params.delete("password") if service_params["password"].blank?
+ service_params
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 7b4747ce3d7..a0220af4c30 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -296,7 +296,7 @@ module ProjectsHelper
def readme_cache_key
sha = @project.commit.try(:sha) || 'nil'
- [@project.id, sha, "readme"].join('-')
+ [@project.path_with_namespace, sha, "readme"].join('-')
end
def round_commit_count(project)
diff --git a/app/models/project.rb b/app/models/project.rb
index 06a66bbf494..b90a82da9f2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -751,13 +751,9 @@ class Project < ActiveRecord::Base
gitlab_ci_project || create_gitlab_ci_project
end
- def enable_ci(user)
- # Enable service
+ def enable_ci
service = gitlab_ci_service || create_gitlab_ci_service
service.active = true
service.save
-
- # Create Ci::Project
- Ci::CreateProjectService.new.execute(user, self)
end
end
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index 436d4cfed81..6d2cf79b691 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -22,12 +22,17 @@ class GitlabCiService < CiService
include Gitlab::Application.routes.url_helpers
after_save :compose_service_hook, if: :activated?
+ after_save :ensure_gitlab_ci_project, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
hook.save
end
+ def ensure_gitlab_ci_project
+ project.ensure_gitlab_ci_project
+ end
+
def supported_events
%w(push tag_push)
end
@@ -67,21 +72,6 @@ class GitlabCiService < CiService
:error
end
- def fork_registration(new_project, current_user)
- params = OpenStruct.new({
- id: new_project.id,
- default_branch: new_project.default_branch
- })
-
- ci_project = Ci::Project.find_by!(gitlab_id: project.id)
-
- Ci::CreateProjectService.new.execute(
- current_user,
- params,
- ci_project
- )
- end
-
def commit_coverage(sha, ref)
get_ci_commit(sha, ref).coverage
rescue ActiveRecord::RecordNotFound
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 56e49af2324..f602a965364 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -135,6 +135,10 @@ class ProjectTeam
!!find_member(user_id)
end
+ def human_max_access(user_id)
+ Gitlab::Access.options.key max_member_access(user_id)
+ end
+
def max_member_access(user_id)
access = []
access << project.project_members.find_by(user_id: user_id).try(:access_field)
diff --git a/app/models/user.rb b/app/models/user.rb
index ef687f737cc..1069f8e3664 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -328,6 +328,10 @@ class User < ActiveRecord::Base
@reset_token
end
+ def recently_sent_password_reset?
+ reset_password_sent_at.present? && reset_password_sent_at >= 1.minute.ago
+ end
+
def disable_two_factor!
update_attributes(
two_factor_enabled: false,
diff --git a/app/services/ci/create_project_service.rb b/app/services/ci/create_project_service.rb
deleted file mode 100644
index f42babd2388..00000000000
--- a/app/services/ci/create_project_service.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Ci
- class CreateProjectService
- include Gitlab::Application.routes.url_helpers
-
- def execute(current_user, params, forked_project = nil)
- @project = Ci::Project.parse(params)
-
- Ci::Project.transaction do
- @project.save!
-
- gl_project = ::Project.find(@project.gitlab_id)
- gl_project.build_missing_services
- gl_project.gitlab_ci_service.update_attributes(active: true)
- end
-
- if forked_project
- # Copy settings
- settings = forked_project.attributes.select do |attr_name, value|
- ["public", "shared_runners_enabled", "allow_git_fetch"].include? attr_name
- end
-
- @project.update(settings)
- end
-
- Ci::EventService.new.create_project(current_user, @project)
-
- @project
- end
- end
-end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 8193b6e192d..f9a8265d2d4 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -58,7 +58,7 @@ class GitPushService
# If CI was disabled but .gitlab-ci.yml file was pushed
# we enable CI automatically
if !project.gitlab_ci? && gitlab_ci_yaml?(newrev)
- project.enable_ci(user)
+ project.enable_ci
end
EventCreateService.new.push(project, user, @push_data)
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 2e995d6fd51..46374a3909a 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -18,7 +18,13 @@ module Projects
if new_project.persisted?
if @project.gitlab_ci?
- @project.gitlab_ci_service.fork_registration(new_project, @current_user)
+ new_project.enable_ci
+
+ settings = @project.gitlab_ci_project.attributes.select do |attr_name, value|
+ ["public", "shared_runners_enabled", "allow_git_fetch"].include? attr_name
+ end
+
+ new_project.gitlab_ci_project.update(settings)
end
end
diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml
index 339362701d4..f75f2e0a32a 100644
--- a/app/views/dashboard/projects/starred.html.haml
+++ b/app/views/dashboard/projects/starred.html.haml
@@ -3,6 +3,9 @@
= render 'dashboard/projects_head'
+- if @last_push
+ = render "events/event_last_push", event: @last_push
+
- if @projects.any?
= render 'projects'
- else
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index 29ffe8a8be3..535e85869e5 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -6,7 +6,7 @@
.devise-errors
= devise_error_messages!
.clearfix.append-bottom-20
- = f.email_field :email, placeholder: "Email", class: "form-control", required: true, value: params[:user_email]
+ = f.email_field :email, placeholder: "Email", class: "form-control", required: true, value: params[:user_email], autofocus: true
.clearfix
= f.submit "Reset password", class: "btn-primary btn"
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 2468687b56d..1f4ade81ed2 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -25,5 +25,5 @@
= render "layouts/flash"
%div{ class: container_class }
.content
- .clearfix
+ .clearfix.max-height
= yield
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index efad4cb1473..cddd5aa3a83 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -5,7 +5,7 @@
- note_count = notes.user.count
- ci_commit = project.ci_commit(commit.sha)
-- cache_key = [project.id, commit.id, note_count]
+- cache_key = [project.path_with_namespace, commit.id, note_count]
- cache_key.push(ci_commit.status) if ci_commit
= cache(cache_key) do
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index cf5d5d6d8ba..1638ad6891a 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -14,10 +14,10 @@
= icon('trash-o')
- unless note.system
- - member = note.project.team.find_member(note.author.id)
- - if member
+ - access = note.project.team.human_max_access(note.author.id)
+ - if access
%span.note-role.label
- = member.human_access
+ = access
= link_to_member(note.project, note.author, avatar: false)
diff --git a/app/views/shared/_field.html.haml b/app/views/shared/_field.html.haml
index 45ec49280d2..8d6e16f74c3 100644
--- a/app/views/shared/_field.html.haml
+++ b/app/views/shared/_field.html.haml
@@ -8,7 +8,10 @@
- help = field[:help]
.form-group
- = form.label name, title, class: "control-label"
+ - if type == "password" && value.present?
+ = form.label name, "Change #{title}", class: "control-label"
+ - else
+ = form.label name, title, class: "control-label"
.col-sm-10
- if type == 'text'
= form.text_field name, class: "form-control", placeholder: placeholder
@@ -19,6 +22,6 @@
- elsif type == 'select'
= form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" }
- elsif type == 'password'
- = form.password_field name, value: value, class: 'form-control'
+ = form.password_field name, autocomplete: "new-password", class: 'form-control'
- if help
%span.help-block= help
diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml
index d8bf0878a3d..22070e37f07 100644
--- a/config/locales/devise.en.yml
+++ b/config/locales/devise.en.yml
@@ -1,61 +1,63 @@
-# Additional translations at http://github.com/plataformatec/devise/wiki/I18n
+# Additional translations at https://github.com/plataformatec/devise/wiki/I18n
en:
+ devise:
+ confirmations:
+ confirmed: "Your email address has been successfully confirmed."
+ send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
+ send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
+ failure:
+ already_authenticated: "You are already signed in."
+ inactive: "Your account is not activated yet."
+ invalid: "Invalid %{authentication_keys} or password."
+ locked: "Your account is locked."
+ last_attempt: "You have one more attempt before your account is locked."
+ not_found_in_database: "Invalid %{authentication_keys} or password."
+ timeout: "Your session expired. Please sign in again to continue."
+ unauthenticated: "You need to sign in or sign up before continuing."
+ unconfirmed: "You have to confirm your email address before continuing."
+ mailer:
+ confirmation_instructions:
+ subject: "Confirmation instructions"
+ reset_password_instructions:
+ subject: "Reset password instructions"
+ unlock_instructions:
+ subject: "Unlock instructions"
+ password_change:
+ subject: "Password Changed"
+ omniauth_callbacks:
+ failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
+ success: "Successfully authenticated from %{kind} account."
+ passwords:
+ no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
+ recently_reset: "Instructions about how to reset your password have already been sent recently. Please wait a few minutes to try again."
+ send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
+ send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
+ updated: "Your password has been changed successfully. You are now signed in."
+ updated_not_active: "Your password has been changed successfully."
+ registrations:
+ destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
+ signed_up: "Welcome! You have signed up successfully."
+ signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
+ signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
+ signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
+ update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
+ updated: "Your account has been updated successfully."
+ sessions:
+ signed_in: "Signed in successfully."
+ signed_out: "Signed out successfully."
+ already_signed_out: "Signed out successfully."
+ unlocks:
+ send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
+ send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
+ unlocked: "Your account has been unlocked successfully. Please sign in to continue."
errors:
messages:
+ already_confirmed: "was already confirmed, please try signing in"
+ confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
expired: "has expired, please request a new one"
not_found: "not found"
- already_confirmed: "was already confirmed, please try signing in"
not_locked: "was not locked"
not_saved:
one: "1 error prohibited this %{resource} from being saved:"
other: "%{count} errors prohibited this %{resource} from being saved:"
-
- devise:
- failure:
- already_authenticated: 'You are already signed in.'
- unauthenticated: 'You need to sign in before continuing.'
- unconfirmed: 'You have to confirm your account before continuing.'
- locked: 'Your account is locked.'
- not_found_in_database: 'Invalid email or password.'
- invalid: 'Invalid email or password.'
- invalid_token: 'Invalid authentication token.'
- timeout: 'Your session expired, please sign in again to continue.'
- inactive: 'Your account was not activated yet.'
- sessions:
- signed_in: ''
- signed_out: ''
- users_sessions:
- user:
- signed_in: 'Signed in successfully.'
- passwords:
- send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
- updated: 'Your password was changed successfully. You are now signed in.'
- updated_not_active: 'Your password was changed successfully.'
- send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
- no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
- confirmations:
- send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
- send_paranoid_instructions: 'If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.'
- confirmed: 'Your account was successfully confirmed. You are now signed in.'
- registrations:
- signed_up: 'Welcome! You have signed up successfully.'
- updated: 'You updated your account successfully.'
- destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
- signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.'
- signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.'
- signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.'
- unlocks:
- send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
- unlocked: 'Your account was successfully unlocked. You are now signed in.'
- send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.'
- omniauth_callbacks:
- success: 'Successfully authorized from %{kind} account.'
- failure: 'Could not authorize you from %{kind} because "%{reason}".'
- mailer:
- confirmation_instructions:
- subject: 'Confirmation instructions'
- reset_password_instructions:
- subject: 'Reset password instructions'
- unlock_instructions:
- subject: 'Unlock Instructions'
diff --git a/doc/migrate_ci_to_ce/README.md b/doc/migrate_ci_to_ce/README.md
index 46ce0fe98c0..1cb1bc2e762 100644
--- a/doc/migrate_ci_to_ce/README.md
+++ b/doc/migrate_ci_to_ce/README.md
@@ -182,6 +182,7 @@ will need this file later.
```
# On your CI server:
# Omnibus
+sudo chown gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
sudo gitlab-ci-rake backup:create
# Source
@@ -228,6 +229,7 @@ be no CI data yet because you turned CI on the GitLab server off earlier.
```
# On your GitLab server:
# Omnibus
+sudo chown git:git /var/opt/gitlab/gitlab-ci/builds
sudo gitlab-rake ci:migrate
# Source
@@ -342,7 +344,12 @@ The fix for this is to update to Omnibus 7.14 first and then update it to 8.0.
#### Permission denied when accessing /var/opt/gitlab/gitlab-ci/builds
To fix that issue you have to change builds/ folder permission before doing final backup:
```
-chown -R gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
+sudo chown -R gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
+```
+
+Then before executing `ci:migrate` you need to fix builds folder permission:
+```
+sudo chown git:git /var/opt/gitlab/gitlab-ci/builds
```
#### Problems when importing CI database to GitLab
diff --git a/features/project/service.feature b/features/project/service.feature
index fdff640ec85..5014b52b9f6 100644
--- a/features/project/service.feature
+++ b/features/project/service.feature
@@ -72,6 +72,7 @@ Feature: Project Services
And I click Atlassian Bamboo CI service link
And I fill Atlassian Bamboo CI settings
Then I should see Atlassian Bamboo CI service settings saved
+ And I should see empty field Change Password
Scenario: Activate jetBrains TeamCity CI service
When I visit project "Shop" services page
diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb
index 47f58091b93..5ebc3a49760 100644
--- a/features/steps/project/commits/commits.rb
+++ b/features/steps/project/commits/commits.rb
@@ -103,7 +103,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
end
step 'commit has ci status' do
- @project.enable_ci(@user)
+ @project.enable_ci
create :ci_commit, gl_project: @project, sha: sample_commit.id
end
diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb
index d3b462bfd31..1c700df0c63 100644
--- a/features/steps/project/services.rb
+++ b/features/steps/project/services.rb
@@ -202,6 +202,10 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
expect(find_field('Username').value).to eq 'user'
end
+ step 'I should see empty field Change Password' do
+ expect(find_field('Change Password').value).to be_nil
+ end
+
step 'I click JetBrains TeamCity CI service link' do
click_link 'JetBrains TeamCity CI'
end
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index fc51cec150e..5744e455ebd 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -199,7 +199,7 @@ module SharedProject
step 'project "Shop" has CI enabled' do
project = Project.find_by(name: "Shop")
- project.enable_ci(@user)
+ project.enable_ci
end
step 'project "Shop" has CI build' do
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index cef432e512b..922c76285d1 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -95,7 +95,7 @@ feature 'Login', feature: true do
user = create(:user, password: 'not-the-default')
login_with(user)
- expect(page).to have_content('Invalid email or password.')
+ expect(page).to have_content('Invalid login or password.')
end
end
end
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index abf66f2356d..85e70b4d47f 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -1,53 +1,43 @@
require 'spec_helper'
feature 'Password reset', feature: true do
- describe 'with two-factor authentication' do
- let(:user) { create(:user, :two_factor) }
-
- it 'requires login after password reset' do
+ describe 'throttling' do
+ it 'sends reset instructions when not previously sent' do
visit root_path
+ forgot_password(create(:user))
- forgot_password
- reset_password
-
- expect(page).to have_content("Your password was changed successfully.")
- expect(page).not_to have_content("You are now signed in.")
+ expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
expect(current_path).to eq new_user_session_path
end
- end
- describe 'without two-factor authentication' do
- let(:user) { create(:user) }
+ it 'sends reset instructions when previously sent more than a minute ago' do
+ user = create(:user)
+ user.send_reset_password_instructions
+ user.update_attribute(:reset_password_sent_at, 5.minutes.ago)
- it 'requires login after password reset' do
visit root_path
+ forgot_password(user)
- forgot_password
- reset_password
-
- expect(page).to have_content("Your password was changed successfully.")
+ expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
expect(current_path).to eq new_user_session_path
end
+
+ it "throttles multiple resets in a short timespan" do
+ user = create(:user)
+ user.send_reset_password_instructions
+
+ visit root_path
+ forgot_password(user)
+
+ expect(page).to have_content(I18n.t('devise.passwords.recently_reset'))
+ expect(current_path).to eq new_user_password_path
+ end
end
- def forgot_password
+ def forgot_password(user)
click_on 'Forgot your password?'
fill_in 'Email', with: user.email
click_button 'Reset password'
user.reload
end
-
- def get_reset_token
- mail = ActionMailer::Base.deliveries.last
- body = mail.body.encoded
- body.scan(/reset_password_token=(.+)\"/).flatten.first
- end
-
- def reset_password(password = 'password')
- visit edit_user_password_path(reset_password_token: get_reset_token)
-
- fill_in 'New password', with: password
- fill_in 'Confirm new password', with: password
- click_button 'Change your password'
- end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 99abb95d906..53e56ebff44 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -61,13 +61,13 @@ describe ProjectsHelper do
end
it "returns a valid cach key" do
- expect(helper.send(:readme_cache_key)).to eq("#{project.id}-#{project.commit.id}-readme")
+ expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-#{project.commit.id}-readme")
end
it "returns a valid cache key if HEAD does not exist" do
allow(project).to receive(:commit) { nil }
- expect(helper.send(:readme_cache_key)).to eq("#{project.id}-nil-readme")
+ expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-nil-readme")
end
end
end
diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb
index ab5d0ccd3ca..683a403a907 100644
--- a/spec/models/project_services/gitlab_ci_service_spec.rb
+++ b/spec/models/project_services/gitlab_ci_service_spec.rb
@@ -55,25 +55,4 @@ describe GitlabCiService do
end
end
end
-
- describe "Fork registration" do
- before do
- @old_project = create(:ci_project).gl_project
- @project = create(:empty_project)
- @user = create(:user)
-
- @service = GitlabCiService.new
- allow(@service).to receive_messages(
- service_hook: true,
- project_url: 'http://ci.gitlab.org/projects/2',
- token: 'verySecret',
- project: @old_project
- )
- end
-
- it "creates fork on CI" do
- expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
- @service.fork_registration(@project, @user)
- end
- end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 3df5300fe38..8b5d2c3a1c1 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -417,9 +417,8 @@ describe Project do
describe :enable_ci do
let(:project) { create :project }
- let(:user) { create :user }
- before { project.enable_ci(user) }
+ before { project.enable_ci }
it { expect(project.gitlab_ci?).to be_truthy }
it { expect(project.gitlab_ci_project).to be_a(Ci::Project) }
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index cc1138490a0..26e8fdae472 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -66,4 +66,16 @@ describe ProjectTeam do
it { expect(project.team.member?(guest)).to be_truthy }
end
end
+
+ describe "#human_max_access" do
+ it "return master role" do
+ user = create :user
+ group = create :group
+ group.add_users([user.id], GroupMember::MASTER)
+ project = create(:project, namespace: group)
+ project.team << [user, :guest]
+
+ expect(project.team.human_max_access(user.id)).to eq("Master")
+ end
+ end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index b7b525bfca2..c71cfb3ebe3 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -228,6 +228,26 @@ describe User do
end
end
+ describe '#recently_sent_password_reset?' do
+ it 'is false when reset_password_sent_at is nil' do
+ user = build_stubbed(:user, reset_password_sent_at: nil)
+
+ expect(user.recently_sent_password_reset?).to eq false
+ end
+
+ it 'is false when sent more than one minute ago' do
+ user = build_stubbed(:user, reset_password_sent_at: 5.minutes.ago)
+
+ expect(user.recently_sent_password_reset?).to eq false
+ end
+
+ it 'is true when sent less than one minute ago' do
+ user = build_stubbed(:user, reset_password_sent_at: Time.now)
+
+ expect(user.recently_sent_password_reset?).to eq true
+ end
+ end
+
describe '#disable_two_factor!' do
it 'clears all 2FA-related fields' do
user = create(:user, :two_factor)
diff --git a/spec/services/ci/create_project_service_spec.rb b/spec/services/ci/create_project_service_spec.rb
deleted file mode 100644
index 2de7b0deca7..00000000000
--- a/spec/services/ci/create_project_service_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'spec_helper'
-
-describe Ci::CreateProjectService do
- let(:service) { Ci::CreateProjectService.new }
- let(:current_user) { double.as_null_object }
- let(:project) { FactoryGirl.create :project }
-
- describe :execute do
- context 'valid params' do
- subject { service.execute(current_user, project) }
-
- it { is_expected.to be_kind_of(Ci::Project) }
- it { is_expected.to be_persisted }
- end
-
- context 'without project dump' do
- it 'should raise exception' do
- expect { service.execute(current_user, '', '') }.
- to raise_error(NoMethodError)
- end
- end
-
- context "forking" do
- let(:ci_origin_project) do
- FactoryGirl.create(:ci_project, shared_runners_enabled: true, public: true, allow_git_fetch: true)
- end
-
- subject { service.execute(current_user, project, ci_origin_project) }
-
- it "uses project as a template for settings and jobs" do
- expect(subject.shared_runners_enabled).to be_truthy
- expect(subject.public).to be_truthy
- expect(subject.allow_git_fetch).to be_truthy
- end
- end
- end
-end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 18ab333c1d1..65a8c81204d 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -43,14 +43,10 @@ describe Projects::ForkService do
end
context 'GitLab CI is enabled' do
- it "calls fork registrator for CI" do
- create(:ci_project, gl_project: @from_project)
- @from_project.build_missing_services
- @from_project.gitlab_ci_service.update_attributes(active: true)
-
- expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
-
- fork_project(@from_project, @to_user)
+ it "fork and enable CI for fork" do
+ @from_project.enable_ci
+ @to_project = fork_project(@from_project, @to_user)
+ expect(@to_project.gitlab_ci?).to be_truthy
end
end
end