diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 10fe1245115648b71dbf9cea3659eb804e6396e3..684f4be0d10e902e4173ce0c084a6e96d74fc6b2 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -110,6 +110,11 @@ production: &base
       # - { name: 'github', app_id: 'YOUR APP ID',
       #     app_secret: 'YOUR APP SECRET' }
 
+  ## User mapping settings
+  user_mapping:
+    name: ->(uid, name, email) { name }
+    username: ->(uid, name, email) { email.match(/^[^@]*/)[0] }
+    email: ->(uid, name, email) { email }
 
 
   #
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 0fee33dbeb0ef4548a91a9c3662de510ca76e91a..9928849721891f51bc09e98a2486837acd8451e7 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -18,30 +18,9 @@ module Gitlab
     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?
-
-      ldap_prefix = ldap ? '(LDAP) ' : ''
-      raise OmniAuth::Error, "#{ldap_prefix}#{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)
-      @user.save!
+      creation_helper = UserCreationHelper.new(auth, ldap)
+      log.info creation_helper.creation_message
+      @user = User.create!(creation_helper.parameters, as: :admin)
 
       if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
         @user.block
@@ -70,5 +49,79 @@ module Gitlab
     def log
       Gitlab::AppLogger
     end
+
+    class UserCreationHelper
+      def initialize(auth, ldap = false)
+        @auth = auth
+        @ldap = ldap
+        @procs = {
+          name_proc: ->(uid, name, email) { name }
+          username_proc: ->(uid, name, email) { email.match(/^[^@]*/)[0] }
+          email_proc: ->(uid, name, email) { email }
+        }.merge(Gitlab.config.user_mapping)
+      end
+
+      def parameters
+        {
+          extern_uid: uid,
+          provider: provider,
+          name: name,
+          username: username,
+          email: email,
+          password: password,
+          password_confirmation: password,
+          projects_limit: Gitlab.config.gitlab.default_projects_limit 
+        }
+      end
+
+      def uid
+        (@auth.info.uid || @auth.uid).to_s.force_encoding("utf-8")
+      end
+
+      def provider
+        @auth.info.provider
+      end
+
+      def name
+        @procs[:name].call(uid, raw_name, raw_email)
+      end
+
+      def username
+        @procs[:username].call(uid, raw_name, raw_email)
+      end
+
+      def email
+        @procs[:email].call(uid, raw_name, raw_email)
+      end
+
+      def password
+        @password ||= Devise.friendly_token[0, 8].downcase
+      end
+
+      def creation_message
+        "#{ldap_prefix}Creating user from #{provider} login"\
+          " {uid => #{uid}, name => #{name}, email => #{email}}"
+      end
+
+      private
+
+      def raw_name
+        @auth.info.name.to_s.force_encoding("utf-8")
+      end
+
+      def raw_email
+        auth.info.email.nil? ? email_error : auth.info.email.to_s.downcase
+      end
+
+      def ldap_prefix
+        ldap ? '(LDAP) ' : ''
+      end
+
+      def email_error
+        raise OmniAuth::Error, "#{ldap_prefix}#{parameters.provider} does not"\
+          " provide an email address" unless parameters.email
+      end
+    end
+
   end
 end