diff options
38 files changed, 239 insertions, 74 deletions
diff --git a/CHANGELOG b/CHANGELOG index 89656265289..d1644d6be20 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,8 @@ v 6.5.0 - Use jquery timeago plugin - Fix 500 error for rdoc files - Ability to customize merge commit message (sponsored by Say Media) + - Search autocomplete via ajax + - Add website url to user profile v6.4.3 - Don't use unicorn worker killer if PhusionPassenger is defined @@ -52,6 +52,9 @@ gem "grape", "~> 0.6.1" gem "grape-entity", "~> 0.3.0" gem 'rack-cors', require: 'rack/cors' +# Email validation +gem "email_validator", "~> 1.4.0", :require => 'email_validator/strict' + # Format dates and times # based on human-friendly examples gem "stamp" @@ -60,7 +63,7 @@ gem "stamp" gem 'enumerize' # Pagination -gem "kaminari", "~> 0.14.1" +gem "kaminari", "~> 0.15.1" # HAML gem "haml-rails" diff --git a/Gemfile.lock b/Gemfile.lock index 80d98a50889..a501aefcae2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -114,6 +114,8 @@ GEM email_spec (1.5.0) launchy (~> 2.1) mail (~> 2.2) + email_validator (1.4.0) + activemodel enumerize (0.7.0) activesupport (>= 3.2) equalizer (0.0.8) @@ -257,7 +259,7 @@ GEM json (1.8.1) jwt (0.1.8) multi_json (>= 1.5) - kaminari (0.14.1) + kaminari (0.15.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.8.1) @@ -279,7 +281,7 @@ GEM minitest (4.7.5) modernizr (2.6.2) sprockets (~> 2.0) - multi_json (1.8.2) + multi_json (1.8.4) multi_xml (0.5.5) multipart-post (1.2.0) mysql2 (0.3.11) @@ -567,6 +569,7 @@ DEPENDENCIES devise (= 3.0.4) devise-async (= 0.8.0) email_spec + email_validator (~> 1.4.0) enumerize factory_girl_rails ffaker @@ -597,7 +600,7 @@ DEPENDENCIES jquery-rails (= 2.1.3) jquery-turbolinks jquery-ui-rails (= 2.0.2) - kaminari (~> 0.14.1) + kaminari (~> 0.15.1) launchy letter_opener minitest (~> 4.7.0) diff --git a/README.md b/README.md index ed486b0052e..0d5dfa8540a 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ or start each component separately * [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations. -* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton, Drew Blessing and Sam Gleske +* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton (newton), Drew Blessing (dblessing), and Sam Gleske (sag47). * [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview. diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index e264e281309..8ea302f256a 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -47,5 +47,9 @@ class Dispatcher initSearch: -> - autocomplete_json = $('.search-autocomplete-json').data('autocomplete-opts') - new SearchAutocomplete(autocomplete_json) + opts = $('.search-autocomplete-opts') + path = opts.data('autocomplete-path') + project_id = opts.data('autocomplete-project-id') + project_ref = opts.data('autocomplete-project-ref') + + new SearchAutocomplete(path, project_id, project_ref) diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee index 3418690e109..e144dfa1d68 100644 --- a/app/assets/javascripts/search_autocomplete.js.coffee +++ b/app/assets/javascripts/search_autocomplete.js.coffee @@ -1,7 +1,12 @@ class SearchAutocomplete - constructor: (json) -> + constructor: (search_autocomplete_path, project_id, project_ref) -> + project_id = '' unless project_id + project_ref = '' unless project_ref + query = "?project_id=" + project_id + "&project_ref=" + project_ref + $("#search").autocomplete - source: json + source: search_autocomplete_path + query + minLength: 1 select: (event, ui) -> location.href = ui.item.url diff --git a/app/assets/stylesheets/generic/selects.scss b/app/assets/stylesheets/generic/selects.scss index 24fc857f41b..c506bff8a74 100644 --- a/app/assets/stylesheets/generic/selects.scss +++ b/app/assets/stylesheets/generic/selects.scss @@ -1,6 +1,6 @@ /** Select2 selectbox style override **/ -.select2-container { +.select2-container, .select2-container.select2-drop-above { .select2-choice { background: #FFF; border-color: #BBB; diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 770fccaa11b..cb46b5b36e8 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -118,8 +118,7 @@ class Projects::IssuesController < Projects::ApplicationController def issues_filtered params[:scope] = 'all' if params[:scope].blank? params[:state] = 'opened' if params[:state].blank? - params[:project_id] = @project.id - @issues = FilteringService.new.execute(Issue, current_user, params) + @issues = FilteringService.new.execute(Issue, current_user, params.merge(project_id: @project.id)) end # Since iids are implemented only in 6.1 diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 40564c7f889..0792dbf041f 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -20,9 +20,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController params[:sort] ||= 'newest' params[:scope] = 'all' if params[:scope].blank? params[:state] = 'opened' if params[:state].blank? - params[:project_id] = @project.id - @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params) + @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params.merge(project_id: @project.id)) @merge_requests = @merge_requests.page(params[:page]).per(20) @sort = params[:sort].humanize diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index e853c22800a..0152d53f7fc 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,4 +1,6 @@ class SearchController < ApplicationController + include SearchHelper + def show @project = Project.find_by_id(params[:project_id]) if params[:project_id].present? @group = Group.find_by_id(params[:group_id]) if params[:group_id].present? @@ -10,4 +12,12 @@ class SearchController < ApplicationController @search_results = Search::GlobalService.new(current_user, params).execute end end + + def autocomplete + term = params[:term] + @project = Project.find(params[:project_id]) if params[:project_id].present? + @ref = params[:project_ref] if params[:project_ref].present? + + render json: search_autocomplete_opts(term).to_json + end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index f24156e4d85..470a495f036 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,16 +1,22 @@ module SearchHelper - def search_autocomplete_source + def search_autocomplete_opts(term) return unless current_user + + resources_results = [ + groups_autocomplete(term), + projects_autocomplete(term), + public_projects_autocomplete(term), + ].flatten + + generic_results = project_autocomplete + default_autocomplete + help_autocomplete + generic_results.select! { |result| result[:label] =~ Regexp.new(term, "i") } + [ - groups_autocomplete, - projects_autocomplete, - public_projects_autocomplete, - default_autocomplete, - project_autocomplete, - help_autocomplete + resources_results, + generic_results ].flatten.uniq do |item| item[:label] - end.to_json + end end private @@ -43,7 +49,7 @@ module SearchHelper # Autocomplete results for the current project, if it's defined def project_autocomplete if @project && @project.repository.exists? && @project.repository.root_ref - prefix = simple_sanitize(@project.name_with_namespace) + prefix = search_result_sanitize(@project.name_with_namespace) ref = @ref || @project.repository.root_ref [ @@ -65,23 +71,36 @@ module SearchHelper end # Autocomplete results for the current user's groups - def groups_autocomplete - current_user.authorized_groups.map do |group| - { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } + def groups_autocomplete(term, limit = 5) + current_user.authorized_groups.search(term).limit(limit).map do |group| + { + label: "group: #{search_result_sanitize(group.name)}", + url: group_path(group) + } end end # Autocomplete results for the current user's projects - def projects_autocomplete - current_user.authorized_projects.non_archived.map do |p| - { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } + def projects_autocomplete(term, limit = 5) + current_user.authorized_projects.search_by_title(term).non_archived.limit(limit).map do |p| + { + label: "project: #{search_result_sanitize(p.name_with_namespace)}", + url: project_path(p) + } end end # Autocomplete results for the current user's projects - def public_projects_autocomplete - Project.public_or_internal_only(current_user).non_archived.map do |p| - { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } + def public_projects_autocomplete(term, limit = 5) + Project.public_or_internal_only(current_user).search_by_title(term).non_archived.limit(limit).map do |p| + { + label: "project: #{search_result_sanitize(p.name_with_namespace)}", + url: project_path(p) + } end end + + def search_result_sanitize(str) + Sanitize.clean(str) + end end diff --git a/app/models/project.rb b/app/models/project.rb index f322b5a2e25..30faaf00fff 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -138,6 +138,10 @@ class Project < ActiveRecord::Base joins(:namespace).where("projects.archived = ?", false).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%") end + def search_by_title query + where("projects.archived = ?", false).where("LOWER(projects.name) LIKE :query", query: "%#{query.downcase}%") + end + def find_with_namespace(id) if id.include?("/") id = id.split("/") diff --git a/app/models/user.rb b/app/models/user.rb index f2cd554f9c3..54284cc99c8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,7 +41,8 @@ # confirmed_at :datetime # confirmation_sent_at :datetime # unconfirmed_email :string(255) -# hide_no_ssh_key :boolean default(FALSE), not null +# hide_no_ssh_key :boolean default(FALSE) +# website_url :string(255) default(""), not null # require 'carrierwave/orm/activerecord' @@ -52,7 +53,7 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, - :skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password, + :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, as: [:default, :admin] @@ -103,7 +104,7 @@ class User < ActiveRecord::Base # Validations # validates :name, presence: true - validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }, uniqueness: true + validates :email, presence: true, email: {strict_mode: true}, uniqueness: true validates :bio, length: { maximum: 255 }, allow_blank: true validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} @@ -424,4 +425,14 @@ class User < ActiveRecord::Base order('id DESC').limit(1000). update_all(updated_at: Time.now) end + + def full_website_url + return "http://#{website_url}" if website_url !~ /^https?:\/\// + + website_url + end + + def short_website_url + website_url.gsub(/https?:\/\//, '') + end end diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 98bf65bc420..ebc68e2ea63 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -80,6 +80,9 @@ .form-group = f.label :twitter, class: 'control-label' .col-sm-10= f.text_field :twitter, class: 'form-control' + .form-group + = f.label :website_url, class: 'control-label' + .col-sm-10= f.text_field :website_url, class: 'form-control' .form-actions - if @user.new_record? diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 9a0db99332a..a0e55b21c32 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -7,4 +7,4 @@ = hidden_field_tag :search_code, true = hidden_field_tag :repository_ref, @ref = submit_tag 'Go' if ENV['RAILS_ENV'] == 'test' - .search-autocomplete-json.hide{:'data-autocomplete-opts' => search_autocomplete_source } + .search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref } diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 6ae1032aebf..f1ccc000524 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -47,6 +47,9 @@ = f.label :twitter, class: "control-label" .col-sm-10= f.text_field :twitter, class: "form-control" .form-group + = f.label :website_url, class: "control-label" + .col-sm-10= f.text_field :website_url, class: "form-control" + .form-group = f.label :bio, class: "control-label" .col-sm-10 = f.text_area :bio, rows: 6, class: "form-control", maxlength: 250 diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml index 67cb5ccd72d..63ebaadaa80 100644 --- a/app/views/projects/merge_requests/_form.html.haml +++ b/app/views/projects/merge_requests/_form.html.haml @@ -90,6 +90,6 @@ $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); }); $('.assign-to-me-link').on('click', function(e){ - $('#merge_request_assignee_id').val("#{current_user.id}").trigger("select2:updated"); + $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); e.preventDefault(); }); diff --git a/app/views/users/_profile.html.haml b/app/views/users/_profile.html.haml index c7eb6fa182e..30a86ba01f1 100644 --- a/app/views/users/_profile.html.haml +++ b/app/views/users/_profile.html.haml @@ -17,6 +17,10 @@ %li %span.light Twitter: %strong= link_to user.twitter, "http://www.twitter.com/#{user.twitter}" + - unless user.website_url.blank? + %li + %span.light Website url: + %strong= link_to user.short_website_url, user.full_website_url - unless user.bio.blank? %li %span.light Bio: diff --git a/config/routes.rb b/config/routes.rb index 734421ede1d..315c339016b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ Gitlab::Application.routes.draw do # Search # get 'search' => "search#show" + get 'search/autocomplete' => "search#autocomplete", as: :search_autocomplete # API API::API.logger Rails.logger diff --git a/db/migrate/20140116231608_add_website_url_to_users.rb b/db/migrate/20140116231608_add_website_url_to_users.rb new file mode 100644 index 00000000000..0996fdcad73 --- /dev/null +++ b/db/migrate/20140116231608_add_website_url_to_users.rb @@ -0,0 +1,5 @@ +class AddWebsiteUrlToUsers < ActiveRecord::Migration + def change + add_column :users, :website_url, :string, {:null => false, :default => ''} + end +end diff --git a/db/schema.rb b/db/schema.rb index e02799e0dbc..73d0a92e1cc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20131217102743) do +ActiveRecord::Schema.define(version: 20140116231608) do create_table "broadcast_messages", force: true do |t| t.text "message", null: false @@ -301,6 +301,7 @@ ActiveRecord::Schema.define(version: 20131217102743) do t.datetime "confirmation_sent_at" t.string "unconfirmed_email" t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree diff --git a/doc/api/session.md b/doc/api/session.md index 162d4c8bf78..fd18d5c5e97 100644 --- a/doc/api/session.md +++ b/doc/api/session.md @@ -26,6 +26,7 @@ __You can login with both GitLab and LDAP credentials now__ "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "dark_scheme": false, "theme_id": 1, "is_admin": false, diff --git a/doc/api/users.md b/doc/api/users.md index 16479ea6e0d..4098da72b30 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -20,6 +20,7 @@ GET /users "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "john.smith", "provider": "provider_name", "theme_id": 1, @@ -38,6 +39,7 @@ GET /users "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "jack.smith", "provider": "provider_name", "theme_id": 1, @@ -74,6 +76,7 @@ Parameters: "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "john.smith", "provider": "provider_name", "theme_id": 1, @@ -102,6 +105,7 @@ Parameters: + `skype` (optional) - Skype ID + `linkedin` (optional) - Linkedin + `twitter` (optional) - Twitter account ++ `website_url` (optional) - Website url + `projects_limit` (optional) - Number of projects user can create + `extern_uid` (optional) - External UID + `provider` (optional) - External provider name @@ -127,6 +131,7 @@ Parameters: + `skype` - Skype ID + `linkedin` - Linkedin + `twitter` - Twitter account ++ `website_url` - Website url + `projects_limit` - Limit projects each user can create + `extern_uid` - External UID + `provider` - External provider name @@ -174,6 +179,7 @@ GET /user "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "theme_id": 1, "color_scheme_id": 2, "is_admin": false, diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 678c109b266..7d85e8d1fbe 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -55,7 +55,7 @@ it might require some work since GitLab uses several Gems that have native exten - 512MB is too little memory, GitLab will be very slow and you will need 250MB of swap - 768MB is the minimal memory size but we advise against this -- 1GB supports up to 100 users +- 1GB supports up to 100 users if you do not have individual repo's over 250MB - **2GB** is the **recommended** memory size and supports up to 1,000 users - 4GB supports up to 10,000 users diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md index 53bb69ddff8..ac8f0a77efd 100644 --- a/doc/update/6.0-to-6.1.md +++ b/doc/update/6.0-to-6.1.md @@ -30,8 +30,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-1-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-1-stable-ee ``` ### 3. Update gitlab-shell diff --git a/doc/update/6.0-to-6.4.md b/doc/update/6.0-to-6.4.md index 6c0cfafcdf6..1e7af70804b 100644 --- a/doc/update/6.0-to-6.4.md +++ b/doc/update/6.0-to-6.4.md @@ -27,8 +27,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-4-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-4-stable-ee ``` diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md index a3849faf065..7342a9117c6 100644 --- a/doc/update/6.1-to-6.2.md +++ b/doc/update/6.1-to-6.2.md @@ -23,8 +23,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-2-stable # Latest version of 6-2-stable addresses CVE-2013-4489 +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-2-stable-ee ``` ### 3. Update gitlab-shell diff --git a/doc/update/6.2-to-6.3.md b/doc/update/6.2-to-6.3.md index 5b02b4cb4dd..7f916047369 100644 --- a/doc/update/6.2-to-6.3.md +++ b/doc/update/6.2-to-6.3.md @@ -20,8 +20,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-3-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-3-stable-ee ``` ### 3. Update gitlab-shell (and its config) diff --git a/doc/update/6.3-to-6.4.md b/doc/update/6.3-to-6.4.md index 69d184722cb..6874056498b 100644 --- a/doc/update/6.3-to-6.4.md +++ b/doc/update/6.3-to-6.4.md @@ -15,8 +15,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-4-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-4-stable-ee ``` ### 3. Update gitlab-shell (and its config) diff --git a/features/profile/profile.feature b/features/profile/profile.feature index 6b0421a20b3..8b6ee6fd67f 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -8,8 +8,8 @@ Feature: Profile Scenario: I edit profile Given I visit profile page - Then I change my contact info - And I should see new contact info + Then I change my profile info + And I should see new profile info Scenario: I change my password without old one Given I visit profile password page diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 7bb4aebde28..33ae6c72998 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -6,18 +6,20 @@ class Profile < Spinach::FeatureSteps page.should have_content "Profile settings" end - step 'I change my contact info' do + step 'I change my profile info' do fill_in "user_skype", with: "testskype" fill_in "user_linkedin", with: "testlinkedin" fill_in "user_twitter", with: "testtwitter" + fill_in "user_website_url", with: "testurl" click_button "Save changes" @user.reload end - step 'I should see new contact info' do + step 'I should see new profile info' do @user.skype.should == 'testskype' @user.linkedin.should == 'testlinkedin' @user.twitter.should == 'testtwitter' + @user.website_url.should == 'testurl' end step 'I change my avatar' do diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8d2f38c4daa..76a56a0f0a6 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1,7 +1,7 @@ module API module Entities class User < Grape::Entity - expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, + expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, :website_url, :theme_id, :color_scheme_id, :state, :created_at, :extern_uid, :provider expose :is_admin?, as: :is_admin expose :can_create_group?, as: :can_create_group diff --git a/lib/api/users.rb b/lib/api/users.rb index 475343a3edf..89ec2c61a86 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -36,6 +36,7 @@ module API # skype - Skype ID # linkedin - Linkedin # twitter - Twitter account + # website_url - Website url # projects_limit - Number of projects user can create # extern_uid - External authentication provider UID # provider - External provider @@ -67,6 +68,7 @@ module API # skype - Skype ID # linkedin - Linkedin # twitter - Twitter account + # website_url - Website url # projects_limit - Limit projects each user can create # extern_uid - External authentication provider UID # provider - External provider @@ -78,7 +80,7 @@ module API put ":id" do authenticated_as_admin! - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] user = User.find(params[:id]) not_found!("User not found") unless user diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index f1b94087b6a..cb2db44c97c 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -20,7 +20,7 @@ # DO NOT EDIT THIS FILE! # This file will be overwritten on update. # Instead add/change your variables in /etc/default/gitlab -# An example defaults file can be found in lib/support/default/gitlab +# An example defaults file can be found in lib/support/init.d/gitlab.default.example ### diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example index 4230783a9d7..9951bacedf5 100755 --- a/lib/support/init.d/gitlab.default.example +++ b/lib/support/init.d/gitlab.default.example @@ -12,3 +12,20 @@ app_user="git" # app_root defines the folder in which gitlab and it's components are installed. # The default is "/home/$app_user/gitlab" app_root="/home/$app_user/gitlab" + +# pid_path defines a folder in which the gitlab and it's components place their pids. +# This variable is also used below to define the relevant pids for the gitlab components. +# The default is "$app_root/tmp/pids" +pid_path="$app_root/tmp/pids" + +# socket_path defines the folder in which gitlab places the sockets +#The default is "$app_root/tmp/sockets" +socket_path="$app_root/tmp/sockets" + +# web_server_pid_path defines the path in which to create the pid file fo the web_server +# The default is "$pid_path/unicorn.pid" +web_server_pid_path="$pid_path/unicorn.pid" + +# sidekiq_pid_path defines the path in which to create the pid file for sidekiq +# The default is "$pid_path/sidekiq.pid" +sidekiq_pid_path="$pid_path/sidekiq.pid" diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index 83e941adcb1..0d1d4ffff27 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -2,12 +2,12 @@ namespace :gitlab do namespace :import do # How to use: # - # 1. copy your bare repos under git repos_path - # 2. run bundle exec rake gitlab:import:repos RAILS_ENV=production + # 1. copy the bare repos under the repos_path (commonly /home/git/repositories) + # 2. run: bundle exec rake gitlab:import:repos RAILS_ENV=production # # Notes: - # * project owner will be a first admin - # * existing projects will be skipped + # * The project owner will set to the first administator of the system + # * Existing projects will be skipped # desc "GITLAB | Import bare repositories from gitlab_shell -> repos_path into GitLab project instance" task repos: :environment do diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 33ecb980202..d04945dfe35 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -13,52 +13,41 @@ describe SearchHelper do end it "it returns nil" do - search_autocomplete_source.should be_nil + search_autocomplete_opts("q").should be_nil end end context "with a user" do let(:user) { create(:user) } - let(:result) { JSON.parse(search_autocomplete_source) } before do allow(self).to receive(:current_user).and_return(user) end it "includes Help sections" do - result.select { |h| h['label'] =~ /^help:/ }.length.should == 9 + search_autocomplete_opts("hel").size.should == 9 end it "includes default sections" do - result.count { |h| h['label'] =~ /^(My|Admin)\s/ }.should == 4 + search_autocomplete_opts("adm").size.should == 1 end it "includes the user's groups" do create(:group).add_owner(user) - result.count { |h| h['label'] =~ /^group:/ }.should == 1 + search_autocomplete_opts("gro").size.should == 1 end it "includes the user's projects" do - create(:project, namespace: create(:namespace, owner: user)) - result.count { |h| h['label'] =~ /^project:/ }.should == 1 + project = create(:project, namespace: create(:namespace, owner: user)) + search_autocomplete_opts(project.name).size.should == 1 end context "with a current project" do before { @project = create(:project_with_code) } it "includes project-specific sections" do - result.count { |h| h['label'] =~ /^#{@project.name_with_namespace} - / }.should == 11 - end - - it "uses @ref in urls if defined" do - @ref = "foo_bar" - result.count { |h| h['url'] == project_tree_path(@project, @ref) }.should == 1 - end - end - - context "with no current project" do - it "does not include project-specific sections" do - result.count { |h| h['label'] =~ /Files$/ }.should == 0 + search_autocomplete_opts("Files").size.should == 1 + search_autocomplete_opts("Commits").size.should == 1 end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 94bd19f5900..5e53ed09b58 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -41,6 +41,8 @@ # confirmed_at :datetime # confirmation_sent_at :datetime # unconfirmed_email :string(255) +# hide_no_ssh_key :boolean default(FALSE) +# website_url :string(255) default(""), not null # require 'spec_helper' @@ -74,6 +76,27 @@ describe User do it { should_not allow_value(-1).for(:projects_limit) } it { should ensure_length_of(:bio).is_within(0..255) } + + describe 'email' do + it 'accepts info@example.com' do + user = build(:user, email: 'info@example.com') + expect(user).to be_valid + end + it 'accepts info+test@example.com' do + user = build(:user, email: 'info+test@example.com') + expect(user).to be_valid + end + + it 'rejects test@test@example.com' do + user = build(:user, email: 'test@test@example.com') + expect(user).to be_invalid + end + + it 'rejects mailto:test@example.com' do + user = build(:user, email: 'mailto:test@example.com') + expect(user).to be_invalid + end + end end describe "Respond to" do @@ -293,4 +316,48 @@ describe User do user.avatar_type.should == ["only images allowed"] end end + + describe '#full_website_url' do + let(:user) { create(:user) } + + it 'begins with http if website url omits it' do + user.website_url = 'test.com' + + expect(user.full_website_url).to eq 'http://test.com' + end + + it 'begins with http if website url begins with http' do + user.website_url = 'http://test.com' + + expect(user.full_website_url).to eq 'http://test.com' + end + + it 'begins with https if website url begins with https' do + user.website_url = 'https://test.com' + + expect(user.full_website_url).to eq 'https://test.com' + end + end + + describe '#short_website_url' do + let(:user) { create(:user) } + + it 'does not begin with http if website url omits it' do + user.website_url = 'test.com' + + expect(user.short_website_url).to eq 'test.com' + end + + it 'does not begin with http if website url begins with http' do + user.website_url = 'http://test.com' + + expect(user.short_website_url).to eq 'test.com' + end + + it 'does not begin with https if website url begins with https' do + user.website_url = 'https://test.com' + + expect(user.short_website_url).to eq 'test.com' + end + end end |