Commit 76f2e065ea51f6364b1ca3dc0b1d29d6f52a4b04
Exists in
master
and in
4 other branches
Merge branch 'master' into install-guide-improvements
Conflicts: doc/install/installation.md
Showing
64 changed files
with
661 additions
and
384 deletions
Show diff stats
CHANGELOG
Gemfile
... | ... | @@ -29,7 +29,7 @@ gem 'gitlab_git', '~> 1.3.0' |
29 | 29 | gem 'gitlab-grack', '~> 1.0.1', require: 'grack' |
30 | 30 | |
31 | 31 | # LDAP Auth |
32 | -gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap" | |
32 | +gem 'gitlab_omniauth-ldap', '1.0.3', require: "omniauth-ldap" | |
33 | 33 | |
34 | 34 | # Syntax highlighter |
35 | 35 | gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb' |
... | ... | @@ -72,6 +72,9 @@ gem "seed-fu" |
72 | 72 | gem "redcarpet", "~> 2.2.2" |
73 | 73 | gem "github-markup", "~> 0.7.4", require: 'github/markup' |
74 | 74 | |
75 | +# Asciidoc to HTML | |
76 | +gem "asciidoctor" | |
77 | + | |
75 | 78 | # Servers |
76 | 79 | gem "puma", '~> 2.0.1' |
77 | 80 | ... | ... |
Gemfile.lock
... | ... | @@ -46,6 +46,7 @@ GEM |
46 | 46 | rails (~> 3.0) |
47 | 47 | addressable (2.3.4) |
48 | 48 | arel (3.0.2) |
49 | + asciidoctor (0.1.3) | |
49 | 50 | awesome_print (1.1.0) |
50 | 51 | backports (2.6.7) |
51 | 52 | bcrypt-ruby (3.0.1) |
... | ... | @@ -168,8 +169,8 @@ GEM |
168 | 169 | github-linguist (~> 2.3.4) |
169 | 170 | gitlab-grit (~> 2.5.1) |
170 | 171 | gitlab_meta (5.0) |
171 | - gitlab_omniauth-ldap (1.0.2) | |
172 | - net-ldap (~> 0.2.2) | |
172 | + gitlab_omniauth-ldap (1.0.3) | |
173 | + net-ldap (~> 0.3.1) | |
173 | 174 | omniauth (~> 1.0) |
174 | 175 | pyu-ruby-sasl (~> 0.0.3.1) |
175 | 176 | rubyntlm (~> 0.1.1) |
... | ... | @@ -265,7 +266,7 @@ GEM |
265 | 266 | multi_xml (0.5.3) |
266 | 267 | multipart-post (1.2.0) |
267 | 268 | mysql2 (0.3.11) |
268 | - net-ldap (0.2.2) | |
269 | + net-ldap (0.3.1) | |
269 | 270 | nokogiri (1.5.9) |
270 | 271 | oauth (0.4.7) |
271 | 272 | oauth2 (0.8.1) |
... | ... | @@ -517,6 +518,7 @@ PLATFORMS |
517 | 518 | DEPENDENCIES |
518 | 519 | acts-as-taggable-on |
519 | 520 | annotate! |
521 | + asciidoctor | |
520 | 522 | awesome_print |
521 | 523 | better_errors |
522 | 524 | binding_of_caller |
... | ... | @@ -544,7 +546,7 @@ DEPENDENCIES |
544 | 546 | gitlab-pygments.rb (~> 0.3.2) |
545 | 547 | gitlab_git (~> 1.3.0) |
546 | 548 | gitlab_meta (= 5.0) |
547 | - gitlab_omniauth-ldap (= 1.0.2) | |
549 | + gitlab_omniauth-ldap (= 1.0.3) | |
548 | 550 | gon |
549 | 551 | grape (~> 0.4.1) |
550 | 552 | grape-entity (~> 0.3.0) | ... | ... |
VERSION
app/assets/javascripts/milestones.js.coffee
... | ... | @@ -1,14 +0,0 @@ |
1 | -$ -> | |
2 | - $('.milestone-issue-filter li[data-closed]').addClass('hide') | |
3 | - | |
4 | - $('.milestone-issue-filter ul.nav li a').click -> | |
5 | - $('.milestone-issue-filter li').toggleClass('active') | |
6 | - $('.milestone-issue-filter li[data-closed]').toggleClass('hide') | |
7 | - false | |
8 | - | |
9 | - $('.milestone-merge-requests-filter li[data-closed]').addClass('hide') | |
10 | - | |
11 | - $('.milestone-merge-requests-filter ul.nav li a').click -> | |
12 | - $('.milestone-merge-requests-filter li').toggleClass('active') | |
13 | - $('.milestone-merge-requests-filter li[data-closed]').toggleClass('hide') | |
14 | - false |
app/assets/stylesheets/gitlab_bootstrap/nav.scss
app/assets/stylesheets/sections/events.scss
app/assets/stylesheets/sections/notes.scss
app/contexts/issues/list_context.rb
... | ... | @@ -8,7 +8,7 @@ module Issues |
8 | 8 | @issues = case params[:status] |
9 | 9 | when issues_filter[:all] then @project.issues |
10 | 10 | when issues_filter[:closed] then @project.issues.closed |
11 | - when issues_filter[:to_me] then @project.issues.assigned(current_user) | |
11 | + when issues_filter[:to_me] then @project.issues.assigned_to(current_user) | |
12 | 12 | when issues_filter[:by_me] then @project.issues.authored(current_user) |
13 | 13 | else @project.issues.opened |
14 | 14 | end | ... | ... |
app/contexts/projects/create_context.rb
... | ... | @@ -51,6 +51,7 @@ module Projects |
51 | 51 | if shell.import_repository(@project.path_with_namespace, @project.import_url) |
52 | 52 | # We should create satellite for imported repo |
53 | 53 | @project.satellite.create unless @project.satellite.exists? |
54 | + @project.imported = true | |
54 | 55 | true |
55 | 56 | else |
56 | 57 | @project.errors.add(:import_url, 'cannot clone repo') | ... | ... |
app/controllers/admin/groups_controller.rb
... | ... | @@ -8,10 +8,6 @@ class Admin::GroupsController < Admin::ApplicationController |
8 | 8 | end |
9 | 9 | |
10 | 10 | def show |
11 | - @projects = Project.scoped | |
12 | - @projects = @projects.not_in_group(@group) if @group.projects.present? | |
13 | - @projects = @projects.all | |
14 | - @projects.reject!(&:empty_repo?) | |
15 | 11 | end |
16 | 12 | |
17 | 13 | def new | ... | ... |
app/controllers/admin/users_controller.rb
... | ... | @@ -55,8 +55,14 @@ class Admin::UsersController < Admin::ApplicationController |
55 | 55 | def create |
56 | 56 | admin = params[:user].delete("admin") |
57 | 57 | |
58 | - @admin_user = User.new(params[:user], as: :admin) | |
58 | + opts = { | |
59 | + force_random_password: true, | |
60 | + password_expires_at: Time.now | |
61 | + } | |
62 | + | |
63 | + @admin_user = User.new(params[:user].merge(opts), as: :admin) | |
59 | 64 | @admin_user.admin = (admin && admin.to_i > 0) |
65 | + @admin_user.created_by_id = current_user.id | |
60 | 66 | |
61 | 67 | respond_to do |format| |
62 | 68 | if @admin_user.save | ... | ... |
app/controllers/application_controller.rb
1 | 1 | class ApplicationController < ActionController::Base |
2 | 2 | before_filter :authenticate_user! |
3 | 3 | before_filter :reject_blocked! |
4 | + before_filter :check_password_expiration | |
4 | 5 | before_filter :set_current_user_for_thread |
5 | 6 | before_filter :add_abilities |
6 | 7 | before_filter :dev_tools if Rails.env == 'development' |
... | ... | @@ -156,4 +157,10 @@ class ApplicationController < ActionController::Base |
156 | 157 | gon.gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url |
157 | 158 | gon.relative_url_root = Gitlab.config.gitlab.relative_url_root |
158 | 159 | end |
160 | + | |
161 | + def check_password_expiration | |
162 | + if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now | |
163 | + redirect_to new_profile_password_path and return | |
164 | + end | |
165 | + end | |
159 | 166 | end | ... | ... |
... | ... | @@ -0,0 +1,38 @@ |
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/snippets_controller.rb
... | ... | @@ -7,8 +7,12 @@ class SnippetsController < ApplicationController |
7 | 7 | # Allow destroy snippet |
8 | 8 | before_filter :authorize_admin_snippet!, only: [:destroy] |
9 | 9 | |
10 | + before_filter :set_title | |
11 | + | |
10 | 12 | respond_to :html |
11 | 13 | |
14 | + layout 'navless' | |
15 | + | |
12 | 16 | def index |
13 | 17 | @snippets = Snippet.public.fresh.non_expired.page(params[:page]).per(20) |
14 | 18 | end |
... | ... | @@ -98,4 +102,8 @@ class SnippetsController < ApplicationController |
98 | 102 | def authorize_admin_snippet! |
99 | 103 | return render_404 unless can?(current_user, :admin_personal_snippet, @snippet) |
100 | 104 | end |
105 | + | |
106 | + def set_title | |
107 | + @title = 'Snippets' | |
108 | + end | |
101 | 109 | end | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -142,7 +142,7 @@ module ApplicationHelper |
142 | 142 | end |
143 | 143 | |
144 | 144 | def user_color_scheme_class |
145 | - COLOR_SCHEMES[current_user.try(:color_scheme_id)] | |
145 | + COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user) | |
146 | 146 | end |
147 | 147 | |
148 | 148 | # Define whenever show last push event | ... | ... |
app/helpers/projects_helper.rb
... | ... | @@ -48,4 +48,36 @@ module ProjectsHelper |
48 | 48 | def remove_project_message(project) |
49 | 49 | "You are going to remove #{project.name_with_namespace}.\n Removed project CANNOT be restored!\n Are you ABSOLUTELY sure?" |
50 | 50 | end |
51 | + | |
52 | + def project_nav_tabs | |
53 | + @nav_tabs ||= get_project_nav_tabs(@project, current_user) | |
54 | + end | |
55 | + | |
56 | + def project_nav_tab?(name) | |
57 | + project_nav_tabs.include? name | |
58 | + end | |
59 | + | |
60 | + private | |
61 | + | |
62 | + def get_project_nav_tabs(project, current_user) | |
63 | + nav_tabs = [:home] | |
64 | + | |
65 | + if project.repo_exists? && can?(current_user, :download_code, project) | |
66 | + nav_tabs << [:files, :commits, :network, :graphs] | |
67 | + end | |
68 | + | |
69 | + if project.repo_exists? && project.merge_requests_enabled | |
70 | + nav_tabs << :merge_requests | |
71 | + end | |
72 | + | |
73 | + if can?(current_user, :admin_project, project) | |
74 | + nav_tabs << :settings | |
75 | + end | |
76 | + | |
77 | + [:issues, :wiki, :wall, :snippets].each do |feature| | |
78 | + nav_tabs << feature if project.send :"#{feature}_enabled" | |
79 | + end | |
80 | + | |
81 | + nav_tabs.flatten | |
82 | + end | |
51 | 83 | end | ... | ... |
app/models/concerns/issuable.rb
... | ... | @@ -22,8 +22,10 @@ module Issuable |
22 | 22 | scope :closed, -> { with_state(:closed) } |
23 | 23 | scope :of_group, ->(group) { where(project_id: group.project_ids) } |
24 | 24 | scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } |
25 | - scope :assigned, ->(u) { where(assignee_id: u.id)} | |
25 | + scope :assigned_to, ->(u) { where(assignee_id: u.id)} | |
26 | 26 | scope :recent, -> { order("created_at DESC") } |
27 | + scope :assigned, -> { where("assignee_id IS NOT NULL") } | |
28 | + scope :unassigned, -> { where("assignee_id IS NULL") } | |
27 | 29 | |
28 | 30 | delegate :name, |
29 | 31 | :email, | ... | ... |
app/models/issue.rb
... | ... | @@ -27,7 +27,7 @@ class Issue < ActiveRecord::Base |
27 | 27 | |
28 | 28 | scope :cared, ->(user) { where(assignee_id: user) } |
29 | 29 | scope :authored, ->(user) { where(author_id: user) } |
30 | - scope :open_for, ->(user) { opened.assigned(user) } | |
30 | + scope :open_for, ->(user) { opened.assigned_to(user) } | |
31 | 31 | |
32 | 32 | state_machine :state, initial: :opened do |
33 | 33 | event :close do | ... | ... |
app/models/merge_request.rb
... | ... | @@ -91,6 +91,15 @@ class MergeRequest < ActiveRecord::Base |
91 | 91 | if target_branch == source_branch |
92 | 92 | errors.add :branch_conflict, "You can not use same branch for source and target branches" |
93 | 93 | end |
94 | + | |
95 | + if opened? || reopened? | |
96 | + similar_mrs = self.project.merge_requests.where(source_branch: source_branch, target_branch: target_branch).opened | |
97 | + similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id | |
98 | + | |
99 | + if similar_mrs.any? | |
100 | + errors.add :base, "There is already an open merge request for this branches" | |
101 | + end | |
102 | + end | |
94 | 103 | end |
95 | 104 | |
96 | 105 | def reload_code | ... | ... |
app/models/namespace.rb
... | ... | @@ -27,6 +27,7 @@ class Namespace < ActiveRecord::Base |
27 | 27 | message: "only letters, digits, spaces & '_' '-' '.' allowed." } |
28 | 28 | validates :description, length: { within: 0..255 } |
29 | 29 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, |
30 | + exclusion: { in: Gitlab::Blacklist.path }, | |
30 | 31 | format: { with: Gitlab::Regex.path_regex, |
31 | 32 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
32 | 33 | ... | ... |
app/models/project.rb
... | ... | @@ -79,6 +79,7 @@ class Project < ActiveRecord::Base |
79 | 79 | format: { with: Gitlab::Regex.project_name_regex, |
80 | 80 | message: "only letters, digits, spaces & '_' '-' '.' allowed. Letter should be first" } |
81 | 81 | validates :path, presence: true, length: { within: 0..255 }, |
82 | + exclusion: { in: Gitlab::Blacklist.path }, | |
82 | 83 | format: { with: Gitlab::Regex.path_regex, |
83 | 84 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
84 | 85 | validates :issues_enabled, :wall_enabled, :merge_requests_enabled, |
... | ... | @@ -92,7 +93,7 @@ class Project < ActiveRecord::Base |
92 | 93 | format: { with: URI::regexp(%w(http https)), message: "should be a valid url" }, |
93 | 94 | if: :import? |
94 | 95 | |
95 | - validate :check_limit, :repo_name | |
96 | + validate :check_limit | |
96 | 97 | |
97 | 98 | # Scopes |
98 | 99 | scope :without_user, ->(user) { where("projects.id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) } |
... | ... | @@ -166,14 +167,6 @@ class Project < ActiveRecord::Base |
166 | 167 | errors[:base] << ("Can't check your ability to create project") |
167 | 168 | end |
168 | 169 | |
169 | - def repo_name | |
170 | - denied_paths = %w(admin dashboard groups help profile projects search) | |
171 | - | |
172 | - if denied_paths.include?(path) | |
173 | - errors.add(:path, "like #{path} is not allowed") | |
174 | - end | |
175 | - end | |
176 | - | |
177 | 170 | def to_param |
178 | 171 | if namespace |
179 | 172 | namespace.path + "/" + path |
... | ... | @@ -420,6 +413,10 @@ class Project < ActiveRecord::Base |
420 | 413 | !(forked_project_link.nil? || forked_project_link.forked_from_project.nil?) |
421 | 414 | end |
422 | 415 | |
416 | + def imported? | |
417 | + imported | |
418 | + end | |
419 | + | |
423 | 420 | def rename_repo |
424 | 421 | old_path_with_namespace = File.join(namespace_dir, path_was) |
425 | 422 | new_path_with_namespace = File.join(namespace_dir, path) | ... | ... |
app/models/user.rb
... | ... | @@ -42,8 +42,11 @@ class User < ActiveRecord::Base |
42 | 42 | |
43 | 43 | attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, |
44 | 44 | :skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password, |
45 | - :extern_uid, :provider, as: [:default, :admin] | |
46 | - attr_accessible :projects_limit, :can_create_team, :can_create_group, as: :admin | |
45 | + :extern_uid, :provider, :password_expires_at, | |
46 | + as: [:default, :admin] | |
47 | + | |
48 | + attr_accessible :projects_limit, :can_create_team, :can_create_group, | |
49 | + as: :admin | |
47 | 50 | |
48 | 51 | attr_accessor :force_random_password |
49 | 52 | |
... | ... | @@ -104,6 +107,7 @@ class User < ActiveRecord::Base |
104 | 107 | validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} |
105 | 108 | validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} |
106 | 109 | validates :username, presence: true, uniqueness: true, |
110 | + exclusion: { in: Gitlab::Blacklist.path }, | |
107 | 111 | format: { with: Gitlab::Regex.username_regex, |
108 | 112 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
109 | 113 | |
... | ... | @@ -363,4 +367,8 @@ class User < ActiveRecord::Base |
363 | 367 | def accessible_deploy_keys |
364 | 368 | DeployKey.in_projects(self.master_projects).uniq |
365 | 369 | end |
370 | + | |
371 | + def created_by | |
372 | + User.find_by_id(created_by_id) if created_by_id | |
373 | + end | |
366 | 374 | end | ... | ... |
app/observers/project_observer.rb
1 | 1 | class ProjectObserver < BaseObserver |
2 | 2 | def after_create(project) |
3 | - unless project.forked? | |
4 | - GitlabShellWorker.perform_async( | |
5 | - :add_repository, | |
6 | - project.path_with_namespace | |
7 | - ) | |
8 | - | |
9 | - log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") | |
10 | - end | |
3 | + return true if project.forked? || project.imported? | |
4 | + | |
5 | + GitlabShellWorker.perform_async( | |
6 | + :add_repository, | |
7 | + project.path_with_namespace | |
8 | + ) | |
9 | + | |
10 | + log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") | |
11 | 11 | end |
12 | 12 | |
13 | 13 | def after_update(project) | ... | ... |
app/views/admin/teams/members/new.html.haml
1 | 1 | %h3.page_title |
2 | - Team: #{@team.name} | |
3 | - | |
4 | -%fieldset | |
5 | - %legend Members (#{@team.members.count}) | |
6 | - = form_tag admin_team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do | |
7 | - %table#members_list | |
8 | - %thead | |
9 | - %tr | |
10 | - %th User name | |
11 | - %th Default project access | |
12 | - %th Team access | |
13 | - %th | |
14 | - - @team.members.each do |member| | |
15 | - %tr.member | |
16 | - %td | |
17 | - = link_to [:admin, member] do | |
18 | - = member.name | |
19 | - %small= "(#{member.email})" | |
20 | - %td= @team.human_default_projects_access(member) | |
21 | - %td= @team.admin?(member) ? "Admin" : "Member" | |
22 | - %td | |
23 | - %tr | |
24 | - %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_username), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5' | |
25 | - %td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" } | |
26 | - %td | |
27 | - %span= check_box_tag :group_admin | |
28 | - %span Admin? | |
29 | - %td= submit_tag 'Add', class: "btn btn-primary", id: :add_members_to_team | |
2 | + New members for | |
3 | + = link_to @team.name, admin_team_path(@team) | |
4 | + team | |
5 | +%hr | |
6 | += form_tag admin_team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do | |
7 | + - if @team.errors.any? | |
8 | + .alert.alert-error | |
9 | + %span= @team.errors.full_messages.first | |
10 | + .clearfix | |
11 | + = label_tag :user_ids do | |
12 | + Users to add | |
13 | + .input | |
14 | + = select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_username), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5' | |
15 | + .clearfix.group-description-holder | |
16 | + = label_tag :default_project_access do | |
17 | + Default permission in projects | |
18 | + .input | |
19 | + = select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" } | |
20 | + .clearfix | |
21 | + = label_tag :group_admin do | |
22 | + Is team admin | |
23 | + .input | |
24 | + = check_box_tag :group_admin | |
25 | + .clearfix.form-actions | |
26 | + = submit_tag 'Add users into team', class: "btn btn-primary", id: :add_members_to_team | |
27 | + = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/admin/users/_form.html.haml
... | ... | @@ -24,19 +24,25 @@ |
24 | 24 | = f.text_field :email, required: true, autocomplete: "off" |
25 | 25 | %span.help-inline * required |
26 | 26 | |
27 | - %fieldset | |
28 | - %legend Password | |
29 | - .clearfix | |
30 | - = f.label :password | |
31 | - .input= f.password_field :password, disabled: f.object.force_random_password | |
32 | - .clearfix | |
33 | - = f.label :password_confirmation | |
34 | - .input= f.password_field :password_confirmation, disabled: f.object.force_random_password | |
35 | - -if f.object.new_record? | |
27 | + - if @admin_user.new_record? | |
28 | + %fieldset | |
29 | + %legend Password | |
30 | + .clearfix | |
31 | + = f.label :password | |
32 | + .input | |
33 | + %strong | |
34 | + A temporary password will be generated and sent to user. | |
35 | + %br | |
36 | + User will be forced to change it after first sign in | |
37 | + - else | |
38 | + %fieldset | |
39 | + %legend Password | |
40 | + .clearfix | |
41 | + = f.label :password | |
42 | + .input= f.password_field :password, disabled: f.object.force_random_password | |
36 | 43 | .clearfix |
37 | - = f.label :force_random_password do | |
38 | - %span Generate random password | |
39 | - .input= f.check_box :force_random_password, {}, true, nil | |
44 | + = f.label :password_confirmation | |
45 | + .input= f.password_field :password_confirmation, disabled: f.object.force_random_password | |
40 | 46 | |
41 | 47 | %fieldset |
42 | 48 | %legend Access | ... | ... |
app/views/admin/users/show.html.haml
1 | +%h3.page_title | |
2 | + User: | |
3 | + = @admin_user.name | |
4 | + - if @admin_user.blocked? | |
5 | + %span.cred (Blocked) | |
6 | + - if @admin_user.admin | |
7 | + %span.cred (Admin) | |
8 | + | |
9 | + .pull-right | |
10 | + = link_to edit_admin_user_path(@admin_user), class: "btn grouped btn-small" do | |
11 | + %i.icon-edit | |
12 | + Edit | |
13 | + - unless @admin_user == current_user | |
14 | + - if @admin_user.blocked? | |
15 | + = link_to 'Unblock', unblock_admin_user_path(@admin_user), method: :put, class: "btn grouped btn-small success" | |
16 | + - else | |
17 | + = link_to 'Block', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn grouped btn-small btn-remove" | |
18 | + = link_to 'Destroy', [:admin, @admin_user], confirm: "USER #{@admin_user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn grouped btn-small btn-remove" | |
19 | +%hr | |
20 | + | |
1 | 21 | .row |
2 | 22 | .span6 |
3 | - %h3.page_title | |
4 | - = image_tag gravatar_icon(@admin_user.email, 90), class: "avatar s90" | |
5 | - = @admin_user.name | |
6 | - - if @admin_user.blocked? | |
7 | - %span.cred (Blocked) | |
8 | - - if @admin_user.admin | |
9 | - %span.cred (Admin) | |
10 | - .pull-right | |
11 | - = link_to edit_admin_user_path(@admin_user), class: "btn pull-right" do | |
12 | - %i.icon-edit | |
13 | - Edit | |
14 | - %br | |
15 | - %small @#{@admin_user.username} | |
16 | - %br | |
17 | - %small member since #{@admin_user.created_at.stamp("Nov 12, 2031")} | |
18 | - .clearfix | |
19 | - %hr | |
20 | - %p | |
21 | - %span.btn.btn-small | |
22 | - %i.icon-envelope | |
23 | - = mail_to @admin_user.email | |
24 | - - unless @admin_user == current_user | |
25 | - - if @admin_user.blocked? | |
26 | - = link_to 'Unblock', unblock_admin_user_path(@admin_user), method: :put, class: "btn btn-small success" | |
27 | - - else | |
28 | - = link_to 'Block', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove" | |
29 | - = link_to 'Destroy', [:admin, @admin_user], confirm: "USER #{@admin_user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
23 | + .ui-box | |
24 | + %h5.title | |
25 | + Account: | |
26 | + .pull-right | |
27 | + = image_tag gravatar_icon(@admin_user.email, 32), class: "avatar s32" | |
28 | + %ul.well-list | |
29 | + %li | |
30 | + %span.light Name: | |
31 | + %strong= @admin_user.name | |
32 | + %li | |
33 | + %span.light Username: | |
34 | + %strong | |
35 | + = @admin_user.username | |
36 | + %li | |
37 | + %span.light Email: | |
38 | + %strong | |
39 | + = mail_to @admin_user.email | |
40 | + | |
41 | + %li | |
42 | + %span.light Member since: | |
43 | + %strong | |
44 | + = @admin_user.created_at.stamp("Nov 12, 2031") | |
45 | + | |
46 | + %li | |
47 | + %span.light Last sign-in at: | |
48 | + %strong | |
49 | + - if @admin_user.last_sign_in_at | |
50 | + = @admin_user.last_sign_in_at.stamp("Nov 12, 2031") | |
51 | + - else | |
52 | + never | |
53 | + | |
54 | + - if @admin_user.ldap_user? | |
55 | + %li | |
56 | + %span.light LDAP uid: | |
57 | + %strong | |
58 | + = @admin_user.extern_uid | |
59 | + | |
60 | + - if @admin_user.created_by | |
61 | + %li | |
62 | + %span.light Created by: | |
63 | + %strong | |
64 | + = link_to @admin_user.created_by.name, [:admin, @admin_user.created_by] | |
65 | + | |
30 | 66 | %hr |
31 | 67 | %h5 |
32 | 68 | Add User to Projects |
... | ... | @@ -67,11 +103,11 @@ |
67 | 103 | |
68 | 104 | |
69 | 105 | .span6 |
70 | - = render 'users/profile', user: @admin_user | |
71 | 106 | .ui-box |
72 | 107 | %h5.title Projects (#{@projects.count}) |
73 | 108 | %ul.well-list |
74 | 109 | - @projects.sort_by(&:name_with_namespace).each do |project| |
110 | + - tm = project.team.get_tm(@admin_user.id) | |
75 | 111 | %li |
76 | 112 | = link_to admin_project_path(project), class: dom_class(project) do |
77 | 113 | - if project.namespace |
... | ... | @@ -79,16 +115,17 @@ |
79 | 115 | \/ |
80 | 116 | %strong.well-title |
81 | 117 | = truncate(project.name, length: 45) |
82 | - %span.pull-right.light | |
83 | - - if project.owner == @admin_user | |
84 | - %i.icon-wrench | |
85 | - - tm = project.team.get_tm(@admin_user.id) | |
86 | - - if tm | |
87 | - = tm.project_access_human | |
88 | - = link_to edit_admin_project_member_path(project, tm.user), class: "btn btn-small" do | |
118 | + | |
119 | + - if project.owner == @admin_user | |
120 | + %span.label.label-info owner | |
121 | + | |
122 | + - if tm | |
123 | + .pull-right | |
124 | + = link_to edit_admin_project_member_path(project, tm.user), class: "btn grouped btn-small" do | |
89 | 125 | %i.icon-edit |
90 | - = link_to admin_project_member_path(project, tm.user), confirm: remove_from_project_team_message(project, @admin_user), method: :delete, class: "btn btn-small btn-remove" do | |
126 | + = link_to admin_project_member_path(project, tm.user), confirm: remove_from_project_team_message(project, @admin_user), method: :delete, class: "btn grouped btn-small btn-remove" do | |
91 | 127 | %i.icon-remove |
92 | - %p.light | |
93 | - %i.icon-wrench | |
94 | - – user is a project owner | |
128 | + | |
129 | + .pull-right.light | |
130 | + = tm.project_access_human | |
131 | + | ... | ... |
app/views/devise/sessions/_oauth_providers.html.haml
1 | -- if enabled_oauth_providers.present? | |
1 | +- providers = (enabled_oauth_providers - [:ldap]) | |
2 | +- if providers.present? | |
2 | 3 | %hr |
3 | 4 | %div{:'data-no-turbolink' => 'data-no-turbolink'} |
4 | 5 | %span Sign in with: |
5 | - - (enabled_oauth_providers - [:ldap]).each do |provider| | |
6 | + - providers.each do |provider| | |
6 | 7 | %span |
7 | 8 | - if default_providers.include?(provider) |
8 | 9 | = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) | ... | ... |
app/views/edit_tree/show.html.haml
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | = hidden_field_tag 'last_commit', @last_commit |
24 | 24 | = hidden_field_tag 'content', '', id: :file_content |
25 | 25 | .commit-button-annotation |
26 | - = button_tag "Commit", class: 'btn commit-btn js-commit-button' | |
26 | + = button_tag "Commit changes", class: 'btn commit-btn js-commit-button btn-primary' | |
27 | 27 | .message |
28 | 28 | to branch |
29 | 29 | %strong= @ref | ... | ... |
app/views/layouts/nav/_project.html.haml
... | ... | @@ -3,43 +3,48 @@ |
3 | 3 | = link_to project_path(@project), title: "Project" do |
4 | 4 | %i.icon-home |
5 | 5 | |
6 | - - unless @project.empty_repo? | |
7 | - - if can? current_user, :download_code, @project | |
8 | - = nav_link(controller: %w(tree blob blame)) do | |
9 | - = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) | |
10 | - = nav_link(controller: %w(commit commits compare repositories protected_branches)) do | |
11 | - = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) | |
12 | - = nav_link(controller: %w(network)) do | |
13 | - = link_to "Network", project_network_path(@project, @ref || @repository.root_ref) | |
14 | - = nav_link(controller: %w(graphs)) do | |
15 | - = link_to "Graphs", project_graph_path(@project, @ref || @repository.root_ref) | |
16 | - | |
17 | - - if @project.issues_enabled | |
6 | + - if project_nav_tab? :files | |
7 | + = nav_link(controller: %w(tree blob blame)) do | |
8 | + = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) | |
9 | + | |
10 | + - if project_nav_tab? :commits | |
11 | + = nav_link(controller: %w(commit commits compare repositories protected_branches)) do | |
12 | + = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) | |
13 | + | |
14 | + - if project_nav_tab? :network | |
15 | + = nav_link(controller: %w(network)) do | |
16 | + = link_to "Network", project_network_path(@project, @ref || @repository.root_ref) | |
17 | + | |
18 | + - if project_nav_tab? :graphs | |
19 | + = nav_link(controller: %w(graphs)) do | |
20 | + = link_to "Graphs", project_graph_path(@project, @ref || @repository.root_ref) | |
21 | + | |
22 | + - if project_nav_tab? :issues | |
18 | 23 | = nav_link(controller: %w(issues milestones labels)) do |
19 | 24 | = link_to url_for_project_issues do |
20 | 25 | Issues |
21 | 26 | - if @project.used_default_issues_tracker? |
22 | 27 | %span.count.issue_counter= @project.issues.opened.count |
23 | 28 | |
24 | - - if @project.repo_exists? && @project.merge_requests_enabled | |
29 | + - if project_nav_tab? :merge_requests | |
25 | 30 | = nav_link(controller: :merge_requests) do |
26 | 31 | = link_to project_merge_requests_path(@project) do |
27 | 32 | Merge Requests |
28 | 33 | %span.count.merge_counter= @project.merge_requests.opened.count |
29 | 34 | |
30 | - - if @project.wiki_enabled | |
35 | + - if project_nav_tab? :wiki | |
31 | 36 | = nav_link(controller: :wikis) do |
32 | 37 | = link_to 'Wiki', project_wiki_path(@project, :home) |
33 | 38 | |
34 | - - if @project.wall_enabled | |
39 | + - if project_nav_tab? :wall | |
35 | 40 | = nav_link(controller: :walls) do |
36 | 41 | = link_to 'Wall', project_wall_path(@project) |
37 | 42 | |
38 | - - if @project.snippets_enabled | |
43 | + - if project_nav_tab? :snippets | |
39 | 44 | = nav_link(controller: :snippets) do |
40 | 45 | = link_to 'Snippets', project_snippets_path(@project) |
41 | 46 | |
42 | - - if can? current_user, :admin_project, @project | |
47 | + - if project_nav_tab? :settings | |
43 | 48 | = nav_link(html_options: {class: "#{project_tab_class}"}) do |
44 | 49 | = link_to edit_project_path(@project), class: "stat-tab tab " do |
45 | 50 | Settings | ... | ... |
app/views/layouts/nav/_team.html.haml
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | Members |
19 | 19 | %span.count= @team.members.count |
20 | 20 | |
21 | - - if can? current_user, :admin_user_team, @team | |
21 | + - if can? current_user, :manage_user_team, @team | |
22 | 22 | = nav_link(path: 'teams#edit') do |
23 | 23 | = link_to edit_team_path(@team), class: "stat-tab tab " do |
24 | 24 | Settings | ... | ... |
app/views/layouts/snippets.html.haml
... | ... | @@ -1,20 +0,0 @@ |
1 | -!!! 5 | |
2 | -%html{ lang: "en"} | |
3 | - = render "layouts/head", title: "Snipepts" | |
4 | - %body{class: "#{app_theme} application", :'data-page' => body_data_page} | |
5 | - = render "layouts/head_panel", title: "Snippets" | |
6 | - = render "layouts/flash" | |
7 | - %nav.main-nav | |
8 | - .container | |
9 | - %ul | |
10 | - = nav_link(path: 'snippets#user_index', html_options: {class: 'home'}) do | |
11 | - = link_to user_snippets_path(current_user), title: "My Snippets" do | |
12 | - %i.icon-home | |
13 | - = nav_link(path: 'snippets#new') do | |
14 | - = link_to new_snippet_path do | |
15 | - New snippet | |
16 | - = nav_link(path: 'snippets#index') do | |
17 | - = link_to snippets_path do | |
18 | - Discover snippets | |
19 | - .container | |
20 | - .content= yield |
... | ... | @@ -0,0 +1,11 @@ |
1 | +.ui-box | |
2 | + %h5.title= title | |
3 | + %ul.well-list | |
4 | + - issues.each do |issue| | |
5 | + %li | |
6 | + = link_to [@project, issue] do | |
7 | + %span.badge{class: issue.closed? ? 'badge-important' : 'badge-info'} ##{issue.id} | |
8 | + = link_to_gfm truncate(issue.title, length: 60), [@project, issue] | |
9 | + - if issue.assignee | |
10 | + .pull-right | |
11 | + = image_tag gravatar_icon(issue.assignee.email, 16), class: "avatar s16" | ... | ... |
app/views/milestones/show.html.haml
... | ... | @@ -55,39 +55,52 @@ |
55 | 55 | = markdown @milestone.description |
56 | 56 | |
57 | 57 | |
58 | -.row | |
59 | - .span6 | |
60 | - .ui-box.milestone-issue-filter | |
61 | - .title | |
62 | - %ul.nav.nav-pills | |
63 | - %li.active= link_to('Open Issues', '#') | |
64 | - %li=link_to('All Issues', '#') | |
65 | - %ul.well-list | |
66 | - - @issues.each do |issue| | |
67 | - %li{data: {closed: issue.closed?}} | |
68 | - = link_to [@project, issue] do | |
69 | - %span.badge.badge-info ##{issue.id} | |
70 | - – | |
71 | - = link_to_gfm truncate(issue.title, length: 60), [@project, issue] | |
58 | +%ul.nav.nav-tabs | |
59 | + %li.active | |
60 | + = link_to '#tab-issues', 'data-toggle' => 'tab' do | |
61 | + Issues | |
62 | + %span.badge= @issues.count | |
63 | + %li | |
64 | + = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do | |
65 | + Merge Requests | |
66 | + %span.badge= @merge_requests.count | |
67 | + %li | |
68 | + = link_to '#tab-participants', 'data-toggle' => 'tab' do | |
69 | + Participants | |
70 | + %span.badge= @users.count | |
72 | 71 | |
73 | - .span6 | |
74 | - .ui-box.milestone-merge-requests-filter | |
75 | - .title | |
76 | - %ul.nav.nav-pills | |
77 | - %li.active= link_to('Open Merge Requests', '#') | |
78 | - %li=link_to('All Merge Requests', '#') | |
79 | - %ul.well-list | |
80 | - - @merge_requests.each do |merge_request| | |
81 | - %li{data: {closed: merge_request.closed? || merge_request.merged?}} | |
82 | - = link_to [@project, merge_request] do | |
83 | - %span.badge.badge-info ##{merge_request.id} | |
84 | - – | |
85 | - = link_to_gfm truncate(merge_request.title, length: 60), [@project, merge_request] | |
86 | 72 | |
87 | -%hr | |
88 | -%h6 Participants: | |
89 | -%div | |
90 | - - @users.each do |user| | |
91 | - = link_to_member(@project, user) | |
73 | +.tab-content | |
74 | + .tab-pane.active#tab-issues | |
75 | + .row | |
76 | + .span4 | |
77 | + = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned) | |
78 | + .span4 | |
79 | + = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned) | |
80 | + .span4 | |
81 | + = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed) | |
82 | + | |
83 | + .tab-pane#tab-merge-requests | |
84 | + .row | |
85 | + .span6 | |
86 | + .ui-box | |
87 | + %h5.title Open | |
88 | + %ul.well-list | |
89 | + - @merge_requests.opened.each do |merge_request| | |
90 | + = render 'merge_request', merge_request: merge_request | |
91 | + .span6 | |
92 | + .ui-box | |
93 | + %h5.title Closed | |
94 | + %ul.well-list | |
95 | + - @merge_requests.closed.each do |merge_request| | |
96 | + = render 'merge_request', merge_request: merge_request | |
92 | 97 | |
93 | -.clearfix | |
98 | + .tab-pane#tab-participants | |
99 | + %ul.bordered-list | |
100 | + - @users.each do |user| | |
101 | + %li | |
102 | + = link_to user, title: user.name, class: "dark" do | |
103 | + = image_tag gravatar_icon(user.email, 32), class: "avatar s32" | |
104 | + %strong= truncate(user.name, lenght: 40) | |
105 | + %br | |
106 | + %small.cgray= user.username | ... | ... |
app/views/notify/new_user_email.html.haml
... | ... | @@ -8,13 +8,14 @@ |
8 | 8 | %p |
9 | 9 | login.......................................... |
10 | 10 | %code= @user['email'] |
11 | -%p | |
12 | - - unless Gitlab.config.gitlab.signup_enabled | |
11 | + | |
12 | +- if @user.created_by_id | |
13 | + %p | |
13 | 14 | password.................................. |
14 | 15 | %code= @password |
15 | 16 | |
16 | -%p | |
17 | - Please change your password immediately after login. | |
17 | + %p | |
18 | + You will be forced to change this password immediately after login. | |
18 | 19 | |
19 | 20 | %p |
20 | 21 | = link_to "Click here to login", root_url | ... | ... |
app/views/notify/new_user_email.text.erb
... | ... | @@ -3,10 +3,11 @@ Hi <%= @user.name %>! |
3 | 3 | The Administrator created an account for you. Now you are a member of company GitLab application. |
4 | 4 | |
5 | 5 | login.................. <%= @user.email %> |
6 | -<% unless Gitlab.config.gitlab.signup_enabled %> | |
6 | +<% if @user.created_by_id %> | |
7 | 7 | password............... <%= @password %> |
8 | + | |
9 | + You will be forced to change this password immediately after login. | |
8 | 10 | <% end %> |
9 | 11 | |
10 | -Please change your password immediately after login. | |
11 | 12 | |
12 | 13 | Click here to login: <%= url_for(root_url) %> | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | += form_for @user, url: profile_password_path, method: :post do |f| | |
2 | + .light-well.padded | |
3 | + %p.slead | |
4 | + Please set new password before proceed. | |
5 | + %br | |
6 | + After successful password update you will be redirected to login screen | |
7 | + -if @user.errors.any? | |
8 | + .alert.alert-error | |
9 | + %ul | |
10 | + - @user.errors.full_messages.each do |msg| | |
11 | + %li= msg | |
12 | + | |
13 | + .clearfix | |
14 | + = f.label :password | |
15 | + .input= f.password_field :password, required: true | |
16 | + .clearfix | |
17 | + = f.label :password_confirmation | |
18 | + .input | |
19 | + = f.password_field :password_confirmation, required: true | |
20 | + .clearfix | |
21 | + .input | |
22 | + = f.submit 'Set new password', class: "btn btn-create" | ... | ... |
app/views/projects/_settings_nav.html.haml
... | ... | @@ -5,8 +5,8 @@ |
5 | 5 | Edit |
6 | 6 | = nav_link(controller: [:team_members, :teams]) do |
7 | 7 | = link_to project_team_index_path(@project), class: "team-tab tab" do |
8 | - %i.icon-user | |
9 | - Team | |
8 | + %i.icon-group | |
9 | + Project Members | |
10 | 10 | = nav_link(controller: :deploy_keys) do |
11 | 11 | = link_to project_deploy_keys_path(@project) do |
12 | 12 | %span |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | = nav_link(controller: :hooks) do |
15 | 15 | = link_to project_hooks_path(@project) do |
16 | 16 | %span |
17 | - Hooks | |
17 | + Web Hooks | |
18 | 18 | = nav_link(controller: :services) do |
19 | 19 | = link_to project_services_path(@project) do |
20 | 20 | %span | ... | ... |
app/views/snippets/current_user_index.html.haml
1 | 1 | %h3.page_title |
2 | 2 | My Snippets |
3 | 3 | %small share code pastes with others out of git repository |
4 | - = link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do | |
5 | - Add new snippet | |
4 | + .pull-right | |
5 | + = link_to new_snippet_path, class: "btn btn-small add_new grouped btn-primary", title: "New Snippet" do | |
6 | + Add new snippet | |
7 | + = link_to snippets_path, class: "btn btn-small grouped" do | |
8 | + Discover snippets | |
6 | 9 | |
7 | 10 | %hr |
8 | 11 | ... | ... |
app/views/snippets/index.html.haml
1 | 1 | %h3.page_title |
2 | 2 | Public snippets |
3 | 3 | %small share code pastes with others out of git repository |
4 | - = link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do | |
5 | - Add new snippet | |
4 | + | |
5 | + .pull-right | |
6 | + = link_to new_snippet_path, class: "btn btn-small add_new grouped btn-primary", title: "New Snippet" do | |
7 | + Add new snippet | |
8 | + = link_to user_snippets_path(current_user), class: "btn btn-small grouped" do | |
9 | + My snippets | |
6 | 10 | |
7 | 11 | %hr |
8 | 12 | .row | ... | ... |
app/views/team_members/index.html.haml
app/views/teams/edit.html.haml
... | ... | @@ -5,8 +5,9 @@ |
5 | 5 | = link_to 'Projects', '#tab-projects', 'data-toggle' => 'tab' |
6 | 6 | %li |
7 | 7 | = link_to 'Edit Team', '#tab-edit', 'data-toggle' => 'tab' |
8 | - %li | |
9 | - = link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab' | |
8 | + - if can? current_user, :admin_user_team, @team | |
9 | + %li | |
10 | + = link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab' | |
10 | 11 | |
11 | 12 | .span9 |
12 | 13 | .tab-content | ... | ... |
config/environments/production.rb
... | ... | @@ -52,7 +52,7 @@ Gitlab::Application.configure do |
52 | 52 | # config.action_mailer.raise_delivery_errors = false |
53 | 53 | |
54 | 54 | # Enable threaded mode |
55 | - config.threadsafe! | |
55 | + config.threadsafe! unless $rails_rake_task | |
56 | 56 | |
57 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to |
58 | 58 | # the I18n.default_locale when a translation can not be found) | ... | ... |
config/routes.rb
db/fixtures/production/001_admin.rb
db/migrate/20130613165816_add_password_expires_at_to_users.rb
0 → 100644
db/schema.rb
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | # |
12 | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | |
14 | -ActiveRecord::Schema.define(:version => 20130522141856) do | |
14 | +ActiveRecord::Schema.define(:version => 20130614132337) do | |
15 | 15 | |
16 | 16 | create_table "deploy_keys_projects", :force => true do |t| |
17 | 17 | t.integer "deploy_key_id", :null => false |
... | ... | @@ -172,6 +172,7 @@ ActiveRecord::Schema.define(:version => 20130522141856) do |
172 | 172 | t.string "issues_tracker_id" |
173 | 173 | t.boolean "snippets_enabled", :default => true, :null => false |
174 | 174 | t.datetime "last_activity_at" |
175 | + t.boolean "imported", :default => false, :null => false | |
175 | 176 | end |
176 | 177 | |
177 | 178 | add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" |
... | ... | @@ -292,6 +293,8 @@ ActiveRecord::Schema.define(:version => 20130522141856) do |
292 | 293 | t.string "state" |
293 | 294 | t.integer "color_scheme_id", :default => 1, :null => false |
294 | 295 | t.integer "notification_level", :default => 1, :null => false |
296 | + t.datetime "password_expires_at" | |
297 | + t.integer "created_by_id" | |
295 | 298 | end |
296 | 299 | |
297 | 300 | add_index "users", ["admin"], :name => "index_users_on_admin" | ... | ... |
doc/api/README.md
... | ... | @@ -69,15 +69,15 @@ When listing resources you can pass the following parameters: |
69 | 69 | |
70 | 70 | ## Contents |
71 | 71 | |
72 | -+ [Users](doc/api/users.md) | |
73 | -+ [Session](doc/api/session.md) | |
74 | -+ [Projects](doc/api/projects.md) | |
75 | -+ [Project Snippets](doc/api/project_snippets.md) | |
76 | -+ [Repositories](doc/api/repositories.md) | |
77 | -+ [Issues](doc/api/issues.md) | |
78 | -+ [Milestones](doc/api/milestones.md) | |
79 | -+ [Notes](doc/api/notes.md) | |
80 | -+ [Deploy Keys](doc/api/deploy_keys.md) | |
81 | -+ [System Hooks](doc/api/system_hooks.md) | |
82 | -+ [Groups](doc/api/groups.md) | |
83 | -+ [User Teams](doc/api/user_teams.md) | |
72 | ++ [Users](users.md) | |
73 | ++ [Session](session.md) | |
74 | ++ [Projects](projects.md) | |
75 | ++ [Project Snippets](project_snippets.md) | |
76 | ++ [Repositories](repositories.md) | |
77 | ++ [Issues](issues.md) | |
78 | ++ [Milestones](milestones.md) | |
79 | ++ [Notes](notes.md) | |
80 | ++ [Deploy Keys](deploy_keys.md) | |
81 | ++ [System Hooks](system_hooks.md) | |
82 | ++ [Groups](groups.md) | |
83 | ++ [User Teams](user_teams.md) | ... | ... |
doc/install/installation.md
... | ... | @@ -148,10 +148,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install |
148 | 148 | cd /home/git/gitlab |
149 | 149 | |
150 | 150 | # Checkout to stable release |
151 | - sudo -u git -H git checkout 5-2-stable | |
151 | + sudo -u git -H git checkout 5-3-stable | |
152 | 152 | |
153 | 153 | **Note:** |
154 | -You can change `5-2-stable` to `master` if you want the *bleeding edge* version, but do so with caution! | |
154 | +You can change `5-3-stable` to `master` if you want the *bleeding edge* version, but do so with caution! | |
155 | 155 | |
156 | 156 | ## Configure it |
157 | 157 | |
... | ... | @@ -352,10 +352,10 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already |
352 | 352 | |
353 | 353 | These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation. |
354 | 354 | |
355 | -* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/Gemfile#L18) | |
355 | +* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/Gemfile#L18) | |
356 | 356 | * Run `sudo -u git -H bundle install` to install the new gem(s) |
357 | -* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/gitlab.yml.example#L53) as a reference) | |
358 | -* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/5-2-stable/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons) | |
357 | +* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/gitlab.yml.example#L53) as a reference) | |
358 | +* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/5-3-stable/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons) | |
359 | 359 | * Restart GitLab |
360 | 360 | |
361 | 361 | ### Examples | ... | ... |
... | ... | @@ -0,0 +1,80 @@ |
1 | +# From 5.2 to 5.3 | |
2 | + | |
3 | +### 0. Backup | |
4 | + | |
5 | +It's useful to make a backup just in case things go south: | |
6 | +(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) | |
7 | + | |
8 | +```bash | |
9 | +cd /home/git/gitlab | |
10 | +sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create | |
11 | +``` | |
12 | + | |
13 | +### 1. Stop server | |
14 | + | |
15 | + sudo service gitlab stop | |
16 | + | |
17 | +### 2. Get latest code | |
18 | + | |
19 | +```bash | |
20 | +cd /home/git/gitlab | |
21 | +sudo -u git -H git fetch | |
22 | +sudo -u git -H git checkout 5-3-stable | |
23 | +``` | |
24 | + | |
25 | +### 3. Install libs, migrations, etc. | |
26 | + | |
27 | +```bash | |
28 | +cd /home/git/gitlab | |
29 | + | |
30 | +# MySQL | |
31 | +sudo -u git -H bundle install --without development test postgres --deployment | |
32 | + | |
33 | +#PostgreSQL | |
34 | +sudo -u git -H bundle install --without development test mysql --deployment | |
35 | + | |
36 | +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production | |
37 | +``` | |
38 | + | |
39 | +### 4. Update config files | |
40 | + | |
41 | +* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/gitlab.yml.example but with your settings. | |
42 | +* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/puma.rb.example but with your settings. | |
43 | + | |
44 | +### 5. Update Init script | |
45 | + | |
46 | +```bash | |
47 | +sudo rm /etc/init.d/gitlab | |
48 | +sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab | |
49 | +sudo chmod +x /etc/init.d/gitlab | |
50 | +``` | |
51 | + | |
52 | +### 6. Start application | |
53 | + | |
54 | + sudo service gitlab start | |
55 | + sudo service nginx restart | |
56 | + | |
57 | +### 7. Check application status | |
58 | + | |
59 | +Check if GitLab and its environment are configured correctly: | |
60 | + | |
61 | + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production | |
62 | + | |
63 | +To make sure you didn't miss anything run a more thorough check with: | |
64 | + | |
65 | + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production | |
66 | + | |
67 | +If all items are green, then congratulations upgrade complete! | |
68 | + | |
69 | +## Things went south? Revert to previous version (5.2) | |
70 | + | |
71 | +### 1. Revert the code to the previous version | |
72 | +Follow the [`upgrade guide from 5.1 to 5.2`](5.1-to-5.2.md), except for the database migration | |
73 | +(The backup is already migrated to the previous version) | |
74 | + | |
75 | +### 2. Restore from the backup: | |
76 | + | |
77 | +```bash | |
78 | +cd /home/git/gitlab | |
79 | +sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore | |
80 | +``` | ... | ... |
features/project/issues/milestones.feature
features/steps/project/project_active_tab.rb
... | ... | @@ -45,7 +45,7 @@ class ProjectActiveTab < Spinach::FeatureSteps |
45 | 45 | # Sub Tabs: Home |
46 | 46 | |
47 | 47 | Given 'I click the "Team" tab' do |
48 | - click_link('Team') | |
48 | + click_link('Project Members') | |
49 | 49 | end |
50 | 50 | |
51 | 51 | Given 'I click the "Attachments" tab' do |
... | ... | @@ -61,7 +61,7 @@ class ProjectActiveTab < Spinach::FeatureSteps |
61 | 61 | end |
62 | 62 | |
63 | 63 | Given 'I click the "Hooks" tab' do |
64 | - click_link('Hooks') | |
64 | + click_link('Web Hooks') | |
65 | 65 | end |
66 | 66 | |
67 | 67 | Given 'I click the "Deploy Keys" tab' do |
... | ... | @@ -73,7 +73,7 @@ class ProjectActiveTab < Spinach::FeatureSteps |
73 | 73 | end |
74 | 74 | |
75 | 75 | Then 'the active sub tab should be Team' do |
76 | - ensure_active_sub_tab('Team') | |
76 | + ensure_active_sub_tab('Project Members') | |
77 | 77 | end |
78 | 78 | |
79 | 79 | Then 'the active sub tab should be Attachments' do |
... | ... | @@ -89,7 +89,7 @@ class ProjectActiveTab < Spinach::FeatureSteps |
89 | 89 | end |
90 | 90 | |
91 | 91 | Then 'the active sub tab should be Hooks' do |
92 | - ensure_active_sub_tab('Hooks') | |
92 | + ensure_active_sub_tab('Web Hooks') | |
93 | 93 | end |
94 | 94 | |
95 | 95 | Then 'the active sub tab should be Deploy Keys' do | ... | ... |
features/steps/project/project_merge_requests.rb
... | ... | @@ -57,8 +57,8 @@ class ProjectMergeRequests < Spinach::FeatureSteps |
57 | 57 | |
58 | 58 | And 'I submit new merge request "Wiki Feature"' do |
59 | 59 | fill_in "merge_request_title", with: "Wiki Feature" |
60 | - select "master", from: "merge_request_source_branch" | |
61 | - select "stable", from: "merge_request_target_branch" | |
60 | + select "bootstrap", from: "merge_request_source_branch" | |
61 | + select "master", from: "merge_request_target_branch" | |
62 | 62 | click_button "Submit merge request" |
63 | 63 | end |
64 | 64 | ... | ... |
features/steps/project/project_milestones.rb
... | ... | @@ -50,12 +50,6 @@ class ProjectMilestones < Spinach::FeatureSteps |
50 | 50 | end |
51 | 51 | |
52 | 52 | Then "I should see 3 issues" do |
53 | - page.should have_selector('.milestone-issue-filter .well-list li', count: 4) | |
54 | - page.should have_selector('.milestone-issue-filter .well-list li.hide', count: 1) | |
55 | - end | |
56 | - | |
57 | - Then "I should see 4 issues" do | |
58 | - page.should have_selector('.milestone-issue-filter .well-list li', count: 4) | |
59 | - page.should_not have_selector('.milestone-issue-filter .well-list li.hide') | |
53 | + page.should have_selector('#tab-issues li', count: 4) | |
60 | 54 | end |
61 | 55 | end | ... | ... |
features/steps/userteams/userteams.rb
... | ... | @@ -93,7 +93,7 @@ class Userteams < Spinach::FeatureSteps |
93 | 93 | Then 'I should see issues from this team assigned to me' do |
94 | 94 | team = UserTeam.last |
95 | 95 | team.projects.each do |project| |
96 | - project.issues.assigned(current_user).each do |issue| | |
96 | + project.issues.assigned_to(current_user).each do |issue| | |
97 | 97 | page.should have_content issue.title |
98 | 98 | end |
99 | 99 | end |
... | ... | @@ -121,7 +121,7 @@ class Userteams < Spinach::FeatureSteps |
121 | 121 | team = UserTeam.last |
122 | 122 | team.projects.each do |project| |
123 | 123 | team.members.each do |member| |
124 | - project.issues.assigned(member).each do |issue| | |
124 | + project.issues.assigned_to(member).each do |issue| | |
125 | 125 | page.should have_content issue.title |
126 | 126 | end |
127 | 127 | end |
... | ... | @@ -131,9 +131,7 @@ class Userteams < Spinach::FeatureSteps |
131 | 131 | Given 'project from team has merge requests assigned to me' do |
132 | 132 | team = UserTeam.last |
133 | 133 | team.projects.each do |project| |
134 | - team.members.each do |member| | |
135 | - 3.times { create(:merge_request, assignee: member, project: project) } | |
136 | - end | |
134 | + create(:merge_request, assignee: current_user, project: project) | |
137 | 135 | end |
138 | 136 | end |
139 | 137 | |
... | ... | @@ -145,10 +143,8 @@ class Userteams < Spinach::FeatureSteps |
145 | 143 | Then 'I should see merge requests from this team assigned to me' do |
146 | 144 | team = UserTeam.last |
147 | 145 | team.projects.each do |project| |
148 | - team.members.each do |member| | |
149 | - project.issues.assigned(member).each do |merge_request| | |
150 | - page.should have_content merge_request.title | |
151 | - end | |
146 | + project.merge_requests.each do |merge_request| | |
147 | + page.should have_content merge_request.title | |
152 | 148 | end |
153 | 149 | end |
154 | 150 | end |
... | ... | @@ -156,20 +152,8 @@ class Userteams < Spinach::FeatureSteps |
156 | 152 | Given 'project from team has merge requests assigned to team members' do |
157 | 153 | team = UserTeam.last |
158 | 154 | team.projects.each do |project| |
159 | - team.members.each do |member| | |
160 | - 3.times { create(:merge_request, assignee: member, project: project) } | |
161 | - end | |
162 | - end | |
163 | - end | |
164 | - | |
165 | - Then 'I should see merge requests from this team assigned to me' do | |
166 | - team = UserTeam.last | |
167 | - team.projects.each do |project| | |
168 | - team.members.each do |member| | |
169 | - project.issues.assigned(member).each do |merge_request| | |
170 | - page.should have_content merge_request.title | |
171 | - end | |
172 | - end | |
155 | + member = team.members.sample | |
156 | + create(:merge_request, assignee: member, project: project) | |
173 | 157 | end |
174 | 158 | end |
175 | 159 | ... | ... |
lib/gitlab/backend/grack_auth.rb
1 | 1 | require_relative 'shell_env' |
2 | -require 'omniauth-ldap' | |
2 | +require_relative 'grack_ldap' | |
3 | +require_relative 'grack_helpers' | |
3 | 4 | |
4 | 5 | module Grack |
5 | 6 | class Auth < Rack::Auth::Basic |
6 | - attr_accessor :user, :project | |
7 | + include LDAP | |
8 | + include Helpers | |
9 | + | |
10 | + attr_accessor :user, :project, :ref, :env | |
7 | 11 | |
8 | 12 | def call(env) |
9 | 13 | @env = env |
... | ... | @@ -14,42 +18,52 @@ module Grack |
14 | 18 | @env['PATH_INFO'] = @request.path |
15 | 19 | @env['SCRIPT_NAME'] = "" |
16 | 20 | |
17 | - return render_not_found unless project | |
18 | - return unauthorized unless project.public || @auth.provided? | |
19 | - return bad_request if @auth.provided? && !@auth.basic? | |
20 | - | |
21 | - if valid? | |
22 | - if @auth.provided? | |
23 | - @env['REMOTE_USER'] = @auth.username | |
24 | - end | |
25 | - return @app.call(env) | |
26 | - else | |
27 | - unauthorized | |
28 | - end | |
21 | + auth! | |
29 | 22 | end |
30 | 23 | |
31 | - def valid? | |
24 | + private | |
25 | + | |
26 | + def auth! | |
27 | + return render_not_found unless project | |
28 | + | |
32 | 29 | if @auth.provided? |
30 | + return bad_request unless @auth.basic? | |
31 | + | |
33 | 32 | # Authentication with username and password |
34 | 33 | login, password = @auth.credentials |
35 | 34 | |
36 | - @user = authenticate(login, password) | |
37 | - return false unless @user | |
35 | + @user = authenticate_user(login, password) | |
38 | 36 | |
39 | - Gitlab::ShellEnv.set_env(@user) | |
37 | + if @user | |
38 | + Gitlab::ShellEnv.set_env(@user) | |
39 | + @env['REMOTE_USER'] = @auth.username | |
40 | + else | |
41 | + return unauthorized | |
42 | + end | |
43 | + | |
44 | + else | |
45 | + return unauthorized unless project.public | |
40 | 46 | end |
41 | 47 | |
48 | + if authorized_git_request? | |
49 | + @app.call(env) | |
50 | + else | |
51 | + unauthorized | |
52 | + end | |
53 | + end | |
54 | + | |
55 | + def authorized_git_request? | |
42 | 56 | # Git upload and receive |
43 | 57 | if @request.get? |
44 | - validate_get_request | |
58 | + authorize_request(@request.params['service']) | |
45 | 59 | elsif @request.post? |
46 | - validate_post_request | |
60 | + authorize_request(File.basename(@request.path)) | |
47 | 61 | else |
48 | 62 | false |
49 | 63 | end |
50 | 64 | end |
51 | 65 | |
52 | - def authenticate(login, password) | |
66 | + def authenticate_user(login, password) | |
53 | 67 | user = User.find_by_email(login) || User.find_by_username(login) |
54 | 68 | |
55 | 69 | # If the provided login was not a known email or username |
... | ... | @@ -65,34 +79,12 @@ module Grack |
65 | 79 | end |
66 | 80 | end |
67 | 81 | |
68 | - def ldap_auth(login, password) | |
69 | - # Check user against LDAP backend if user is not authenticated | |
70 | - # Only check with valid login and password to prevent anonymous bind results | |
71 | - return nil unless ldap_conf.enabled && !login.blank? && !password.blank? | |
72 | - | |
73 | - ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf) | |
74 | - ldap_user = ldap.bind_as( | |
75 | - filter: Net::LDAP::Filter.eq(ldap.uid, login), | |
76 | - size: 1, | |
77 | - password: password | |
78 | - ) | |
79 | - | |
80 | - User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap') if ldap_user | |
81 | - end | |
82 | - | |
83 | - def validate_get_request | |
84 | - validate_request(@request.params['service']) | |
85 | - end | |
86 | - | |
87 | - def validate_post_request | |
88 | - validate_request(File.basename(@request.path)) | |
89 | - end | |
90 | - | |
91 | - def validate_request(service) | |
92 | - if service == 'git-upload-pack' | |
82 | + def authorize_request(service) | |
83 | + case service | |
84 | + when 'git-upload-pack' | |
93 | 85 | project.public || can?(user, :download_code, project) |
94 | - elsif service == 'git-receive-pack' | |
95 | - action = if project.protected_branch?(current_ref) | |
86 | + when'git-receive-pack' | |
87 | + action = if project.protected_branch?(ref) | |
96 | 88 | :push_code_to_protected_branches |
97 | 89 | else |
98 | 90 | :push_code |
... | ... | @@ -104,49 +96,24 @@ module Grack |
104 | 96 | end |
105 | 97 | end |
106 | 98 | |
107 | - def can?(object, action, subject) | |
108 | - abilities.allowed?(object, action, subject) | |
109 | - end | |
110 | - | |
111 | - def current_ref | |
112 | - if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/ | |
113 | - input = Zlib::GzipReader.new(@request.body).read | |
114 | - else | |
115 | - input = @request.body.read | |
116 | - end | |
117 | - # Need to reset seek point | |
118 | - @request.body.rewind | |
119 | - /refs\/heads\/([\w\.-]+)/n.match(input.force_encoding('ascii-8bit')).to_a.last | |
120 | - end | |
121 | - | |
122 | 99 | def project |
123 | - unless instance_variable_defined? :@project | |
124 | - # Find project by PATH_INFO from env | |
125 | - if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a | |
126 | - @project = Project.find_with_namespace(m.last) | |
127 | - end | |
128 | - end | |
129 | - return @project | |
100 | + @project ||= project_by_path(@request.path_info) | |
130 | 101 | end |
131 | 102 | |
132 | - PLAIN_TYPE = {"Content-Type" => "text/plain"} | |
133 | - | |
134 | - def render_not_found | |
135 | - [404, PLAIN_TYPE, ["Not Found"]] | |
103 | + def ref | |
104 | + @ref ||= parse_ref | |
136 | 105 | end |
137 | 106 | |
138 | - protected | |
107 | + def parse_ref | |
108 | + input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/ | |
109 | + Zlib::GzipReader.new(@request.body).read | |
110 | + else | |
111 | + @request.body.read | |
112 | + end | |
139 | 113 | |
140 | - def abilities | |
141 | - @abilities ||= begin | |
142 | - abilities = Six.new | |
143 | - abilities << Ability | |
144 | - abilities | |
145 | - end | |
146 | - end | |
147 | - | |
148 | - def ldap_conf | |
149 | - @ldap_conf ||= Gitlab.config.ldap | |
114 | + # Need to reset seek point | |
115 | + @request.body.rewind | |
116 | + /refs\/heads\/([\w\.-]+)/n.match(input.force_encoding('ascii-8bit')).to_a.last | |
150 | 117 | end |
151 | - end# Auth | |
152 | -end# Grack | |
118 | + end | |
119 | +end | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +module Grack | |
2 | + module Helpers | |
3 | + def project_by_path(path) | |
4 | + if m = /^\/([\w\.\/-]+)\.git/.match(path).to_a | |
5 | + path_with_namespace = m.last | |
6 | + path_with_namespace.gsub!(/.wiki$/, '') | |
7 | + | |
8 | + Project.find_with_namespace(path_with_namespace) | |
9 | + end | |
10 | + end | |
11 | + | |
12 | + def render_not_found | |
13 | + [404, {"Content-Type" => "text/plain"}, ["Not Found"]] | |
14 | + end | |
15 | + | |
16 | + def can?(object, action, subject) | |
17 | + abilities.allowed?(object, action, subject) | |
18 | + end | |
19 | + | |
20 | + def abilities | |
21 | + @abilities ||= begin | |
22 | + abilities = Six.new | |
23 | + abilities << Ability | |
24 | + abilities | |
25 | + end | |
26 | + end | |
27 | + end | |
28 | +end | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +require 'omniauth-ldap' | |
2 | + | |
3 | +module Grack | |
4 | + module LDAP | |
5 | + def ldap_auth(login, password) | |
6 | + # Check user against LDAP backend if user is not authenticated | |
7 | + # Only check with valid login and password to prevent anonymous bind results | |
8 | + return nil unless ldap_conf.enabled && !login.blank? && !password.blank? | |
9 | + | |
10 | + ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf) | |
11 | + ldap_user = ldap.bind_as( | |
12 | + filter: Net::LDAP::Filter.eq(ldap.uid, login), | |
13 | + size: 1, | |
14 | + password: password | |
15 | + ) | |
16 | + | |
17 | + User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap') if ldap_user | |
18 | + end | |
19 | + | |
20 | + def ldap_conf | |
21 | + @ldap_conf ||= Gitlab.config.ldap | |
22 | + end | |
23 | + end | |
24 | +end | ... | ... |
spec/features/admin/admin_users_spec.rb
... | ... | @@ -20,13 +20,10 @@ describe "Admin::Users" do |
20 | 20 | |
21 | 21 | describe "GET /admin/users/new" do |
22 | 22 | before do |
23 | - @password = "123ABC" | |
24 | 23 | visit new_admin_user_path |
25 | 24 | fill_in "user_name", with: "Big Bang" |
26 | 25 | fill_in "user_username", with: "bang" |
27 | 26 | fill_in "user_email", with: "bigbang@mail.com" |
28 | - fill_in "user_password", with: @password | |
29 | - fill_in "user_password_confirmation", with: @password | |
30 | 27 | end |
31 | 28 | |
32 | 29 | it "should create new user" do |
... | ... | @@ -57,26 +54,13 @@ describe "Admin::Users" do |
57 | 54 | end |
58 | 55 | |
59 | 56 | it "should send valid email to user with email & password" do |
60 | - Gitlab.config.gitlab.stub(:signup_enabled).and_return(false) | |
61 | 57 | User.observers.enable :user_observer do |
62 | 58 | click_button "Create user" |
63 | 59 | user = User.last |
64 | 60 | email = ActionMailer::Base.deliveries.last |
65 | 61 | email.subject.should have_content("Account was created") |
66 | 62 | email.text_part.body.should have_content(user.email) |
67 | - email.text_part.body.should have_content(@password) | |
68 | - end | |
69 | - end | |
70 | - | |
71 | - it "should send valid email to user with email without password when signup is enabled" do | |
72 | - Gitlab.config.gitlab.stub(:signup_enabled).and_return(true) | |
73 | - User.observers.enable :user_observer do | |
74 | - click_button "Create user" | |
75 | - user = User.last | |
76 | - email = ActionMailer::Base.deliveries.last | |
77 | - email.subject.should have_content("Account was created") | |
78 | - email.text_part.body.should have_content(user.email) | |
79 | - email.text_part.body.should_not have_content(@password) | |
63 | + email.text_part.body.should have_content('password') | |
80 | 64 | end |
81 | 65 | end |
82 | 66 | end | ... | ... |
spec/mailers/notify_spec.rb
... | ... | @@ -15,7 +15,7 @@ describe Notify do |
15 | 15 | |
16 | 16 | describe 'for new users, the email' do |
17 | 17 | let(:example_site_path) { root_path } |
18 | - let(:new_user) { create(:user, email: 'newguy@example.com') } | |
18 | + let(:new_user) { create(:user, email: 'newguy@example.com', created_by_id: 1) } | |
19 | 19 | |
20 | 20 | subject { Notify.new_user_email(new_user.id, new_user.password) } |
21 | 21 | |
... | ... | @@ -32,8 +32,7 @@ describe Notify do |
32 | 32 | end |
33 | 33 | |
34 | 34 | it 'contains the new user\'s password' do |
35 | - Gitlab.config.gitlab.stub(:signup_enabled).and_return(false) | |
36 | - should have_body_text /#{new_user.password}/ | |
35 | + should have_body_text /password/ | |
37 | 36 | end |
38 | 37 | |
39 | 38 | it 'includes a link to the site' do |
... | ... | @@ -61,8 +60,7 @@ describe Notify do |
61 | 60 | end |
62 | 61 | |
63 | 62 | it 'should not contain the new user\'s password' do |
64 | - Gitlab.config.gitlab.stub(:signup_enabled).and_return(true) | |
65 | - should_not have_body_text /#{new_user.password}/ | |
63 | + should_not have_body_text /password/ | |
66 | 64 | end |
67 | 65 | |
68 | 66 | it 'includes a link to the site' do | ... | ... |