From 372cb87f05e73dadb1304a9b8412e32624258e5b Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 4 Dec 2014 09:47:27 +0100 Subject: [PATCH 01/13] Reword the 512 memmory advise. --- doc/install/requirements.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 2b60c3560a..660c1adb80 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -50,12 +50,12 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab ### Memory -- 512MB is the absolute minimum but we do not recommend this amount of memory. -You will need to configure minimum 1.5GB of swap space. -With 1.5GB of swap space you must configure only one unicorn worker. -With one unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check). -If you use SSD storage and configure 1.5GB of swap space you can use two Unicorn workers, this will allow HTTP access but it will still be slow. -Consider installing GitLab on Ubuntu as installation on CentOS could be unsuccessful with this amount of memory. +- 512MB is the absolute minimum but we strongly **advise against** this amount of memory. +You will need to configure a minimum of 1.5GB of swap space to make the Omnibus package reconfigure run succeed. +If you use a magnetic (non-SSD) swap drive we recommend to configure only one Unicorn worker. +With one Unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check). +If you use a SSD drive you can use two Unicorn workers, this will allow HTTP access although it will be slow. +Consider installing GitLab on Ubuntu instead of CentOS because sometimes CentOS gives errors during installation and usage with this amount of memory. - 1GB RAM + 1GB swap supports up to 100 users - **2GB RAM** is the **recommended** memory size and supports up to 500 users - 4GB RAM supports up to 2,000 users From 1a80d13a3990937580c97e2b0ba8fb98f69bc055 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 25 Nov 2014 18:15:30 +0200 Subject: [PATCH 02/13] Multi-provider auth. LDAP is not reworked --- .../omniauth_callbacks_controller.rb | 7 +- app/helpers/profile_helper.rb | 2 +- app/models/identity.rb | 7 ++ app/models/user.rb | 3 +- .../20141121161704_add_identity_table.rb | 21 ++++ db/schema.rb | 107 +++++++++++++----- lib/gitlab/ldap/user.rb | 5 +- lib/gitlab/oauth/user.rb | 21 ++-- 8 files changed, 123 insertions(+), 50 deletions(-) create mode 100644 app/models/identity.rb create mode 100644 db/migrate/20141121161704_add_identity_table.rb diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index bd4b310fcb..58d0506c07 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -42,10 +42,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def handle_omniauth if current_user - # Change a logged-in user's authentication method: - current_user.extern_uid = oauth['uid'] - current_user.provider = oauth['provider'] - current_user.save + # Add new authentication method + current_user.identities.find_or_create_by(extern_uid: oauth['uid'], provider: oauth['provider']) redirect_to profile_path else @user = Gitlab::OAuth::User.new(oauth) @@ -53,6 +51,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Only allow properly saved users to login. if @user.persisted? && @user.valid? + # binding.pry sign_in_and_redirect(@user.gl_user) else error_message = diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 0b37555830..816074e024 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -1,6 +1,6 @@ module ProfileHelper def oauth_active_class(provider) - if current_user.provider == provider.to_s + if current_user.identities.exists?(provider: provider.to_s) 'active' end end diff --git a/app/models/identity.rb b/app/models/identity.rb new file mode 100644 index 0000000000..e6af93bcc5 --- /dev/null +++ b/app/models/identity.rb @@ -0,0 +1,7 @@ +class Identity < ActiveRecord::Base + belongs_to :user + + validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} + + scope :ldap, -> { where('provider LIKE ?', 'ldap%') } +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 1cddd85ada..0cf0946593 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -79,6 +79,7 @@ class User < ActiveRecord::Base # Profile has_many :keys, dependent: :destroy has_many :emails, dependent: :destroy + has_many :identities, dependent: :destroy # Groups has_many :members, dependent: :destroy @@ -113,7 +114,6 @@ class User < ActiveRecord::Base validates :name, presence: 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} validates :username, presence: true, uniqueness: { case_sensitive: false }, exclusion: { in: Gitlab::Blacklist.path }, @@ -178,7 +178,6 @@ class User < ActiveRecord::Base scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } - scope :ldap, -> { where('provider LIKE ?', 'ldap%') } scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active } # diff --git a/db/migrate/20141121161704_add_identity_table.rb b/db/migrate/20141121161704_add_identity_table.rb new file mode 100644 index 0000000000..7d019c65ee --- /dev/null +++ b/db/migrate/20141121161704_add_identity_table.rb @@ -0,0 +1,21 @@ +class AddIdentityTable < ActiveRecord::Migration + def up + create_table :identities do |t| + t.string :extern_uid + t.string :provider + t.references :user + end + + add_index :identities, :user_id + + User.where("provider is not NULL").find_each do |user| + execute "INSERT INTO identities(provider, extern_uid, user_id) VALUES('#{user.provider}', '#{user.extern_uid}', '#{user.id}')" + end + + #TODO remove user's columns extern_uid and provider + end + + def down +#TODO + end +end diff --git a/db/schema.rb b/db/schema.rb index 68d1080b6e..34f991e5cf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,11 +11,20 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141121133009) do +ActiveRecord::Schema.define(version: 20141121161704) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "appearances", force: true do |t| + t.string "title" + t.text "description" + t.string "logo" + t.integer "updated_by" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "broadcast_messages", force: true do |t| t.text "message", null: false t.datetime "starts_at" @@ -74,6 +83,29 @@ ActiveRecord::Schema.define(version: 20141121133009) do add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree + create_table "git_hooks", force: true do |t| + t.string "force_push_regex" + t.string "delete_branch_regex" + t.string "commit_message_regex" + t.boolean "deny_delete_tag" + t.integer "project_id" + t.datetime "created_at" + t.datetime "updated_at" + t.string "username_regex" + t.string "email_regex" + t.string "author_email_regex" + t.boolean "member_check", default: false, null: false + t.string "file_name_regex" + end + + create_table "identities", force: true do |t| + t.string "extern_uid" + t.string "provider" + t.integer "user_id" + end + + add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree + create_table "issues", force: true do |t| t.string "title" t.integer "assignee_id" @@ -130,6 +162,15 @@ ActiveRecord::Schema.define(version: 20141121133009) do add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree + create_table "ldap_group_links", force: true do |t| + t.string "cn", null: false + t.integer "group_access", null: false + t.integer "group_id", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "provider" + end + create_table "members", force: true do |t| t.integer "access_level", null: false t.integer "source_id", null: false @@ -209,6 +250,8 @@ ActiveRecord::Schema.define(version: 20141121133009) do t.string "type" t.string "description", default: "", null: false t.string "avatar" + t.string "ldap_cn" + t.integer "ldap_access" end add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree @@ -240,6 +283,14 @@ ActiveRecord::Schema.define(version: 20141121133009) do add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree + create_table "project_group_links", force: true do |t| + t.integer "project_id", null: false + t.integer "group_id", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.integer "group_access", default: 30, null: false + end + create_table "projects", force: true do |t| t.string "name" t.string "path" @@ -247,21 +298,22 @@ ActiveRecord::Schema.define(version: 20141121133009) do t.datetime "created_at" t.datetime "updated_at" t.integer "creator_id" - t.boolean "issues_enabled", default: true, null: false - t.boolean "wall_enabled", default: true, null: false - t.boolean "merge_requests_enabled", default: true, null: false - t.boolean "wiki_enabled", default: true, null: false + t.boolean "issues_enabled", default: true, null: false + t.boolean "wall_enabled", default: true, null: false + t.boolean "merge_requests_enabled", default: true, null: false + t.boolean "wiki_enabled", default: true, null: false t.integer "namespace_id" - t.string "issues_tracker", default: "gitlab", null: false + t.string "issues_tracker", default: "gitlab", null: false t.string "issues_tracker_id" - t.boolean "snippets_enabled", default: true, null: false + t.boolean "snippets_enabled", default: true, null: false t.datetime "last_activity_at" t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false t.string "import_status" - t.float "repository_size", default: 0.0 - t.integer "star_count", default: 0, null: false + t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false + t.text "merge_requests_template" end add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree @@ -327,12 +379,12 @@ ActiveRecord::Schema.define(version: 20141121133009) do end create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -340,24 +392,24 @@ ActiveRecord::Schema.define(version: 20141121133009) do t.datetime "created_at" t.datetime "updated_at" t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.string "authentication_token" - t.integer "theme_id", default: 1, null: false + t.integer "theme_id", default: 1, null: false t.string "bio" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", default: 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false t.string "state" - t.integer "color_scheme_id", default: 1, null: false - t.integer "notification_level", default: 1, null: false + t.integer "color_scheme_id", default: 1, null: false + t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" t.string "avatar" @@ -365,9 +417,10 @@ ActiveRecord::Schema.define(version: 20141121133009) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false t.datetime "last_credential_check_at" + t.datetime "admin_email_unsubscribed_at" end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 3176e9790a..827a33b521 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -12,9 +12,10 @@ module Gitlab class << self def find_by_uid_and_provider(uid, provider) # LDAP distinguished name is case-insensitive - ::User. + identity = ::Identity. where(provider: [provider, :ldap]). where('lower(extern_uid) = ?', uid.downcase).last + identity && identity.user end end @@ -34,7 +35,7 @@ module Gitlab end def find_by_email - model.find_by(email: auth_hash.email) + User.find_by(email: auth_hash.email) end def update_user_attributes diff --git a/lib/gitlab/oauth/user.rb b/lib/gitlab/oauth/user.rb index 47f62153a5..7c1970eb8e 100644 --- a/lib/gitlab/oauth/user.rb +++ b/lib/gitlab/oauth/user.rb @@ -27,11 +27,9 @@ module Gitlab def save unauthorized_to_create unless gl_user + gl_user.save! if needs_blocking? - gl_user.save! gl_user.block - else - gl_user.save! end log.info "(OAuth) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" @@ -70,24 +68,23 @@ module Gitlab end def find_by_uid_and_provider - model.where(provider: auth_hash.provider, extern_uid: auth_hash.uid).last + identity = Identity.find_by(provider: auth_hash.provider, extern_uid: auth_hash.uid) + identity && identity.user end def build_new_user - model.new(user_attributes).tap do |user| - user.skip_confirmation! - end + user = User.new(user_attributes) + user.skip_confirmation! + user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider) end def user_attributes { - extern_uid: auth_hash.uid, - provider: auth_hash.provider, name: auth_hash.name, username: auth_hash.username, email: auth_hash.email, password: auth_hash.password, - password_confirmation: auth_hash.password, + password_confirmation: auth_hash.password } end @@ -95,10 +92,6 @@ module Gitlab Gitlab::AppLogger end - def model - ::User - end - def raise_unauthorized_to_create raise StandardError.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}") end From 3a5ed5260b24051939575d1934ce9b8392cac09f Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 27 Nov 2014 13:34:39 +0200 Subject: [PATCH 03/13] Supporting for multiple omniauth provider for the same user --- .../omniauth_callbacks_controller.rb | 5 +- app/helpers/profile_helper.rb | 4 +- app/models/identity.rb | 2 - app/models/user.rb | 6 +- app/services/notification_service.rb | 2 +- app/views/admin/users/show.html.haml | 2 +- .../sessions/_oauth_providers.html.haml | 2 +- .../20141121161704_add_identity_table.rb | 17 ++- db/schema.rb | 102 +++++------------- features/steps/profile/profile.rb | 2 +- lib/api/entities.rb | 8 +- lib/api/users.rb | 12 ++- lib/gitlab/ldap/access.rb | 8 +- lib/gitlab/ldap/user.rb | 10 +- lib/gitlab/oauth/user.rb | 13 ++- spec/factories.rb | 22 +++- spec/lib/gitlab/ldap/user_spec.rb | 8 +- spec/lib/gitlab/oauth/user_spec.rb | 7 +- spec/models/user_spec.rb | 16 ++- spec/requests/api/users_spec.rb | 2 +- 20 files changed, 123 insertions(+), 127 deletions(-) diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 58d0506c07..3e984e5007 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -51,7 +51,6 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Only allow properly saved users to login. if @user.persisted? && @user.valid? - # binding.pry sign_in_and_redirect(@user.gl_user) else error_message = @@ -66,8 +65,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return end end - rescue StandardError - flash[:notice] = "There's no such user!" + rescue ForbiddenAction => e + flash[:notice] = e.message redirect_to new_user_session_path end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 816074e024..6480fd3886 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -10,10 +10,10 @@ module ProfileHelper end def show_profile_social_tab? - enabled_social_providers.any? && !current_user.ldap_user? + enabled_social_providers.any? end def show_profile_remove_tab? - gitlab_config.signup_enabled && !current_user.ldap_user? + gitlab_config.signup_enabled end end diff --git a/app/models/identity.rb b/app/models/identity.rb index e6af93bcc5..5fb1850c30 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -2,6 +2,4 @@ class Identity < ActiveRecord::Base belongs_to :user validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} - - scope :ldap, -> { where('provider LIKE ?', 'ldap%') } end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 0cf0946593..7faeef1b5b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -406,7 +406,11 @@ class User < ActiveRecord::Base end def ldap_user? - extern_uid && provider.start_with?('ldap') + identities.exists?(["provider LIKE ? AND extern_uid IS NOT NULL", "ldap%"]) + end + + def ldap_identity + @ldap_identity ||= identities.find_by(["provider LIKE ?", "ldap%"]) end def accessible_deploy_keys diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 2b6217e2e2..d1aadd741e 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -107,7 +107,7 @@ class NotificationService # Notify new user with email after creation def new_user(user, token = nil) # Don't email omniauth created users - mailer.new_user_email(user.id, token) unless user.extern_uid? + mailer.new_user_email(user.id, token) unless user.identities.any? end # Notify users on new note in system diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 211d77d518..29717aedd8 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -95,7 +95,7 @@ %li %span.light LDAP uid: %strong - = @user.extern_uid + = @user.ldap_identity.extern_uid - if @user.created_by %li diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml index 15048a7806..d053c51d7e 100644 --- a/app/views/devise/sessions/_oauth_providers.html.haml +++ b/app/views/devise/sessions/_oauth_providers.html.haml @@ -1,4 +1,4 @@ -- providers = (enabled_oauth_providers - [:ldap]) +- providers = enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} - if providers.present? .bs-callout.bs-callout-info{:'data-no-turbolink' => 'data-no-turbolink'} %span Sign in with:   diff --git a/db/migrate/20141121161704_add_identity_table.rb b/db/migrate/20141121161704_add_identity_table.rb index 7d019c65ee..243958039a 100644 --- a/db/migrate/20141121161704_add_identity_table.rb +++ b/db/migrate/20141121161704_add_identity_table.rb @@ -8,14 +8,25 @@ class AddIdentityTable < ActiveRecord::Migration add_index :identities, :user_id - User.where("provider is not NULL").find_each do |user| + User.where("provider IS NOT NULL").find_each do |user| execute "INSERT INTO identities(provider, extern_uid, user_id) VALUES('#{user.provider}', '#{user.extern_uid}', '#{user.id}')" end - #TODO remove user's columns extern_uid and provider + remove_column :users, :extern_uid + remove_column :users, :provider end def down -#TODO + add_column :users, :extern_uid, :string + add_column :users, :provider, :string + + User.where("id IN(SELECT user_id FROM identities)").find_each do |user| + identity = user.identities.last + user.extern_uid = identity.extern_uid + user.provider = identity.provider + user.save + end + + drop_table :identities end end diff --git a/db/schema.rb b/db/schema.rb index 34f991e5cf..ec211901e4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -16,15 +16,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" - create_table "appearances", force: true do |t| - t.string "title" - t.text "description" - t.string "logo" - t.integer "updated_by" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "broadcast_messages", force: true do |t| t.text "message", null: false t.datetime "starts_at" @@ -83,21 +74,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree - create_table "git_hooks", force: true do |t| - t.string "force_push_regex" - t.string "delete_branch_regex" - t.string "commit_message_regex" - t.boolean "deny_delete_tag" - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.string "username_regex" - t.string "email_regex" - t.string "author_email_regex" - t.boolean "member_check", default: false, null: false - t.string "file_name_regex" - end - create_table "identities", force: true do |t| t.string "extern_uid" t.string "provider" @@ -162,15 +138,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree - create_table "ldap_group_links", force: true do |t| - t.string "cn", null: false - t.integer "group_access", null: false - t.integer "group_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "provider" - end - create_table "members", force: true do |t| t.integer "access_level", null: false t.integer "source_id", null: false @@ -250,8 +217,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do t.string "type" t.string "description", default: "", null: false t.string "avatar" - t.string "ldap_cn" - t.integer "ldap_access" end add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree @@ -283,14 +248,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree - create_table "project_group_links", force: true do |t| - t.integer "project_id", null: false - t.integer "group_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.integer "group_access", default: 30, null: false - end - create_table "projects", force: true do |t| t.string "name" t.string "path" @@ -298,22 +255,21 @@ ActiveRecord::Schema.define(version: 20141121161704) do t.datetime "created_at" t.datetime "updated_at" t.integer "creator_id" - t.boolean "issues_enabled", default: true, null: false - t.boolean "wall_enabled", default: true, null: false - t.boolean "merge_requests_enabled", default: true, null: false - t.boolean "wiki_enabled", default: true, null: false + t.boolean "issues_enabled", default: true, null: false + t.boolean "wall_enabled", default: true, null: false + t.boolean "merge_requests_enabled", default: true, null: false + t.boolean "wiki_enabled", default: true, null: false t.integer "namespace_id" - t.string "issues_tracker", default: "gitlab", null: false + t.string "issues_tracker", default: "gitlab", null: false t.string "issues_tracker_id" - t.boolean "snippets_enabled", default: true, null: false + t.boolean "snippets_enabled", default: true, null: false t.datetime "last_activity_at" t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false t.string "import_status" - t.float "repository_size", default: 0.0 - t.integer "star_count", default: 0, null: false - t.text "merge_requests_template" + t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false end add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree @@ -379,12 +335,12 @@ ActiveRecord::Schema.define(version: 20141121161704) do end create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -392,35 +348,32 @@ ActiveRecord::Schema.define(version: 20141121161704) do t.datetime "created_at" t.datetime "updated_at" t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false t.string "authentication_token" - t.integer "theme_id", default: 1, null: false + t.integer "theme_id", default: 1, null: false t.string "bio" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", default: 0 t.datetime "locked_at" - t.string "extern_uid" - t.string "provider" t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false t.string "state" - t.integer "color_scheme_id", default: 1, null: false - t.integer "notification_level", default: 1, null: false + t.integer "color_scheme_id", default: 1, null: false + t.integer "notification_level", default: 1, null: false t.datetime "password_expires_at" t.integer "created_by_id" + t.datetime "last_credential_check_at" t.string "avatar" t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false - t.datetime "last_credential_check_at" - t.datetime "admin_email_unsubscribed_at" + 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 @@ -428,7 +381,6 @@ ActiveRecord::Schema.define(version: 20141121161704) do add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree - add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree add_index "users", ["username"], name: "index_users_on_username", using: :btree diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 6d747b65ba..38aaadcd28 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -170,7 +170,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I am not an ldap user" do - current_user.update_attributes(extern_uid: nil, provider: '') + current_user.identities.delete current_user.ldap_user?.should be_false end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 42e4442365..2fea151aeb 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -14,10 +14,14 @@ module API expose :bio, :skype, :linkedin, :twitter, :website_url end + class Identity < Grape::Entity + expose :provider, :extern_uid + end + class UserFull < User expose :email - expose :theme_id, :color_scheme_id, :extern_uid, :provider, \ - :projects_limit + expose :theme_id, :color_scheme_id, :projects_limit + expose :identities, using: Entities::Identity expose :can_create_group?, as: :can_create_group expose :can_create_project?, as: :can_create_project end diff --git a/lib/api/users.rb b/lib/api/users.rb index d07815a8a9..37b36ddcf9 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -59,10 +59,16 @@ module API post do authenticated_as_admin! required_attributes! [:email, :password, :name, :username] - 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, :projects_limit, :username, :bio, :can_create_group, :admin] user = User.build_user(attrs) admin = attrs.delete(:admin) user.admin = admin unless admin.nil? + + identity_attrs = attributes_for_keys [:provider, :extern_uid] + if identity_attrs.any? + user.identities.build(identity_attrs) + end + if user.save present user, with: Entities::UserFull else @@ -89,8 +95,6 @@ module API # twitter - Twitter account # website_url - Website url # projects_limit - Limit projects each user can create - # extern_uid - External authentication provider UID - # provider - External provider # bio - Bio # admin - User is admin - true or false (default) # can_create_group - User can create groups - true or false @@ -99,7 +103,7 @@ module API put ":id" do authenticated_as_admin! - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :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, :bio, :can_create_group, :admin] user = User.find(params[:id]) not_found!('User') unless user diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index eb2c4e48ff..0c85acf7e6 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -8,7 +8,7 @@ module Gitlab attr_reader :adapter, :provider, :user def self.open(user, &block) - Gitlab::LDAP::Adapter.open(user.provider) do |adapter| + Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter| block.call(self.new(user, adapter)) end end @@ -28,13 +28,13 @@ module Gitlab def initialize(user, adapter=nil) @adapter = adapter @user = user - @provider = user.provider + @provider = user.ldap_identity.provider end def allowed? - if Gitlab::LDAP::Person.find_by_dn(user.extern_uid, adapter) + if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) return true unless ldap_config.active_directory - !Gitlab::LDAP::Person.disabled_via_active_directory?(user.extern_uid, adapter) + !Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter) else false end diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 827a33b521..3ef494ba13 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -35,15 +35,13 @@ module Gitlab end def find_by_email - User.find_by(email: auth_hash.email) + ::User.find_by(email: auth_hash.email) end def update_user_attributes - gl_user.attributes = { - extern_uid: auth_hash.uid, - provider: auth_hash.provider, - email: auth_hash.email - } + gl_user.email = auth_hash.email + gl_user.identities.build(provider: auth_hash.provider, extern_uid: auth_hash.uid) + gl_user end def changed? diff --git a/lib/gitlab/oauth/user.rb b/lib/gitlab/oauth/user.rb index 7c1970eb8e..6861427864 100644 --- a/lib/gitlab/oauth/user.rb +++ b/lib/gitlab/oauth/user.rb @@ -5,6 +5,8 @@ # module Gitlab module OAuth + class ForbiddenAction < StandardError; end + class User attr_accessor :auth_hash, :gl_user @@ -27,9 +29,11 @@ module Gitlab def save unauthorized_to_create unless gl_user - gl_user.save! if needs_blocking? + gl_user.save! gl_user.block + else + gl_user.save! end log.info "(OAuth) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" @@ -73,9 +77,10 @@ module Gitlab end def build_new_user - user = User.new(user_attributes) + user = ::User.new(user_attributes) user.skip_confirmation! user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider) + user end def user_attributes @@ -92,8 +97,8 @@ module Gitlab Gitlab::AppLogger end - def raise_unauthorized_to_create - raise StandardError.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}") + def unauthorized_to_create + raise ForbiddenAction.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}") end end end diff --git a/spec/factories.rb b/spec/factories.rb index 15899d8c3c..5806013163 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -18,15 +18,24 @@ FactoryGirl.define do password "12345678" password_confirmation { password } confirmed_at { Time.now } - confirmation_token { nil } + confirmation_token { nil } trait :admin do admin true end - trait :ldap do - provider 'ldapmain' - extern_uid 'my-ldap-id' + factory :omniauth_user do + ignore do + extern_uid '123456' + provider 'ldapmain' + end + + after(:create) do |user, evaluator| + user.identities << create(:identity, + provider: evaluator.provider, + extern_uid: evaluator.extern_uid + ) + end end factory :admin, traits: [:admin] @@ -182,4 +191,9 @@ FactoryGirl.define do deploy_key project end + + factory :identity do + provider 'ldapmain' + extern_uid 'my-ldap-id' + end end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 726c9764e3..294ee6cbae 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -15,18 +15,18 @@ describe Gitlab::LDAP::User do describe :find_or_create do it "finds the user if already existing" do - existing_user = create(:user, extern_uid: 'my-uid', provider: 'ldapmain') + existing_user = create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain') expect{ gl_user.save }.to_not change{ User.count } end it "connects to existing non-ldap user if the email matches" do - existing_user = create(:user, email: 'john@example.com') + existing_user = create(:omniauth_user, email: 'john@example.com') expect{ gl_user.save }.to_not change{ User.count } existing_user.reload - expect(existing_user.extern_uid).to eql 'my-uid' - expect(existing_user.provider).to eql 'ldapmain' + expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid' + expect(existing_user.ldap_identity.provider).to eql 'ldapmain' end it "creates a new user if not found" do diff --git a/spec/lib/gitlab/oauth/user_spec.rb b/spec/lib/gitlab/oauth/user_spec.rb index 8a83a1b258..8830751578 100644 --- a/spec/lib/gitlab/oauth/user_spec.rb +++ b/spec/lib/gitlab/oauth/user_spec.rb @@ -15,7 +15,7 @@ describe Gitlab::OAuth::User do end describe :persisted? do - let!(:existing_user) { create(:user, extern_uid: 'my-uid', provider: 'my-provider') } + let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') } it "finds an existing user based on uid and provider (facebook)" do auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider') @@ -39,8 +39,9 @@ describe Gitlab::OAuth::User do oauth_user.save expect(gl_user).to be_valid - expect(gl_user.extern_uid).to eql uid - expect(gl_user.provider).to eql 'twitter' + identity = gl_user.identities.first + expect(identity.extern_uid).to eql uid + expect(identity.provider).to eql 'twitter' end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6d865cfc69..8be7f733a5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -62,6 +62,7 @@ describe User do it { should have_many(:assigned_issues).dependent(:destroy) } it { should have_many(:merge_requests).dependent(:destroy) } it { should have_many(:assigned_merge_requests).dependent(:destroy) } + it { should have_many(:identities).dependent(:destroy) } end describe "Mass assignment" do @@ -361,24 +362,29 @@ describe User do end describe :ldap_user? do - let(:user) { build(:user, :ldap) } - it "is true if provider name starts with ldap" do - user.provider = 'ldapmain' + user = create(:omniauth_user, provider: 'ldapmain') expect( user.ldap_user? ).to be_true end it "is false for other providers" do - user.provider = 'other-provider' + user = create(:omniauth_user, provider: 'other-provider') expect( user.ldap_user? ).to be_false end it "is false if no extern_uid is provided" do - user.extern_uid = nil + user = create(:omniauth_user, extern_uid: nil) expect( user.ldap_user? ).to be_false end end + describe :ldap_identity do + it "returns ldap identity" do + user = create :omniauth_user + user.ldap_identity.provider.should_not be_empty + end + end + describe '#full_website_url' do let(:user) { create(:user) } diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 113a39b870..1ecc79ea7e 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -33,7 +33,7 @@ describe API::API, api: true do response.status.should == 200 json_response.should be_an Array json_response.first.keys.should include 'email' - json_response.first.keys.should include 'extern_uid' + json_response.first.keys.should include 'identities' json_response.first.keys.should include 'can_create_project' end end From b56b96d438c92981cd5c0f5e2f4b23d3799a3bd3 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 4 Dec 2014 12:55:37 +0200 Subject: [PATCH 04/13] added helper --- app/helpers/oauth_helper.rb | 4 ++++ .../devise/sessions/_oauth_providers.html.haml | 2 +- spec/helpers/oauth_helper_spec.rb | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 spec/helpers/oauth_helper_spec.rb diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb index 7024483b8b..df18db71c8 100644 --- a/app/helpers/oauth_helper.rb +++ b/app/helpers/oauth_helper.rb @@ -16,4 +16,8 @@ module OauthHelper [:twitter, :github, :google_oauth2].include?(name.to_sym) end end + + def additional_providers + enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} + end end diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml index d053c51d7e..8d6aaefb9f 100644 --- a/app/views/devise/sessions/_oauth_providers.html.haml +++ b/app/views/devise/sessions/_oauth_providers.html.haml @@ -1,4 +1,4 @@ -- providers = enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} +- providers = additional_providers - if providers.present? .bs-callout.bs-callout-info{:'data-no-turbolink' => 'data-no-turbolink'} %span Sign in with:   diff --git a/spec/helpers/oauth_helper_spec.rb b/spec/helpers/oauth_helper_spec.rb new file mode 100644 index 0000000000..846e65b54e --- /dev/null +++ b/spec/helpers/oauth_helper_spec.rb @@ -0,0 +1,17 @@ +require "spec_helper" + +describe OauthHelper do + describe "additional_providers" do + it 'returns appropriate values' do + [ + [[:twitter, :github], [:twitter, :github]], + [[:ldap_main], []], + [[:twitter, :ldap_main], [:twitter]], + [[], []], + ].each do |couple| + allow(helper).to receive(:enabled_oauth_providers) { couple.first } + additional_providers.should include(*couple.last) + end + end + end +end \ No newline at end of file From db2edff937cbc309c10bb1a987356a58f8a9c8fa Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 4 Dec 2014 15:07:01 +0200 Subject: [PATCH 05/13] Handle web hook exception Write to log if web hook cant be executed. This prevents 500 error when test web hook with invalid URL and prevent exceptions and retries in sidekiq Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects/hooks_controller.rb | 1 + app/models/hooks/web_hook.rb | 8 +++++++- app/services/test_hook_service.rb | 3 --- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index cab8fd76e6..2d6c311119 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -26,6 +26,7 @@ class Projects::HooksController < Projects::ApplicationController def test if !@project.empty_repo? status = TestHookService.new.execute(hook, current_user) + if status flash[:notice] = 'Hook successfully executed.' else diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 23fa01e0b7..8479d4aecf 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -32,7 +32,10 @@ class WebHook < ActiveRecord::Base def execute(data) parsed_url = URI.parse(url) if parsed_url.userinfo.blank? - WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" }, verify: false) + WebHook.post(url, + body: data.to_json, + headers: { "Content-Type" => "application/json" }, + verify: false) else post_url = url.gsub("#{parsed_url.userinfo}@", "") auth = { @@ -45,6 +48,9 @@ class WebHook < ActiveRecord::Base verify: false, basic_auth: auth) end + rescue SocketError, Errno::ECONNREFUSED => e + logger.error("WebHook Error => #{e}") + false end def async_execute(data) diff --git a/app/services/test_hook_service.rb b/app/services/test_hook_service.rb index b6b1ef29b5..17d86a7a27 100644 --- a/app/services/test_hook_service.rb +++ b/app/services/test_hook_service.rb @@ -2,8 +2,5 @@ class TestHookService def execute(hook, current_user) data = GitPushService.new.sample_data(hook.project, current_user) hook.execute(data) - true - rescue SocketError - false end end From f9a730ebb48ffe21c7b80ed4d188e47ec1baa497 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 4 Dec 2014 13:43:08 +0200 Subject: [PATCH 06/13] fix specs --- spec/helpers/oauth_helper_spec.rb | 23 ++++++++++++--------- spec/lib/gitlab/ldap/access_spec.rb | 2 +- spec/lib/gitlab/ldap/authentication_spec.rb | 2 +- spec/lib/gitlab/ldap/user_spec.rb | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/spec/helpers/oauth_helper_spec.rb b/spec/helpers/oauth_helper_spec.rb index 846e65b54e..453699136e 100644 --- a/spec/helpers/oauth_helper_spec.rb +++ b/spec/helpers/oauth_helper_spec.rb @@ -2,16 +2,19 @@ require "spec_helper" describe OauthHelper do describe "additional_providers" do - it 'returns appropriate values' do - [ - [[:twitter, :github], [:twitter, :github]], - [[:ldap_main], []], - [[:twitter, :ldap_main], [:twitter]], - [[], []], - ].each do |couple| - allow(helper).to receive(:enabled_oauth_providers) { couple.first } - additional_providers.should include(*couple.last) - end + it 'returns all enabled providers' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :github] } + helper.additional_providers.should include(*[:twitter, :github]) + end + + it 'does not return ldap provider' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :ldapmain] } + helper.additional_providers.should include(:twitter) + end + + it 'returns empty array' do + allow(helper).to receive(:enabled_oauth_providers) { [] } + helper.additional_providers.should == [] end end end \ No newline at end of file diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb index f4d5a92739..4573b8696c 100644 --- a/spec/lib/gitlab/ldap/access_spec.rb +++ b/spec/lib/gitlab/ldap/access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::LDAP::Access do let(:access) { Gitlab::LDAP::Access.new user } - let(:user) { create(:user, :ldap) } + let(:user) { create(:omniauth_user) } describe :allowed? do subject { access.allowed? } diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb index 0eb7c443b8..11fdf10875 100644 --- a/spec/lib/gitlab/ldap/authentication_spec.rb +++ b/spec/lib/gitlab/ldap/authentication_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::LDAP::Authentication do let(:klass) { Gitlab::LDAP::Authentication } - let(:user) { create(:user, :ldap, extern_uid: dn) } + let(:user) { create(:omniauth_user, extern_uid: dn) } let(:dn) { 'uid=john,ou=people,dc=example,dc=com' } let(:login) { 'john' } let(:password) { 'password' } diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 294ee6cbae..f73884e644 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::LDAP::User do end it "connects to existing non-ldap user if the email matches" do - existing_user = create(:omniauth_user, email: 'john@example.com') + existing_user = create(:omniauth_user, email: 'john@example.com', provider: "twitter") expect{ gl_user.save }.to_not change{ User.count } existing_user.reload From cdc62cffcb86dfd939c119cba2acaf266af39f23 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 4 Dec 2014 15:22:10 +0100 Subject: [PATCH 07/13] Add rake task for google schema whitelisting. --- app/mailers/notify.rb | 8 ++ doc/integration/gitlab_buttons_in_gmail.md | 17 +++++ .../mail_google_schema_whitelisting.rake | 73 +++++++++++++++++++ .../gitlab/mail_google_schema_whitelisting.rb | 27 +++++++ 4 files changed, 125 insertions(+) create mode 100644 lib/tasks/gitlab/mail_google_schema_whitelisting.rake create mode 100644 spec/tasks/gitlab/mail_google_schema_whitelisting.rb diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 0ee1983662..6d671e6e0b 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -26,6 +26,14 @@ class Notify < ActionMailer::Base delay_for(2.seconds) end + def test_email(recepient_email, subject, body) + mail(to: recepient_email, + subject: subject, + body: body.html_safe, + content_type: 'text/html' + ) + end + private # The default email address to send emails from diff --git a/doc/integration/gitlab_buttons_in_gmail.md b/doc/integration/gitlab_buttons_in_gmail.md index 5cfea5a90f..0816509c55 100644 --- a/doc/integration/gitlab_buttons_in_gmail.md +++ b/doc/integration/gitlab_buttons_in_gmail.md @@ -9,3 +9,20 @@ If correctly setup, emails that require an action will be marked in Gmail. To get this functioning, you need to be registered with Google. [See how to register with google in this document.](https://developers.google.com/gmail/markup/registering-with-google) +To aid the registering with google, GitLab offers a rake task that will send an email to google whitelisting email address from your GitLab server. + +To check what would be sent to the google email address, run the rake task: + +```bash +bundle exec rake gitlab:mail_google_schema_whitelisting RAILS_ENV=production +``` + +**This will not send the email but give you the output of how the mail will look.** + +Copy the output of the rake task to [google email markup tester](https://www.google.com/webmasters/markup-tester/u/0/) and press "Validate". + +If you receive "No errors detected" message from the tester you can send the email using: + +```bash +bundle exec rake gitlab:mail_google_schema_whitelisting RAILS_ENV=production SEND=true +`` diff --git a/lib/tasks/gitlab/mail_google_schema_whitelisting.rake b/lib/tasks/gitlab/mail_google_schema_whitelisting.rake new file mode 100644 index 0000000000..f40bba24da --- /dev/null +++ b/lib/tasks/gitlab/mail_google_schema_whitelisting.rake @@ -0,0 +1,73 @@ +require "#{Rails.root}/app/helpers/emails_helper" +require 'action_view/helpers' +extend ActionView::Helpers + +include ActionView::Context +include EmailsHelper + +namespace :gitlab do + desc "Email google whitelisting email with example email for actions in inbox" + task mail_google_schema_whitelisting: :environment do + subject = "Rails | Implemented feature" + url = "#{Gitlab.config.gitlab.url}/base/rails-project/issues/#{rand(1..100)}#note_#{rand(10..1000)}" + schema = email_action(url) + body = email_template(schema, url) + mail = Notify.test_email("schema.whitelisting+sample@gmail.com", subject, body.html_safe) + if send_now + mail.deliver + else + puts "WOULD SEND:" + end + puts mail + end + + def email_template(schema, url) + " + + + + GitLab + + + + + +
+
+

I like it :+1:

+
+
+ + + + " + end + + def send_now + if ENV['SEND'] == "true" + true + else + false + end + end +end diff --git a/spec/tasks/gitlab/mail_google_schema_whitelisting.rb b/spec/tasks/gitlab/mail_google_schema_whitelisting.rb new file mode 100644 index 0000000000..45aaf0fc90 --- /dev/null +++ b/spec/tasks/gitlab/mail_google_schema_whitelisting.rb @@ -0,0 +1,27 @@ +require 'spec_helper' +require 'rake' + +describe 'gitlab:mail_google_schema_whitelisting rake task' do + before :all do + Rake.application.rake_require "tasks/gitlab/task_helpers" + Rake.application.rake_require "tasks/gitlab/mail_google_schema_whitelisting" + # empty task as env is already loaded + Rake::Task.define_task :environment + end + + describe 'call' do + before do + # avoid writing task output to spec progress + $stdout.stub :write + end + + let :run_rake_task do + Rake::Task["gitlab:mail_google_schema_whitelisting"].reenable + Rake.application.invoke_task "gitlab:mail_google_schema_whitelisting" + end + + it 'should run the task without errors' do + expect { run_rake_task }.to_not raise_error + end + end +end From 704b7237e6c4daa3642c01f8803072fdc3a45eaf Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 4 Dec 2014 16:54:08 +0100 Subject: [PATCH 08/13] Fix notifications for developers that don't read the documentation. --- doc/development/rake_tasks.md | 5 ++++- lib/tasks/seed.rake | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 lib/tasks/seed.rake diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md index 6d9ac161e9..ffa61e6613 100644 --- a/doc/development/rake_tasks.md +++ b/doc/development/rake_tasks.md @@ -1,6 +1,6 @@ # Rake tasks for developers -## Setup db with developer seeds: +## Setup db with developer seeds Note that if your db user does not have advanced privileges you must create the db manually before running this command. @@ -8,6 +8,9 @@ Note that if your db user does not have advanced privileges you must create the bundle exec rake setup ``` +The `setup` task is a alias for `gitlab:setup`. +This tasks calls `db:setup` to create the database, with `add_limits_mysql` it adds limits to the database schema in case of a MySQL database and fianlly it runs `db:seed_fu` to seed the database. + ## Run tests This runs all test suites present in GitLab. diff --git a/lib/tasks/seed.rake b/lib/tasks/seed.rake new file mode 100644 index 0000000000..c54a1e694a --- /dev/null +++ b/lib/tasks/seed.rake @@ -0,0 +1,8 @@ +namespace :db do + namespace :seed do + desc "Seed is replaced with seed_fu" + task :dump => :environment do + raise "Please run db:seed_fu instead of db:seed." + end + end +end From 18164afbccf90074abf55e2bcdb91204b213ede1 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Nov 2014 19:06:21 +0100 Subject: [PATCH 09/13] Update Sidekiq to 2.17.8 --- CHANGELOG | 1 + Gemfile | 2 +- Gemfile.lock | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ae8de1df27..2c6808f46b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ v 7.6.0 - - - In the docker directory is a container template based on the Omnibus packages. + - Update Sidekiq to version 2.17.8 - - diff --git a/Gemfile b/Gemfile index 613ef11cf4..b4ca596927 100644 --- a/Gemfile +++ b/Gemfile @@ -112,7 +112,7 @@ gem "acts-as-taggable-on" # Background jobs gem 'slim' gem 'sinatra', require: nil -gem 'sidekiq', '2.17.0' +gem 'sidekiq', '2.17.8' # HTTP requests gem "httparty" diff --git a/Gemfile.lock b/Gemfile.lock index 7871f49d0b..4bcb1eb0de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,7 +78,7 @@ GEM coffee-script-source (1.6.3) colored (1.2) colorize (0.5.8) - connection_pool (1.2.0) + connection_pool (2.1.0) coveralls (0.7.0) multi_json (~> 1.3) rest-client @@ -402,7 +402,7 @@ GEM rdoc (3.12.2) json (~> 1.4) redcarpet (3.1.2) - redis (3.0.6) + redis (3.1.0) redis-actionpack (4.0.0) actionpack (~> 4) redis-rack (~> 1.5.0) @@ -410,8 +410,8 @@ GEM redis-activesupport (4.0.0) activesupport (~> 4) redis-store (~> 1.1.0) - redis-namespace (1.4.1) - redis (~> 3.0.4) + redis-namespace (1.5.1) + redis (~> 3.0, >= 3.0.4) redis-rack (1.5.0) rack (~> 1.5) redis-store (~> 1.1.0) @@ -470,12 +470,12 @@ GEM sexp_processor (4.4.0) shoulda-matchers (2.1.0) activesupport (>= 3.0.0) - sidekiq (2.17.0) - celluloid (>= 0.15.2) - connection_pool (>= 1.0.0) + sidekiq (2.17.8) + celluloid (= 0.15.2) + connection_pool (~> 2.0) json - redis (>= 3.0.4) - redis-namespace (>= 1.3.1) + redis (~> 3.1) + redis-namespace (~> 1.3) simple_oauth (0.1.9) simplecov (0.9.0) docile (~> 1.1.0) @@ -684,7 +684,7 @@ DEPENDENCIES semantic-ui-sass (~> 0.16.1.0) settingslogic shoulda-matchers (~> 2.1.0) - sidekiq (= 2.17.0) + sidekiq (= 2.17.8) simplecov sinatra six From 288df41c0a3b950f3474d9ae00c644d4780de321 Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 4 Dec 2014 18:14:54 +0100 Subject: [PATCH 10/13] Seed is not seed dump. --- lib/tasks/seed.rake | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/tasks/seed.rake b/lib/tasks/seed.rake index c54a1e694a..7c006c1663 100644 --- a/lib/tasks/seed.rake +++ b/lib/tasks/seed.rake @@ -1,8 +1,6 @@ namespace :db do - namespace :seed do - desc "Seed is replaced with seed_fu" - task :dump => :environment do - raise "Please run db:seed_fu instead of db:seed." - end + desc "Seed is replaced with seed_fu" + task :seed => :environment do + raise "Please run db:seed_fu instead of db:seed." end end From a46fe875c6aea206e575e2b083bd31ed36ee1b1e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 4 Dec 2014 21:49:19 +0200 Subject: [PATCH 11/13] Feature: atom feed for user activity Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 2 +- app/controllers/users_controller.rb | 7 ++++- app/views/users/show.atom.builder | 29 +++++++++++++++++++ app/views/users/show.html.haml | 10 ++++++- config/routes.rb | 3 +- spec/features/atom/users_spec.rb | 43 +++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 app/views/users/show.atom.builder create mode 100644 spec/features/atom/users_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 2c6808f46b..6c28a57370 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -20,7 +20,7 @@ v 7.6.0 - In the docker directory is a container template based on the Omnibus packages. - Update Sidekiq to version 2.17.8 - - - + - Atom feed for user activity v 7.5.2 - Don't log Sidekiq arguments by default diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 0b442f5383..67af1801bd 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -20,9 +20,14 @@ class UsersController < ApplicationController # Get user activity feed for projects common for both users @events = @user.recent_events. - where(project_id: authorized_projects_ids).limit(20) + where(project_id: authorized_projects_ids).limit(30) @title = @user.name + + respond_to do |format| + format.html + format.atom { render layout: false } + end end def determine_layout diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder new file mode 100644 index 0000000000..0d61a9e809 --- /dev/null +++ b/app/views/users/show.atom.builder @@ -0,0 +1,29 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do + xml.title "Activity feed for #{@user.name}" + xml.link :href => user_url(@user, :atom), :rel => "self", :type => "application/atom+xml" + xml.link :href => user_url(@user), :rel => "alternate", :type => "text/html" + xml.id projects_url + xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? + + @events.each do |event| + if event.proper? + xml.entry do + event_link = event_feed_url(event) + event_title = event_feed_title(event) + event_summary = event_feed_summary(event) + + xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" + xml.link :href => event_link + xml.title truncate(event_title, :length => 80) + xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email) + xml.author do |author| + xml.name event.author_name + xml.email event.author_email + end + xml.summary(:type => "xhtml") { |x| x << event_summary unless event_summary.nil? } + end + end + end +end diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index cb49c030af..54f2666ce5 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -18,7 +18,15 @@ %h4 Groups: = render 'groups', groups: @groups %hr - %h4 User Activity: + %h4 + User Activity: + + - if current_user + %span.rss-icon.pull-right + = link_to user_path(@user, :atom, { private_token: current_user.private_token }) do + %strong + %i.fa.fa-rss + = render @events .col-md-4 = render 'profile', user: @user diff --git a/config/routes.rb b/config/routes.rb index 723104daf1..f2984069b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -137,7 +137,8 @@ Gitlab::Application.routes.draw do end end - match "/u/:username" => "users#show", as: :user, constraints: { username: /.*/ }, via: :get + match "/u/:username" => "users#show", as: :user, + constraints: {username: /(?:[^.]|\.(?!atom$))+/, format: /atom/}, via: :get # # Dashboard Area diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb new file mode 100644 index 0000000000..746b6fc1ac --- /dev/null +++ b/spec/features/atom/users_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe "User Feed", feature: true do + describe "GET /" do + let!(:user) { create(:user) } + + context "user atom feed via private token" do + it "should render user atom feed" do + visit user_path(user, :atom, private_token: user.private_token) + body.should have_selector("feed title") + end + end + + context 'feed content' do + let(:project) { create(:project) } + let(:issue) { create(:issue, project: project, author: user, description: '') } + let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) } + + before do + project.team << [user, :master] + issue_event(issue, user) + note_event(note, user) + visit user_path(user, :atom, private_token: user.private_token) + end + + it "should have issue opened event" do + body.should have_content("#{user.name} opened issue ##{issue.iid}") + end + + it "should have issue comment event" do + body.should have_content("#{user.name} commented on issue ##{issue.iid}") + end + end + end + + def issue_event(issue, user) + EventCreateService.new.open_issue(issue, user) + end + + def note_event(note, user) + EventCreateService.new.leave_note(note, user) + end +end From d31d711a70779132ea43387f93eb4ccc1e472761 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 4 Dec 2014 22:14:20 +0200 Subject: [PATCH 12/13] DRY and refactor atom code Signed-off-by: Dmitriy Zaporozhets --- app/helpers/events_helper.rb | 22 +++++++++++++++++ app/helpers/issues_helper.rb | 15 ++++++++++++ app/views/dashboard/issues.atom.builder | 21 ++++------------ app/views/dashboard/show.atom.builder | 25 ++++---------------- app/views/groups/issues.atom.builder | 13 +--------- app/views/groups/show.atom.builder | 24 ++++--------------- app/views/projects/issues/index.atom.builder | 13 +--------- app/views/users/show.atom.builder | 25 ++++---------------- 8 files changed, 56 insertions(+), 102 deletions(-) diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 71f97fbb8c..a3136926b3 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -145,4 +145,26 @@ module EventsHelper rescue "--broken encoding" end + + def event_to_atom(xml, event) + if event.proper? + xml.entry do + event_link = event_feed_url(event) + event_title = event_feed_title(event) + event_summary = event_feed_summary(event) + + xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" + xml.link href: event_link + xml.title truncate(event_title, length: 80) + xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(event.author_email) + xml.author do |author| + xml.name event.author_name + xml.email event.author_email + end + + xml.summary(type: "xhtml") { |x| x << event_summary unless event_summary.nil? } + end + end + end end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index d513e0ba58..a5b393c1e3 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -113,4 +113,19 @@ module IssuesHelper 'issue-box-open' end end + + def issue_to_atom(xml, issue) + xml.entry do + xml.id project_issue_url(issue.project, issue) + xml.link href: project_issue_url(issue.project, issue) + xml.title truncate(issue.title, length: 80) + xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(issue.author_email) + xml.author do |author| + xml.name issue.author_name + xml.email issue.author_email + end + xml.summary issue.title + end + end end diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder index f541355778..6638131022 100644 --- a/app/views/dashboard/issues.atom.builder +++ b/app/views/dashboard/issues.atom.builder @@ -1,24 +1,13 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do xml.title "#{current_user.name} issues" - xml.link :href => issues_dashboard_url(:atom, :private_token => current_user.private_token), :rel => "self", :type => "application/atom+xml" - xml.link :href => issues_dashboard_url(:private_token => current_user.private_token), :rel => "alternate", :type => "text/html" - xml.id issues_dashboard_url(:private_token => current_user.private_token) + xml.link href: issues_dashboard_url(:atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml" + xml.link href: issues_dashboard_url(private_token: current_user.private_token), rel: "alternate", type: "text/html" + xml.id issues_dashboard_url(private_token: current_user.private_token) xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? @issues.each do |issue| - xml.entry do - xml.id project_issue_url(issue.project, issue) - xml.link :href => project_issue_url(issue.project, issue) - xml.title truncate(issue.title, :length => 80) - xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email) - xml.author do |author| - xml.name issue.author_name - xml.email issue.author_email - end - xml.summary issue.title - end + issue_to_atom(xml, issue) end end diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/show.atom.builder index f4cf24ccd9..70ac66f801 100644 --- a/app/views/dashboard/show.atom.builder +++ b/app/views/dashboard/show.atom.builder @@ -1,29 +1,12 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do xml.title "Dashboard feed#{" - #{current_user.name}" if current_user.name.present?}" - xml.link :href => dashboard_url(:atom), :rel => "self", :type => "application/atom+xml" - xml.link :href => dashboard_url, :rel => "alternate", :type => "text/html" + xml.link href: dashboard_url(:atom), rel: "self", type: "application/atom+xml" + xml.link href: dashboard_url, rel: "alternate", type: "text/html" xml.id projects_url xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| - if event.proper? - xml.entry do - event_link = event_feed_url(event) - event_title = event_feed_title(event) - event_summary = event_feed_summary(event) - - xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link :href => event_link - xml.title truncate(event_title, :length => 80) - xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email) - xml.author do |author| - xml.name event.author_name - xml.email event.author_email - end - xml.summary(:type => "xhtml") { |x| x << event_summary unless event_summary.nil? } - end - end + event_to_atom(xml, event) end end diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder index f2005193f8..240001967f 100644 --- a/app/views/groups/issues.atom.builder +++ b/app/views/groups/issues.atom.builder @@ -7,18 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? @issues.each do |issue| - xml.entry do - xml.id project_issue_url(issue.project, issue) - xml.link :href => project_issue_url(issue.project, issue) - xml.title truncate(issue.title, :length => 80) - xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email) - xml.author do |author| - xml.name issue.author_name - xml.email issue.author_email - end - xml.summary issue.title - end + issue_to_atom(xml, issue) end end diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder index e07bb7d2fb..e765ea8338 100644 --- a/app/views/groups/show.atom.builder +++ b/app/views/groups/show.atom.builder @@ -1,28 +1,12 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do xml.title "Group feed - #{@group.name}" - xml.link :href => group_path(@group, :atom), :rel => "self", :type => "application/atom+xml" - xml.link :href => group_path(@group), :rel => "alternate", :type => "text/html" + xml.link href: group_path(@group, :atom), rel: "self", type: "application/atom+xml" + xml.link href: group_path(@group), rel: "alternate", type: "text/html" xml.id projects_url xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| - if event.proper? - xml.entry do - event_link = event_feed_url(event) - event_title = event_feed_title(event) - - xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link :href => event_link - xml.title truncate(event_title, :length => 80) - xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email) - xml.author do |author| - xml.name event.author_name - xml.email event.author_email - end - xml.summary event_title - end - end + event_to_atom(xml, event) end end diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder index 012ba23595..61e651da93 100644 --- a/app/views/projects/issues/index.atom.builder +++ b/app/views/projects/issues/index.atom.builder @@ -7,17 +7,6 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? @issues.each do |issue| - xml.entry do - xml.id project_issue_url(@project, issue) - xml.link :href => project_issue_url(@project, issue) - xml.title truncate(issue.title, :length => 80) - xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(issue.author_email) - xml.author do |author| - xml.name issue.author_name - xml.email issue.author_email - end - xml.summary issue.title - end + issue_to_atom(xml, issue) end end diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder index 0d61a9e809..b7216a8876 100644 --- a/app/views/users/show.atom.builder +++ b/app/views/users/show.atom.builder @@ -1,29 +1,12 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do xml.title "Activity feed for #{@user.name}" - xml.link :href => user_url(@user, :atom), :rel => "self", :type => "application/atom+xml" - xml.link :href => user_url(@user), :rel => "alternate", :type => "text/html" + xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml" + xml.link href: user_url(@user), rel: "alternate", type: "text/html" xml.id projects_url xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| - if event.proper? - xml.entry do - event_link = event_feed_url(event) - event_title = event_feed_title(event) - event_summary = event_feed_summary(event) - - xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link :href => event_link - xml.title truncate(event_title, :length => 80) - xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(event.author_email) - xml.author do |author| - xml.name event.author_name - xml.email event.author_email - end - xml.summary(:type => "xhtml") { |x| x << event_summary unless event_summary.nil? } - end - end + event_to_atom(xml, event) end end From 3dc25ba331c4f5c4708b0fcd8478d943d182d760 Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 4 Dec 2014 21:22:21 +0100 Subject: [PATCH 13/13] Remove warning from db seed since it is called by db setup. --- doc/development/rake_tasks.md | 3 ++- lib/tasks/seed.rake | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 lib/tasks/seed.rake diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md index ffa61e6613..53f8095cb1 100644 --- a/doc/development/rake_tasks.md +++ b/doc/development/rake_tasks.md @@ -9,7 +9,8 @@ bundle exec rake setup ``` The `setup` task is a alias for `gitlab:setup`. -This tasks calls `db:setup` to create the database, with `add_limits_mysql` it adds limits to the database schema in case of a MySQL database and fianlly it runs `db:seed_fu` to seed the database. +This tasks calls `db:setup` to create the database, calls `add_limits_mysql` that adds limits to the database schema in case of a MySQL database and fianlly it calls `db:seed_fu` to seed the database. +Note: `db:setup` calls `db:seed` but this does nothing. ## Run tests diff --git a/lib/tasks/seed.rake b/lib/tasks/seed.rake deleted file mode 100644 index 7c006c1663..0000000000 --- a/lib/tasks/seed.rake +++ /dev/null @@ -1,6 +0,0 @@ -namespace :db do - desc "Seed is replaced with seed_fu" - task :seed => :environment do - raise "Please run db:seed_fu instead of db:seed." - end -end