Commit 54d32f56 authored by Sytse Sijbrandij's avatar Sytse Sijbrandij

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq

parents 3a3471cc 69e8b0e9
...@@ -18,8 +18,9 @@ v 7.6.0 ...@@ -18,8 +18,9 @@ v 7.6.0
- -
- -
- In the docker directory is a container template based on the Omnibus packages. - 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 v 7.5.2
- Don't log Sidekiq arguments by default - Don't log Sidekiq arguments by default
......
...@@ -112,7 +112,7 @@ gem "acts-as-taggable-on" ...@@ -112,7 +112,7 @@ gem "acts-as-taggable-on"
# Background jobs # Background jobs
gem 'slim' gem 'slim'
gem 'sinatra', require: nil gem 'sinatra', require: nil
gem 'sidekiq', '2.17.0' gem 'sidekiq', '2.17.8'
# HTTP requests # HTTP requests
gem "httparty" gem "httparty"
......
...@@ -78,7 +78,7 @@ GEM ...@@ -78,7 +78,7 @@ GEM
coffee-script-source (1.6.3) coffee-script-source (1.6.3)
colored (1.2) colored (1.2)
colorize (0.5.8) colorize (0.5.8)
connection_pool (1.2.0) connection_pool (2.1.0)
coveralls (0.7.0) coveralls (0.7.0)
multi_json (~> 1.3) multi_json (~> 1.3)
rest-client rest-client
...@@ -402,7 +402,7 @@ GEM ...@@ -402,7 +402,7 @@ GEM
rdoc (3.12.2) rdoc (3.12.2)
json (~> 1.4) json (~> 1.4)
redcarpet (3.1.2) redcarpet (3.1.2)
redis (3.0.6) redis (3.1.0)
redis-actionpack (4.0.0) redis-actionpack (4.0.0)
actionpack (~> 4) actionpack (~> 4)
redis-rack (~> 1.5.0) redis-rack (~> 1.5.0)
...@@ -410,8 +410,8 @@ GEM ...@@ -410,8 +410,8 @@ GEM
redis-activesupport (4.0.0) redis-activesupport (4.0.0)
activesupport (~> 4) activesupport (~> 4)
redis-store (~> 1.1.0) redis-store (~> 1.1.0)
redis-namespace (1.4.1) redis-namespace (1.5.1)
redis (~> 3.0.4) redis (~> 3.0, >= 3.0.4)
redis-rack (1.5.0) redis-rack (1.5.0)
rack (~> 1.5) rack (~> 1.5)
redis-store (~> 1.1.0) redis-store (~> 1.1.0)
...@@ -470,12 +470,12 @@ GEM ...@@ -470,12 +470,12 @@ GEM
sexp_processor (4.4.0) sexp_processor (4.4.0)
shoulda-matchers (2.1.0) shoulda-matchers (2.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (2.17.0) sidekiq (2.17.8)
celluloid (>= 0.15.2) celluloid (= 0.15.2)
connection_pool (>= 1.0.0) connection_pool (~> 2.0)
json json
redis (>= 3.0.4) redis (~> 3.1)
redis-namespace (>= 1.3.1) redis-namespace (~> 1.3)
simple_oauth (0.1.9) simple_oauth (0.1.9)
simplecov (0.9.0) simplecov (0.9.0)
docile (~> 1.1.0) docile (~> 1.1.0)
...@@ -684,7 +684,7 @@ DEPENDENCIES ...@@ -684,7 +684,7 @@ DEPENDENCIES
semantic-ui-sass (~> 0.16.1.0) semantic-ui-sass (~> 0.16.1.0)
settingslogic settingslogic
shoulda-matchers (~> 2.1.0) shoulda-matchers (~> 2.1.0)
sidekiq (= 2.17.0) sidekiq (= 2.17.8)
simplecov simplecov
sinatra sinatra
six six
......
...@@ -42,10 +42,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -42,10 +42,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def handle_omniauth def handle_omniauth
if current_user if current_user
# Change a logged-in user's authentication method: # Add new authentication method
current_user.extern_uid = oauth['uid'] current_user.identities.find_or_create_by(extern_uid: oauth['uid'], provider: oauth['provider'])
current_user.provider = oauth['provider']
current_user.save
redirect_to profile_path redirect_to profile_path
else else
@user = Gitlab::OAuth::User.new(oauth) @user = Gitlab::OAuth::User.new(oauth)
...@@ -67,8 +65,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -67,8 +65,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return
end end
end end
rescue StandardError rescue ForbiddenAction => e
flash[:notice] = "There's no such user!" flash[:notice] = e.message
redirect_to new_user_session_path redirect_to new_user_session_path
end end
......
...@@ -26,6 +26,7 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -26,6 +26,7 @@ class Projects::HooksController < Projects::ApplicationController
def test def test
if !@project.empty_repo? if !@project.empty_repo?
status = TestHookService.new.execute(hook, current_user) status = TestHookService.new.execute(hook, current_user)
if status if status
flash[:notice] = 'Hook successfully executed.' flash[:notice] = 'Hook successfully executed.'
else else
......
...@@ -20,9 +20,14 @@ class UsersController < ApplicationController ...@@ -20,9 +20,14 @@ class UsersController < ApplicationController
# Get user activity feed for projects common for both users # Get user activity feed for projects common for both users
@events = @user.recent_events. @events = @user.recent_events.
where(project_id: authorized_projects_ids).limit(20) where(project_id: authorized_projects_ids).limit(30)
@title = @user.name @title = @user.name
respond_to do |format|
format.html
format.atom { render layout: false }
end
end end
def determine_layout def determine_layout
......
...@@ -145,4 +145,26 @@ module EventsHelper ...@@ -145,4 +145,26 @@ module EventsHelper
rescue rescue
"--broken encoding" "--broken encoding"
end 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 end
...@@ -113,4 +113,19 @@ module IssuesHelper ...@@ -113,4 +113,19 @@ module IssuesHelper
'issue-box-open' 'issue-box-open'
end end
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 end
...@@ -16,4 +16,8 @@ module OauthHelper ...@@ -16,4 +16,8 @@ module OauthHelper
[:twitter, :github, :google_oauth2].include?(name.to_sym) [:twitter, :github, :google_oauth2].include?(name.to_sym)
end end
end end
def additional_providers
enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')}
end
end end
module ProfileHelper module ProfileHelper
def oauth_active_class(provider) def oauth_active_class(provider)
if current_user.provider == provider.to_s if current_user.identities.exists?(provider: provider.to_s)
'active' 'active'
end end
end end
...@@ -10,10 +10,10 @@ module ProfileHelper ...@@ -10,10 +10,10 @@ module ProfileHelper
end end
def show_profile_social_tab? def show_profile_social_tab?
enabled_social_providers.any? && !current_user.ldap_user? enabled_social_providers.any?
end end
def show_profile_remove_tab? def show_profile_remove_tab?
gitlab_config.signup_enabled && !current_user.ldap_user? gitlab_config.signup_enabled
end end
end end
...@@ -26,6 +26,14 @@ class Notify < ActionMailer::Base ...@@ -26,6 +26,14 @@ class Notify < ActionMailer::Base
delay_for(2.seconds) delay_for(2.seconds)
end end
def test_email(recepient_email, subject, body)
mail(to: recepient_email,
subject: subject,
body: body.html_safe,
content_type: 'text/html'
)
end
private private
# The default email address to send emails from # The default email address to send emails from
......
...@@ -32,7 +32,10 @@ class WebHook < ActiveRecord::Base ...@@ -32,7 +32,10 @@ class WebHook < ActiveRecord::Base
def execute(data) def execute(data)
parsed_url = URI.parse(url) parsed_url = URI.parse(url)
if parsed_url.userinfo.blank? 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 else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = { auth = {
...@@ -45,6 +48,9 @@ class WebHook < ActiveRecord::Base ...@@ -45,6 +48,9 @@ class WebHook < ActiveRecord::Base
verify: false, verify: false,
basic_auth: auth) basic_auth: auth)
end end
rescue SocketError, Errno::ECONNREFUSED => e
logger.error("WebHook Error => #{e}")
false
end end
def async_execute(data) def async_execute(data)
......
class Identity < ActiveRecord::Base
belongs_to :user
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
end
\ No newline at end of file
...@@ -79,6 +79,7 @@ class User < ActiveRecord::Base ...@@ -79,6 +79,7 @@ class User < ActiveRecord::Base
# Profile # Profile
has_many :keys, dependent: :destroy has_many :keys, dependent: :destroy
has_many :emails, dependent: :destroy has_many :emails, dependent: :destroy
has_many :identities, dependent: :destroy
# Groups # Groups
has_many :members, dependent: :destroy has_many :members, dependent: :destroy
...@@ -113,7 +114,6 @@ class User < ActiveRecord::Base ...@@ -113,7 +114,6 @@ class User < ActiveRecord::Base
validates :name, presence: true validates :name, presence: true
validates :email, presence: true, email: {strict_mode: true}, uniqueness: true validates :email, presence: true, email: {strict_mode: true}, uniqueness: true
validates :bio, length: { maximum: 255 }, allow_blank: 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 :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
validates :username, presence: true, uniqueness: { case_sensitive: false }, validates :username, presence: true, uniqueness: { case_sensitive: false },
exclusion: { in: Gitlab::Blacklist.path }, exclusion: { in: Gitlab::Blacklist.path },
...@@ -178,7 +178,6 @@ class User < ActiveRecord::Base ...@@ -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_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 :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 :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 } scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
# #
...@@ -407,7 +406,11 @@ class User < ActiveRecord::Base ...@@ -407,7 +406,11 @@ class User < ActiveRecord::Base
end end
def ldap_user? 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 end
def accessible_deploy_keys def accessible_deploy_keys
......
...@@ -107,7 +107,7 @@ class NotificationService ...@@ -107,7 +107,7 @@ class NotificationService
# Notify new user with email after creation # Notify new user with email after creation
def new_user(user, token = nil) def new_user(user, token = nil)
# Don't email omniauth created users # 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 end
# Notify users on new note in system # Notify users on new note in system
......
...@@ -2,8 +2,5 @@ class TestHookService ...@@ -2,8 +2,5 @@ class TestHookService
def execute(hook, current_user) def execute(hook, current_user)
data = GitPushService.new.sample_data(hook.project, current_user) data = GitPushService.new.sample_data(hook.project, current_user)
hook.execute(data) hook.execute(data)
true
rescue SocketError
false
end end
end end
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
%li %li
%span.light LDAP uid: %span.light LDAP uid:
%strong %strong
= @user.extern_uid = @user.ldap_identity.extern_uid
- if @user.created_by - if @user.created_by
%li %li
......
xml.instruct! 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.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(: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.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.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? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|
xml.entry do issue_to_atom(xml, issue)
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
end end
xml.instruct! 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.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(:atom), rel: "self", type: "application/atom+xml"
xml.link :href => dashboard_url, :rel => "alternate", :type => "text/html" xml.link href: dashboard_url, rel: "alternate", type: "text/html"
xml.id projects_url xml.id projects_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
if event.proper? event_to_atom(xml, event)
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
end end
- providers = (enabled_oauth_providers - [:ldap]) - providers = additional_providers
- if providers.present? - if providers.present?
.bs-callout.bs-callout-info{:'data-no-turbolink' => 'data-no-turbolink'} .bs-callout.bs-callout-info{:'data-no-turbolink' => 'data-no-turbolink'}
%span Sign in with: &nbsp; %span Sign in with: &nbsp;
......
...@@ -7,18 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -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? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|
xml.entry do issue_to_atom(xml, issue)
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
end end
xml.instruct! 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.title "Group feed - #{@group.name}"
xml.link :href => group_path(@group, :atom), :rel => "self", :type => "application/atom+xml" 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), rel: "alternate", type: "text/html"
xml.id projects_url xml.id projects_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event| @events.each do |event|
if event.proper? event_to_atom(xml, event)
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
end end
end end
...@@ -7,17 +7,6 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -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? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|
xml.entry do issue_to_atom(xml, issue)
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
end end
end end
xml.instruct!
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.id projects_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event|
event_to_atom(xml, event)
end
end
...@@ -18,7 +18,15 @@ ...@@ -18,7 +18,15 @@
%h4 Groups: %h4 Groups:
= render 'groups', groups: @groups = render 'groups', groups: @groups
%hr %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 = render @events
.col-md-4 .col-md-4
= render 'profile', user: @user = render 'profile', user: @user
......
...@@ -137,7 +137,8 @@ Gitlab::Application.routes.draw do ...@@ -137,7 +137,8 @@ Gitlab::Application.routes.draw do
end end
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 # Dashboard Area
......
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
remove_column :users, :extern_uid
remove_column :users, :provider
end
def down
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
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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 # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -74,6 +74,14 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -74,6 +74,14 @@ 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 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 "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| create_table "issues", force: true do |t|
t.string "title" t.string "title"
t.integer "assignee_id" t.integer "assignee_id"
...@@ -350,8 +358,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -350,8 +358,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.string "bio" t.string "bio"
t.integer "failed_attempts", default: 0 t.integer "failed_attempts", default: 0
t.datetime "locked_at" t.datetime "locked_at"
t.string "extern_uid"
t.string "provider"
t.string "username" t.string "username"
t.boolean "can_create_group", default: true, null: false t.boolean "can_create_group", default: true, null: false
t.boolean "can_create_team", default: true, null: false t.boolean "can_create_team", default: true, null: false
...@@ -360,6 +366,7 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -360,6 +366,7 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.integer "notification_level", default: 1, null: false t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at" t.datetime "password_expires_at"
t.integer "created_by_id" t.integer "created_by_id"
t.datetime "last_credential_check_at"
t.string "avatar" t.string "avatar"
t.string "confirmation_token" t.string "confirmation_token"
t.datetime "confirmed_at" t.datetime "confirmed_at"
...@@ -367,7 +374,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -367,7 +374,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.string "unconfirmed_email" t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false t.string "website_url", default: "", null: false
t.datetime "last_credential_check_at"
end end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
...@@ -375,7 +381,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -375,7 +381,6 @@ ActiveRecord::Schema.define(version: 20141121133009) do
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree 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", ["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", ["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", ["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", ["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 add_index "users", ["username"], name: "index_users_on_username", using: :btree
......
# Rake tasks for developers # 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. Note that if your db user does not have advanced privileges you must create the db manually before running this command.
...@@ -8,6 +8,10 @@ Note that if your db user does not have advanced privileges you must create the ...@@ -8,6 +8,10 @@ Note that if your db user does not have advanced privileges you must create the
bundle exec rake setup bundle exec rake setup
``` ```
The `setup` task is a alias for `gitlab:setup`.
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 ## Run tests
This runs all test suites present in GitLab. This runs all test suites present in GitLab.
......
...@@ -50,12 +50,12 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab ...@@ -50,12 +50,12 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab
### Memory ### Memory
- 512MB is the absolute minimum but we do not recommend this amount of memory. - 512MB is the absolute minimum but we strongly **advise against** this amount of memory.
You will need to configure minimum 1.5GB of swap space. You will need to configure a minimum of 1.5GB of swap space to make the Omnibus package reconfigure run succeed.
With 1.5GB of swap space you must configure only one unicorn worker. 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). 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. 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 as installation on CentOS could be unsuccessful with this amount of memory. 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 - 1GB RAM + 1GB swap supports up to 100 users
- **2GB RAM** is the **recommended** memory size and supports up to 500 users - **2GB RAM** is the **recommended** memory size and supports up to 500 users
- 4GB RAM supports up to 2,000 users - 4GB RAM supports up to 2,000 users
......
...@@ -9,3 +9,20 @@ If correctly setup, emails that require an action will be marked in Gmail. ...@@ -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. 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) [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
``
...@@ -170,7 +170,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps ...@@ -170,7 +170,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
end end
step "I am not an ldap user" do 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 current_user.ldap_user?.should be_false
end end
......
...@@ -14,10 +14,14 @@ module API ...@@ -14,10 +14,14 @@ module API
expose :bio, :skype, :linkedin, :twitter, :website_url expose :bio, :skype, :linkedin, :twitter, :website_url
end end
class Identity < Grape::Entity
expose :provider, :extern_uid
end
class UserFull < User class UserFull < User
expose :email expose :email
expose :theme_id, :color_scheme_id, :extern_uid, :provider, \ expose :theme_id, :color_scheme_id, :projects_limit
:projects_limit expose :identities, using: Entities::Identity
expose :can_create_group?, as: :can_create_group expose :can_create_group?, as: :can_create_group
expose :can_create_project?, as: :can_create_project expose :can_create_project?, as: :can_create_project
end end
......
...@@ -59,10 +59,16 @@ module API ...@@ -59,10 +59,16 @@ module API
post do post do
authenticated_as_admin! authenticated_as_admin!
required_attributes! [:email, :password, :name, :username] 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) user = User.build_user(attrs)
admin = attrs.delete(:admin) admin = attrs.delete(:admin)
user.admin = admin unless admin.nil? 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 if user.save
present user, with: Entities::UserFull present user, with: Entities::UserFull
else else
...@@ -89,8 +95,6 @@ module API ...@@ -89,8 +95,6 @@ module API
# twitter - Twitter account # twitter - Twitter account
# website_url - Website url # website_url - Website url
# projects_limit - Limit projects each user can create # projects_limit - Limit projects each user can create
# extern_uid - External authentication provider UID
# provider - External provider
# bio - Bio # bio - Bio
# admin - User is admin - true or false (default) # admin - User is admin - true or false (default)
# can_create_group - User can create groups - true or false # can_create_group - User can create groups - true or false
...@@ -99,7 +103,7 @@ module API ...@@ -99,7 +103,7 @@ module API
put ":id" do put ":id" do
authenticated_as_admin! 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]) user = User.find(params[:id])
not_found!('User') unless user not_found!('User') unless user
......
...@@ -8,7 +8,7 @@ module Gitlab ...@@ -8,7 +8,7 @@ module Gitlab
attr_reader :adapter, :provider, :user attr_reader :adapter, :provider, :user
def self.open(user, &block) 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)) block.call(self.new(user, adapter))
end end
end end
...@@ -28,13 +28,13 @@ module Gitlab ...@@ -28,13 +28,13 @@ module Gitlab
def initialize(user, adapter=nil) def initialize(user, adapter=nil)
@adapter = adapter @adapter = adapter
@user = user @user = user
@provider = user.provider @provider = user.ldap_identity.provider
end end
def allowed? 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 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 else
false false
end end
......
...@@ -12,9 +12,10 @@ module Gitlab ...@@ -12,9 +12,10 @@ module Gitlab
class << self class << self
def find_by_uid_and_provider(uid, provider) def find_by_uid_and_provider(uid, provider)
# LDAP distinguished name is case-insensitive # LDAP distinguished name is case-insensitive
::User. identity = ::Identity.
where(provider: [provider, :ldap]). where(provider: [provider, :ldap]).
where('lower(extern_uid) = ?', uid.downcase).last where('lower(extern_uid) = ?', uid.downcase).last
identity && identity.user
end end
end end
...@@ -34,15 +35,13 @@ module Gitlab ...@@ -34,15 +35,13 @@ module Gitlab
end end
def find_by_email def find_by_email
model.find_by(email: auth_hash.email) ::User.find_by(email: auth_hash.email)
end end
def update_user_attributes def update_user_attributes
gl_user.attributes = { gl_user.email = auth_hash.email
extern_uid: auth_hash.uid, gl_user.identities.build(provider: auth_hash.provider, extern_uid: auth_hash.uid)
provider: auth_hash.provider, gl_user
email: auth_hash.email
}
end end
def changed? def changed?
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
# #
module Gitlab module Gitlab
module OAuth module OAuth
class ForbiddenAction < StandardError; end
class User class User
attr_accessor :auth_hash, :gl_user attr_accessor :auth_hash, :gl_user
...@@ -70,24 +72,24 @@ module Gitlab ...@@ -70,24 +72,24 @@ module Gitlab
end end
def find_by_uid_and_provider 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 end
def build_new_user def build_new_user
model.new(user_attributes).tap do |user| user = ::User.new(user_attributes)
user.skip_confirmation! user.skip_confirmation!
end user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider)
user
end end
def user_attributes def user_attributes
{ {
extern_uid: auth_hash.uid,
provider: auth_hash.provider,
name: auth_hash.name, name: auth_hash.name,
username: auth_hash.username, username: auth_hash.username,
email: auth_hash.email, email: auth_hash.email,
password: auth_hash.password, password: auth_hash.password,
password_confirmation: auth_hash.password, password_confirmation: auth_hash.password
} }
end end
...@@ -95,12 +97,8 @@ module Gitlab ...@@ -95,12 +97,8 @@ module Gitlab
Gitlab::AppLogger Gitlab::AppLogger
end end
def model def unauthorized_to_create
::User raise ForbiddenAction.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}")
end
def raise_unauthorized_to_create
raise StandardError.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}")
end end
end end
end end
......
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)
"<html lang='en'>
<head>
<meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
<title>
GitLab
</title>
</meta>
</head>
<style>
img {
max-width: 100%;
height: auto;
}
p.details {
font-style:italic;
color:#777
}
.footer p {
font-size:small;
color:#777
}
</style>
<body>
<div class='content'>
<div>
<p>I like it :+1: </p>
</div>
</div>
<div class='footer' style='margin-top: 10px;'>
<p>
<br>
You're receiving this notification because you are a member of the Base / Rails Project project team.
<a href=\"#{url}\">View it on GitLab</a>
#{schema}
</p>
</div>
</body>
</html>"
end
def send_now
if ENV['SEND'] == "true"
true
else
false
end
end
end
...@@ -18,15 +18,24 @@ FactoryGirl.define do ...@@ -18,15 +18,24 @@ FactoryGirl.define do
password "12345678" password "12345678"
password_confirmation { password } password_confirmation { password }
confirmed_at { Time.now } confirmed_at { Time.now }
confirmation_token { nil } confirmation_token { nil }
trait :admin do trait :admin do
admin true admin true
end end
trait :ldap do factory :omniauth_user do
provider 'ldapmain' ignore do
extern_uid 'my-ldap-id' 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 end
factory :admin, traits: [:admin] factory :admin, traits: [:admin]
...@@ -182,4 +191,9 @@ FactoryGirl.define do ...@@ -182,4 +191,9 @@ FactoryGirl.define do
deploy_key deploy_key
project project
end end
factory :identity do
provider 'ldapmain'
extern_uid 'my-ldap-id'
end
end end
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
require "spec_helper"
describe OauthHelper do
describe "additional_providers" do
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
...@@ -2,7 +2,7 @@ require 'spec_helper' ...@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::LDAP::Access do describe Gitlab::LDAP::Access do
let(:access) { Gitlab::LDAP::Access.new user } let(:access) { Gitlab::LDAP::Access.new user }
let(:user) { create(:user, :ldap) } let(:user) { create(:omniauth_user) }
describe :allowed? do describe :allowed? do
subject { access.allowed? } subject { access.allowed? }
......
...@@ -2,7 +2,7 @@ require 'spec_helper' ...@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::LDAP::Authentication do describe Gitlab::LDAP::Authentication do
let(:klass) { Gitlab::LDAP::Authentication } 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(:dn) { 'uid=john,ou=people,dc=example,dc=com' }
let(:login) { 'john' } let(:login) { 'john' }
let(:password) { 'password' } let(:password) { 'password' }
......
...@@ -15,18 +15,18 @@ describe Gitlab::LDAP::User do ...@@ -15,18 +15,18 @@ describe Gitlab::LDAP::User do
describe :find_or_create do describe :find_or_create do
it "finds the user if already existing" 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 } expect{ gl_user.save }.to_not change{ User.count }
end end
it "connects to existing non-ldap user if the email matches" do 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', provider: "twitter")
expect{ gl_user.save }.to_not change{ User.count } expect{ gl_user.save }.to_not change{ User.count }
existing_user.reload existing_user.reload
expect(existing_user.extern_uid).to eql 'my-uid' expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
expect(existing_user.provider).to eql 'ldapmain' expect(existing_user.ldap_identity.provider).to eql 'ldapmain'
end end
it "creates a new user if not found" do it "creates a new user if not found" do
......
...@@ -15,7 +15,7 @@ describe Gitlab::OAuth::User do ...@@ -15,7 +15,7 @@ describe Gitlab::OAuth::User do
end end
describe :persisted? do 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 it "finds an existing user based on uid and provider (facebook)" do
auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider') auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider')
...@@ -39,8 +39,9 @@ describe Gitlab::OAuth::User do ...@@ -39,8 +39,9 @@ describe Gitlab::OAuth::User do
oauth_user.save oauth_user.save
expect(gl_user).to be_valid expect(gl_user).to be_valid
expect(gl_user.extern_uid).to eql uid identity = gl_user.identities.first
expect(gl_user.provider).to eql 'twitter' expect(identity.extern_uid).to eql uid
expect(identity.provider).to eql 'twitter'
end end
end end
......
...@@ -62,6 +62,7 @@ describe User do ...@@ -62,6 +62,7 @@ describe User do
it { should have_many(:assigned_issues).dependent(:destroy) } it { should have_many(:assigned_issues).dependent(:destroy) }
it { should have_many(:merge_requests).dependent(:destroy) } it { should have_many(:merge_requests).dependent(:destroy) }
it { should have_many(:assigned_merge_requests).dependent(:destroy) } it { should have_many(:assigned_merge_requests).dependent(:destroy) }
it { should have_many(:identities).dependent(:destroy) }
end end
describe "Mass assignment" do describe "Mass assignment" do
...@@ -361,24 +362,29 @@ describe User do ...@@ -361,24 +362,29 @@ describe User do
end end
describe :ldap_user? do describe :ldap_user? do
let(:user) { build(:user, :ldap) }
it "is true if provider name starts with ldap" do 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 expect( user.ldap_user? ).to be_true
end end
it "is false for other providers" do 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 expect( user.ldap_user? ).to be_false
end end
it "is false if no extern_uid is provided" do 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 expect( user.ldap_user? ).to be_false
end end
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 describe '#full_website_url' do
let(:user) { create(:user) } let(:user) { create(:user) }
......
...@@ -33,7 +33,7 @@ describe API::API, api: true do ...@@ -33,7 +33,7 @@ describe API::API, api: true do
response.status.should == 200 response.status.should == 200
json_response.should be_an Array json_response.should be_an Array
json_response.first.keys.should include 'email' 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' json_response.first.keys.should include 'can_create_project'
end end
end end
......
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment