diff --git a/CHANGELOG b/CHANGELOG
index afb06aa259e65c3e991ae215316bed4f2ca1dc29..2d05a51e77d8df5559a6c323e866e3124e5244e2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,7 +18,7 @@ v 4.1.0
   - added new classes Team, Repository
   - Reduce amount of gitolite calls
   - Ability to add user in all group projects
-  - remove derecated configs
+  - remove deprecated configs
   - replaced Korolev font with open font
   - restyled admin/dashboard page
   - restyled admin/projects page
diff --git a/Gemfile b/Gemfile
index 96b5bb6a074f2b86d8748ff4072b51418c07133f..e969c2294710d0aa3ef9ee652a75e048784b914c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -20,6 +20,7 @@ gem 'omniauth', "~> 1.1.1"
 gem 'omniauth-google-oauth2'
 gem 'omniauth-twitter'
 gem 'omniauth-github'
+gem "omniauth-shibboleth", "~> 1.0.7"
 
 # GITLAB patched libs
 gem "grit",          git: "https://github.com/gitlabhq/grit.git",           ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
diff --git a/Gemfile.lock b/Gemfile.lock
index 7bf31c95babd5aefafa42bc586678740f6993e40..4b6a6d3ad6308031dba9378fd83d945203c36c69 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -297,6 +297,8 @@ GEM
     omniauth-oauth2 (1.1.1)
       oauth2 (~> 0.8.0)
       omniauth (~> 1.0)
+    omniauth-shibboleth (1.0.7)
+      omniauth-oauth (~> 1.0)
     omniauth-twitter (0.0.14)
       multi_json (~> 1.3)
       omniauth-oauth (~> 1.0)
@@ -518,6 +520,7 @@ DEPENDENCIES
   omniauth (~> 1.1.1)
   omniauth-github
   omniauth-google-oauth2
+  omniauth-shibboleth (~> 1.0.7)
   omniauth-twitter
   pg
   poltergeist!
diff --git a/VERSION b/VERSION
index 87db9036a822108fd68f9be0ad2186f2760e1155..ee74734aa2258df77aa09402d55798a1e2e55212 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.1.0rc1
+4.1.0
diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee
index cdc685f2c0906ed3b2ab782aaf6bd989bcd61eef..9c9cc6132b354d9d0220c6ecc1bb1102f9d12bca 100644
--- a/app/assets/javascripts/merge_requests.js.coffee
+++ b/app/assets/javascripts/merge_requests.js.coffee
@@ -51,6 +51,10 @@ class MergeRequest
     this.$('.nav-tabs').on 'click', 'li', (event) =>
       this.activateTab($(event.currentTarget).data('action'))
 
+    this.$('.accept_merge_request').on 'click', ->
+      $('.automerge_widget.can_be_merged').hide()
+      $('.merge-in-progress').show()
+
   activateTab: (action) ->
     this.$('.nav-tabs li').removeClass 'active'
     this.$('.tab-content').hide()
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index c4ebf0e48896b511b7c75cec48624a90edefa685..3cf3e5d277c912eaf9bdc815838257bb6483bf65 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -1,6 +1,6 @@
 class OmniauthCallbacksController < Devise::OmniauthCallbacksController
-  Gitlab.config.omniauth.providers.each do |provider|
-    define_method provider['name'] do
+  Gitlab.config.omniauth.providers.each_pair do |provider,args|
+    define_method provider do
       handle_omniauth
     end
   end
@@ -15,15 +15,6 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
     error.to_s.humanize if error
   end
 
-  def ldap
-    # We only find ourselves here if the authentication to LDAP was successful.
-    @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
-    if @user.persisted?
-      @user.remember_me = true
-    end
-    sign_in_and_redirect @user
-  end
-
   private
 
   def handle_omniauth
@@ -38,6 +29,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
       redirect_to profile_path
     else
       @user = User.find_or_new_for_omniauth(oauth)
+      # From old ldap callback, if persisted then remember_me.
+      if @user.persisted?
+        @user.remember_me = true
+      end
 
       if @user
         sign_in_and_redirect @user
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 6478982cdad3737a1a5957c7695f1225c98808fc..579e05911bf52d0ba6a74b1bc5292d5958216e7d 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -122,6 +122,10 @@ module ApplicationHelper
     Devise.omniauth_providers.include?(:ldap)
   end
 
+  def shibboleth_enable?
+    Devise.omniauth_providers.include?(:shibboleth)
+  end
+
   def app_theme
     Gitlab::Theme.css_class_by_id(current_user.try(:theme_id))
   end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index c0da9396baa3feb55a3241101ba331594b4f90c7..9d33501fdbc57a0cb2c79b245a7396e8b9d77500 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -57,13 +57,13 @@ class Ability
     def project_report_rules
       project_guest_rules + [
         :download_code,
-        :write_merge_request,
         :write_snippet
       ]
     end
 
     def project_dev_rules
       project_report_rules + [
+        :write_merge_request,
         :write_wiki,
         :push_code
       ]
diff --git a/app/models/user.rb b/app/models/user.rb
index 7a75379e5008662fd666bda146af875caa470dc7..2fc54d0d346193e6a4de2bf13374cfc6381ff7d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -115,10 +115,6 @@ class User < ActiveRecord::Base
       gitlab_auth.find_or_new_for_omniauth(auth)
     end
 
-    def find_for_ldap_auth(auth, signed_in_resource = nil)
-      gitlab_auth.find_for_ldap_auth(auth, signed_in_resource)
-    end
-
     def gitlab_auth
       Gitlab::Auth.new
     end
@@ -191,9 +187,9 @@ class User < ActiveRecord::Base
                   namespaces: namespaces.map(&:id), user_id: self.id)
   end
 
-  # Team membership in personal projects
-  def tm_in_personal_projects
-    UsersProject.where(project_id:  personal_projects.map(&:id), user_id: self.id)
+  # Team membership in authorized projects
+  def tm_in_authorized_projects
+    UsersProject.where(project_id:  authorized_projects.map(&:id), user_id: self.id)
   end
 
   # Returns a string for use as a Gitolite user identifier
diff --git a/app/views/admin/team_members/edit.html.haml b/app/views/admin/team_members/edit.html.haml
index 431387be15293055495236d6c6a17f440cbe8c70..aea9bd70a79d29f6d658979a62976ac5f597beb2 100644
--- a/app/views/admin/team_members/edit.html.haml
+++ b/app/views/admin/team_members/edit.html.haml
@@ -1,19 +1,8 @@
-%h3
-  Edit access
-  %small
-    = @admin_team_member.project.name
-    &ndash;
-    = @admin_team_member.user_name
+%p.slead
+  Edit access for
+  = link_to @admin_team_member.user_name, admin_user_path(@admin_team_member)
+  in
+  = link_to @admin_team_member.project.name_with_namespace, admin_project_path(@admin_team_member)
 
 %hr
-%table.zebra-striped
-  %tr
-    %td User:
-    %td= @admin_team_member.user_name
-  %tr
-    %td Project:
-    %td= @admin_team_member.project.name
-  %tr
-    %td Since:
-    %td= @admin_team_member.updated_at.stamp("Nov 11, 2010")
 = render 'form'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index db132359c7ffdec086291aef8c97f2b2198e19f9..a3be6614136818f04a1b9c56d351b791f0c891d7 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -106,8 +106,8 @@
         %td= link_to group.name, admin_group_path(group)
 
 
-- if @admin_user.personal_projects.present?
-  %h5 Personal Projects:
+- if @admin_user.authorized_projects.present?
+  %h5 Authorized Projects:
   %br
 
   %table.zebra-striped
@@ -118,7 +118,7 @@
         %th
         %th
 
-    - @admin_user.tm_in_personal_projects.each do |tm|
+    - @admin_user.tm_in_authorized_projects.each do |tm|
       - project = tm.project
       %tr
         %td= link_to project.name_with_namespace, admin_project_path(project)
diff --git a/app/views/devise/sessions/_new_shibboleth.html.haml b/app/views/devise/sessions/_new_shibboleth.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..c15f4243badae990cd59f0dcf7d59cdc5c995dbe
--- /dev/null
+++ b/app/views/devise/sessions/_new_shibboleth.html.haml
@@ -0,0 +1,2 @@
+:javascript
+  window.location.href="/users/auth/shibboleth";
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 0983f3157c4eeee3bd6690309e41acaa179825ae..034d2be8509f4292b27e0abb577a7f4dce656e76 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,5 +1,7 @@
 - if ldap_enable?
   = render :partial => 'devise/sessions/new_ldap'
+- elsif shibboleth_enable?
+  = render :partial => 'devise/sessions/new_shibboleth'
 - else
   = form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f|
     = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo"
diff --git a/app/views/help/permissions.html.haml b/app/views/help/permissions.html.haml
index c9ec701add7ef223e1ec30888451c1ec22ad94ad..b56251f35ebcddd2df84498d93258eff32b6c287 100644
--- a/app/views/help/permissions.html.haml
+++ b/app/views/help/permissions.html.haml
@@ -19,7 +19,6 @@
     %li Write on project wall
     %li Pull project code
     %li Download project
-    %li Create new merge request
     %li Create a code snippets
 
 
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index e00f96a7723e1f246c19746945661fc21bc27d94..14671c5ca70b116eb0066908653211618fbc5d5c 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -6,6 +6,9 @@
     = render "layouts/head_panel", title: project_title(@project)
     - if can?(current_user, :download_code, @project)
       = render 'shared/no_ssh'
+
+    - unless @project.users.include?(current_user)
+      = render 'shared/not_in_team'
     .container
       %ul.main_menu
         = nav_link(html_options: {class: "home #{project_tab_class}"}) do
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index 43651a5ca155944901cdc4af483bdda9b4f1f51f..61c32b533f6d7ef798f59958a8f883e7372badf7 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -1,4 +1,4 @@
-- if can? current_user, :write_issue, @project
+- if can? current_user, :write_merge_request, @project
   = link_to new_project_merge_request_path(@project), class: "right btn primary", title: "New Merge Request" do
     %i.icon-plus
     New Merge Request
@@ -10,7 +10,7 @@
 
 .row
   .span3
-    = render 'filter', entity: 'issue'
+    = render 'filter'
   .span9
     .ui-box
       .title
diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml
index 522e45e637a390a25a7a58e3d64c0291799b50be..51a55b8d5ac623b543dd809ca8a0f6c1d9a7a4e9 100644
--- a/app/views/profiles/account.html.haml
+++ b/app/views/profiles/account.html.haml
@@ -1,4 +1,4 @@
-- if Gitlab.config.omniauth.enabled
+- if Gitlab.config.omniauth.enabled and not Gitlab.config.omniauth.allow_single_sign_on
   %fieldset
     %legend Social Accounts
     .oauth_select_holder
@@ -29,27 +29,28 @@
             %span You don`t have one yet. Click generate to fix it.
             = f.submit 'Generate', class: "btn success btn-build-token"
 
-%fieldset
-  %legend Password
-  = form_for @user, url: update_password_profile_path, method: :put do |f|
-    .padded
-      %p.slead After successful password update you will be redirected to login page where you should login with new password
-      -if @user.errors.any?
-        .alert-message.block-message.error
-          %ul
-            - @user.errors.full_messages.each do |msg|
-              %li= msg
-
-      .clearfix
-        = f.label :password
-        .input= f.password_field :password, required: true
-      .clearfix
-        = f.label :password_confirmation
-        .input
-          = f.password_field :password_confirmation, required: true
-      .clearfix
-        .input
-          = f.submit 'Save password', class: "btn save-btn"
+- if not Gitlab.config.omniauth.allow_single_sign_on
+  %fieldset
+    %legend Password
+    = form_for @user, url: update_password_profile_path, method: :put do |f|
+      .padded
+        %p.slead After successful password update you will be redirected to login page where you should login with new password
+        -if @user.errors.any?
+          .alert-message.block-message.error
+            %ul
+              - @user.errors.full_messages.each do |msg|
+                %li= msg
+  
+        .clearfix
+          = f.label :password
+          .input= f.password_field :password, required: true
+        .clearfix
+          = f.label :password_confirmation
+          .input
+            = f.password_field :password_confirmation, required: true
+        .clearfix
+          .input
+            = f.submit 'Save password', class: "btn save-btn"
 
 
 
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index 7b5de4a62748d1549f1c430c431ef45e920c6dc6..5a92889254eda2c1a69a9213ee5f72f471360aa9 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -1,5 +1,6 @@
 .input-prepend.project_clone_holder
   %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
-  %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
+  - if not ( Gitlab.config.omniauth.allow_single_sign_on and shibboleth_enable? )
+    %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
 
   = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
diff --git a/app/views/shared/_not_in_team.html.haml b/app/views/shared/_not_in_team.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..0d003bde953e961af80895c0da288405392a8668
--- /dev/null
+++ b/app/views/shared/_not_in_team.html.haml
@@ -0,0 +1,2 @@
+%p.error_message.centered
+  You won't be able to use git over ssh until you join project on #{link_to 'team page', project_team_index_path(@project)}
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index b2dccbe3d4c9a4062300d26a3b0ddd9aa3332d07..683cb95a8af77a8865e8a6a23a55e175b3f27400 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -47,19 +47,6 @@ gravatar:
 #
 # 2. Auth settings
 # ==========================
-
-## LDAP settings
-ldap:
-  enabled: false
-  host: '_your_ldap_server'
-  base: '_the_base_where_you_search_for_users'
-  port: 636
-  uid: 'sAMAccountName'
-  method: 'ssl' # "ssl" or "plain"
-  bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
-  password: '_the_password_of_the_bind_user'
-
-## Omniauth settings
 omniauth:
   # Enable ability for users
   # Allow logging in via Twitter, Google, etc. using Omniauth providers
@@ -71,6 +58,9 @@ omniauth:
   allow_single_sign_on: false
   # Locks down those users until they have been cleared by the admin (default: true)
   block_auto_created_users: true
+  # Please note that ldap and shibboleth authentication methods need this settings:
+  # allow_single_sign_on: true
+  # block_auto_created_users: false
 
   ## Auth providers
   # Uncomment the lines and fill in the data of the auth provider you want to use
@@ -79,14 +69,40 @@ omniauth:
   # The 'app_id' and 'app_secret' parameters are always passed as the first two
   # arguments, followed by optional 'args' which can be either a hash or an array.
   providers:
-    # - { name: 'google_oauth2', app_id: 'YOUR APP ID',
-    #     app_secret: 'YOUR APP SECRET',
-    #     args: { access_type: 'offline', approval_prompt: '' } }
-    # - { name: 'twitter', app_id: 'YOUR APP ID',
-    #     app_secret: 'YOUR APP SECRET'}
-    # - { name: 'github', app_id: 'YOUR APP ID',
-    #     app_secret: 'YOUR APP SECRET' }
 
+    google_oauth2:
+      - 'YOUR APP ID'
+      - 'YOUR APP SECRET'
+      - args:
+          access_type: 'offline'
+          approval_prompt: ''
+
+    twitter:
+      - 'YOUR APP ID'
+      - 'YOUR APP SECRET'
+
+    github:
+      - 'YOUR APP ID'
+      - 'YOUR APP SECRET'
+
+    ldap:
+      host: '_your_ldap_server'
+      base: '_the_base_where_you_search_for_users'
+      port: 636
+      uid: 'sAMAccountName'
+      method: 'ssl' # plain
+      bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
+      password: '_the_password_of_the_bind_user'
+
+    shibboleth:
+      shib_session_id_field:     'HTTP_SHIB_SESSION_ID'
+      shib_application_id_field: 'HTTP_SHIB_APPLICATION_ID'
+      uid_field:   'HTTP_SSOUNIXNAME'
+      name_field:  'HTTP_SSONAME'
+      info_fields:
+        email: 'HTTP_SSOCONTACTMAIL'
+        username: 'HTTP_SSOUNIXNAME'
+      debug: false
 
 
 #
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index a1afa5b22c4f434b5fd1ff65ace51c387f7fa307..d3405c28f5e4ec336e843137fda92a90b1a43387 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -38,8 +38,9 @@ Settings['ldap'] ||= Settingslogic.new({})
 Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil?
 
 Settings['omniauth'] ||= Settingslogic.new({})
-Settings.omniauth['enabled']      = false if Settings.omniauth['enabled'].nil?
-Settings.omniauth['providers']  ||= []
+Settings.omniauth['enabled']              = false if Settings.omniauth['enabled'].nil?
+Settings.omniauth['allow_single_sign_on'] = false if Settings.omniauth['allow_single_sign_on'].nil?
+Settings.omniauth['providers']          ||= []
 
 Settings['gitlab'] ||= Settingslogic.new({})
 Settings.gitlab['default_projects_limit'] ||=  10
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 97946c54b40dad0976660da805da4d9102f81083..09858baca325eff6cdb214871ccdc1eb3104c216 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -205,27 +205,15 @@ Devise.setup do |config|
   #   manager.default_strategies(:scope => :user).unshift :some_external_strategy
   # end
 
-  if Gitlab.config.ldap.enabled
-    config.omniauth :ldap,
-      :host     => Gitlab.config.ldap['host'],
-      :base     => Gitlab.config.ldap['base'],
-      :uid      => Gitlab.config.ldap['uid'],
-      :port     => Gitlab.config.ldap['port'],
-      :method   => Gitlab.config.ldap['method'],
-      :bind_dn  => Gitlab.config.ldap['bind_dn'],
-      :password => Gitlab.config.ldap['password']
-  end
+  gl = Gitlab.config
 
-  Gitlab.config.omniauth.providers.each do |provider|
-    case provider['args']
-    when Array
+  gl.omniauth.providers.each_pair do |provider,args|
+    if Array == args.class
       # An Array from the configuration will be expanded.
-      config.omniauth provider['name'].to_sym, provider['app_id'], provider['app_secret'], *provider['args']
-    when Hash
+      config.omniauth provider.to_sym, *args
+    elsif Hash == args.class
       # A Hash from the configuration will be passed as is.
-      config.omniauth provider['name'].to_sym, provider['app_id'], provider['app_secret'], provider['args']
-    else
-      config.omniauth provider['name'].to_sym, provider['app_id'], provider['app_secret']
+      config.omniauth provider.to_sym, args
     end
   end
 end
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 27c87ec825f737466cca9fe935229b6c7ab39dce..7107d84617bbf047775397db331dd59a32cd3de5 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -190,10 +190,10 @@ See `doc/install/databases.md`
     cd /home/gitlab/gitlab
    
     # Checkout to stable release
-    sudo -u gitlab -H git checkout 4-0-stable
+    sudo -u gitlab -H git checkout 4-1-stable
 
 **Note:**
-You can change `4-0-stable` to `master` if you want the *bleeding edge* version, but
+You can change `4-1-stable` to `master` if you want the *bleeding edge* version, but
 do so with caution!
 
 ## Configure it
@@ -267,7 +267,7 @@ used for the `email.from` setting in `config/gitlab.yml`)
 
 Download the init script (will be /etc/init.d/gitlab):
 
-    sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab
+    sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab
     sudo chmod +x /etc/init.d/gitlab
 
 Make GitLab start on boot:
@@ -308,7 +308,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the
 
 Download an example site config:
 
-    sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab
+    sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/nginx/gitlab
     sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
 
 Make sure to edit the config file to match your setup:
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index d0e792befbb178ea6c3f5b5be520de106cdbb6c5..818f19c4212eb36a6f2f44e6096a22b2d355875d 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -1,67 +1,50 @@
 module Gitlab
   class Auth
-    def find_for_ldap_auth(auth, signed_in_resource = nil)
-      uid = auth.info.uid
+
+    def find_or_new_for_omniauth(auth)
       provider = auth.provider
+      uid = auth.info.uid || auth.uid
+      uid = uid.to_s.force_encoding("utf-8")
+      name = auth.info.name.force_encoding("utf-8")
       email = auth.info.email.downcase unless auth.info.email.nil?
-      raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
+      username = auth.info.username || email.match(/^[^@]*/)[0]
 
-      if @user = User.find_by_extern_uid_and_provider(uid, provider)
+      if @user = User.find_by_provider_and_extern_uid(provider, uid)
         @user
-      elsif @user = User.find_by_email(email)
-        log.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
+
+      elsif email and @user = User.find_by_email(email)
+        log.info "Updating legacy user #{email} with extern_uid => #{uid} from"\
+            " #{provider} {uid => #{uid}, name => #{name}, email => #{email}}"
         @user.update_attributes(:extern_uid => uid, :provider => provider)
         @user
-      else
-        create_from_omniauth(auth, true)
-      end
-    end
 
-    def create_from_omniauth(auth, ldap = false)
-      provider = auth.provider
-      uid = auth.info.uid || auth.uid
-      uid = uid.to_s.force_encoding("utf-8")
-      name = auth.info.name.to_s.force_encoding("utf-8")
-      email = auth.info.email.to_s.downcase unless auth.info.email.nil?
+      elsif Gitlab.config.omniauth['allow_single_sign_on']
 
-      ldap_prefix = ldap ? '(LDAP) ' : ''
-      raise OmniAuth::Error, "#{ldap_prefix}#{provider} does not provide an email"\
-        " address" if auth.info.email.blank?
+        raise OmniAuth::Error, "#{provider} does not provide an email"\
+          " address" if auth.info.email.blank?
 
-      log.info "#{ldap_prefix}Creating user from #{provider} login"\
-        " {uid => #{uid}, name => #{name}, email => #{email}}"
-      password = Devise.friendly_token[0, 8].downcase
-      @user = User.new({
-        extern_uid: uid,
-        provider: provider,
-        name: name,
-        username: email.match(/^[^@]*/)[0],
-        email: email,
-        password: password,
-        password_confirmation: password,
-        projects_limit: Gitlab.config.gitlab.default_projects_limit,
-      }, as: :admin)
-      if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
-        @user.blocked = true
-      end
-      @user.save!
-      @user
-    end
+        log.info "Creating user from #{provider} login"\
+          " {uid => #{uid}, name => #{name}, email => #{email}}"
 
-    def find_or_new_for_omniauth(auth)
-      provider, uid = auth.provider, auth.uid
-      email = auth.info.email.downcase unless auth.info.email.nil?
+        password = Devise.friendly_token[0, 8].downcase
 
-      if @user = User.find_by_provider_and_extern_uid(provider, uid)
-        @user
-      elsif @user = User.find_by_email(email)
-        @user.update_attributes(:extern_uid => uid, :provider => provider)
-        @user
-      else
-        if Gitlab.config.omniauth['allow_single_sign_on']
-          @user = create_from_omniauth(auth)
-          @user
+        @user = User.new({
+          extern_uid: uid,
+          provider: provider,
+          name: name,
+          email: email,
+          username: username,
+          password: password,
+          password_confirmation: password,
+          projects_limit: Gitlab.config.gitlab.default_projects_limit,
+        }, as: :admin)
+
+        if Gitlab.config.omniauth['block_auto_created_users']
+          @user.blocked = true
         end
+
+        @user.save!
+        @user
       end
     end
 
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 826b78ec5b1bc8ff175efa78704215aab5f773ba..e20809cc843e6ec3a50b93743da8ef7b90c63042 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -142,7 +142,7 @@ namespace :gitlab do
         return
       end
 
-      recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null`
+      recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab 2>/dev/null`
       script_content = File.read(script_path)
 
       if recipe_content == script_content
diff --git a/spec/lib/auth_spec.rb b/spec/lib/auth_spec.rb
index 1e03bc591b485b6a5a08eef89025478bfd3f6cf4..b4c707501e9133b320679183687f487371b4d59c 100644
--- a/spec/lib/auth_spec.rb
+++ b/spec/lib/auth_spec.rb
@@ -13,37 +13,6 @@ describe Gitlab::Auth do
     )
   end
 
-  describe :find_for_ldap_auth do
-    before do
-      @auth = mock(
-        uid: '12djsak321',
-        info: @info,
-        provider: 'ldap'
-      )
-    end
-
-    it "should find by uid & provider" do
-      User.should_receive :find_by_extern_uid_and_provider
-      gl_auth.find_for_ldap_auth(@auth)
-    end
-
-    it "should update credentials by email if missing uid" do
-      user = double('User')
-      User.stub find_by_extern_uid_and_provider: nil
-      User.stub find_by_email: user
-      user.should_receive :update_attributes
-      gl_auth.find_for_ldap_auth(@auth)
-    end
-
-
-    it "should create from auth if user doesnot exist"do
-      User.stub find_by_extern_uid_and_provider: nil
-      User.stub find_by_email: nil
-      gl_auth.should_receive :create_from_omniauth
-      gl_auth.find_for_ldap_auth(@auth)
-    end
-  end
-
   describe :find_or_new_for_omniauth do
     before do
       @auth = mock(
@@ -55,41 +24,19 @@ describe Gitlab::Auth do
 
     it "should find user"do
       User.should_receive :find_by_provider_and_extern_uid
-      gl_auth.should_not_receive :create_from_omniauth
       gl_auth.find_or_new_for_omniauth(@auth)
     end
 
     it "should not create user"do
       User.stub find_by_provider_and_extern_uid: nil
-      gl_auth.should_not_receive :create_from_omniauth
       gl_auth.find_or_new_for_omniauth(@auth)
     end
 
     it "should create user if single_sing_on"do
       Gitlab.config.omniauth['allow_single_sign_on'] = true
       User.stub find_by_provider_and_extern_uid: nil
-      gl_auth.should_receive :create_from_omniauth
       gl_auth.find_or_new_for_omniauth(@auth)
     end
   end
 
-  describe :create_from_omniauth do
-    it "should create user from LDAP" do
-      @auth = mock(info: @info, provider: 'ldap')
-      user = gl_auth.create_from_omniauth(@auth, true)
-
-      user.should be_valid
-      user.extern_uid.should == @info.uid
-      user.provider.should == 'ldap'
-    end
-
-    it "should create user from Omniauth" do
-      @auth = mock(info: @info, provider: 'twitter')
-      user = gl_auth.create_from_omniauth(@auth, false)
-
-      user.should be_valid
-      user.extern_uid.should == @info.uid
-      user.provider.should == 'twitter'
-    end
-  end
 end