Commit 621affecb59b8ce5304370cfd7979fba2b73ff4e
Exists in
master
and in
4 other branches
Merge branch 'master' of https://github.com/funglaub/gitlabhq into funglaub-master
Conflicts: Gemfile.lock app/helpers/application_helper.rb app/views/devise/sessions/new.html.erb db/schema.rb
Showing
18 changed files
with
188 additions
and
34 deletions
Show diff stats
Gemfile
@@ -16,6 +16,10 @@ gem "mysql2" | @@ -16,6 +16,10 @@ gem "mysql2" | ||
16 | 16 | ||
17 | # Auth | 17 | # Auth |
18 | gem "devise", "~> 2.1.0" | 18 | gem "devise", "~> 2.1.0" |
19 | +gem 'omniauth' | ||
20 | +gem 'omniauth-google-oauth2' | ||
21 | +gem 'omniauth-twitter' | ||
22 | +gem 'omniauth-github' | ||
19 | 23 | ||
20 | # GITLAB patched libs | 24 | # GITLAB patched libs |
21 | gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837" | 25 | gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837" |
app/assets/stylesheets/main.scss
@@ -134,7 +134,7 @@ $hover: #fdf5d9; | @@ -134,7 +134,7 @@ $hover: #fdf5d9; | ||
134 | * TODO: clean it | 134 | * TODO: clean it |
135 | */ | 135 | */ |
136 | @import "common.scss"; | 136 | @import "common.scss"; |
137 | - | 137 | +@import "auth_methods.scss"; |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * Styles related to specific part of app | 140 | * Styles related to specific part of app |
app/controllers/omniauth_callbacks_controller.rb
@@ -9,7 +9,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController | @@ -9,7 +9,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController | ||
9 | error ||= env["omniauth.error.type"].to_s | 9 | error ||= env["omniauth.error.type"].to_s |
10 | error.to_s.humanize if error | 10 | error.to_s.humanize if error |
11 | end | 11 | end |
12 | - | 12 | + |
13 | def ldap | 13 | def ldap |
14 | # We only find ourselves here if the authentication to LDAP was successful. | 14 | # We only find ourselves here if the authentication to LDAP was successful. |
15 | @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user) | 15 | @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user) |
@@ -19,4 +19,33 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController | @@ -19,4 +19,33 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController | ||
19 | sign_in_and_redirect @user | 19 | sign_in_and_redirect @user |
20 | end | 20 | end |
21 | 21 | ||
22 | + Settings.omniauth_providers.each do |provider| | ||
23 | + define_method provider['name'] do | ||
24 | + handle_omniauth | ||
25 | + end | ||
26 | + end | ||
27 | + | ||
28 | + private | ||
29 | + | ||
30 | + def handle_omniauth | ||
31 | + oauth = request.env['omniauth.auth'] | ||
32 | + provider, uid = oauth['provider'], oauth['uid'] | ||
33 | + | ||
34 | + if current_user | ||
35 | + # Change a logged-in user's authentication method: | ||
36 | + current_user.extern_uid = uid | ||
37 | + current_user.provider = provider | ||
38 | + current_user.save | ||
39 | + redirect_to profile_path | ||
40 | + else | ||
41 | + @user = User.find_or_new_for_omniauth(oauth) | ||
42 | + | ||
43 | + if @user | ||
44 | + sign_in_and_redirect @user | ||
45 | + else | ||
46 | + flash[:notice] = "There's no such user!" | ||
47 | + redirect_to new_user_session_path | ||
48 | + end | ||
49 | + end | ||
50 | + end | ||
22 | end | 51 | end |
app/helpers/application_helper.rb
@@ -135,4 +135,9 @@ module ApplicationHelper | @@ -135,4 +135,9 @@ module ApplicationHelper | ||
135 | "Never" | 135 | "Never" |
136 | end | 136 | end |
137 | end | 137 | end |
138 | + | ||
139 | + def authbutton(provider, size = 64) | ||
140 | + image_tag("authbuttons/#{provider.to_s.split('_').first}_#{size}.png", | ||
141 | + alt: "Sign in with #{provider.to_s.titleize}" ) | ||
142 | + end | ||
138 | end | 143 | end |
app/models/user.rb
@@ -86,10 +86,50 @@ class User < ActiveRecord::Base | @@ -86,10 +86,50 @@ class User < ActiveRecord::Base | ||
86 | where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') | 86 | where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') |
87 | end | 87 | end |
88 | 88 | ||
89 | + def self.create_from_omniauth(auth, ldap = false) | ||
90 | + provider, uid = auth.provider, auth.uid | ||
91 | + name = auth.info.name.force_encoding("utf-8") | ||
92 | + email = auth.info.email.downcase unless auth.info.email.nil? | ||
93 | + | ||
94 | + ldap_prefix = ldap ? '(LDAP) ' : '' | ||
95 | + raise OmniAuth::Error, "#{ldap_prefix}#{provider} does not provide an email"\ | ||
96 | + " address" if auth.info.email.blank? | ||
97 | + | ||
98 | + logger.info "#{ldap_prefix}Creating user from #{provider} login"\ | ||
99 | + " {uid => #{uid}, name => #{name}, email => #{email}}" | ||
100 | + password = Devise.friendly_token[0, 8].downcase | ||
101 | + @user = User.new( | ||
102 | + extern_uid: uid, | ||
103 | + provider: provider, | ||
104 | + name: name, | ||
105 | + email: email, | ||
106 | + password: password, | ||
107 | + password_confirmation: password, | ||
108 | + projects_limit: Gitlab.config.default_projects_limit, | ||
109 | + ) | ||
110 | + if Gitlab.config.omniauth.block_auto_created_users && !ldap | ||
111 | + @user.blocked = true | ||
112 | + end | ||
113 | + @user.save! | ||
114 | + @user | ||
115 | + end | ||
116 | + | ||
117 | + def self.find_or_new_for_omniauth(auth) | ||
118 | + provider, uid = auth.provider, auth.uid | ||
119 | + | ||
120 | + if @user = User.find_by_provider_and_extern_uid(provider, uid) | ||
121 | + @user | ||
122 | + else | ||
123 | + if Gitlab.config.omniauth.allow_single_sign_on | ||
124 | + @user = User.create_from_omniauth(auth) | ||
125 | + @user | ||
126 | + end | ||
127 | + end | ||
128 | + end | ||
129 | + | ||
89 | def self.find_for_ldap_auth(auth, signed_in_resource=nil) | 130 | def self.find_for_ldap_auth(auth, signed_in_resource=nil) |
90 | uid = auth.info.uid | 131 | uid = auth.info.uid |
91 | provider = auth.provider | 132 | provider = auth.provider |
92 | - name = auth.info.name.force_encoding("utf-8") | ||
93 | email = auth.info.email.downcase unless auth.info.email.nil? | 133 | email = auth.info.email.downcase unless auth.info.email.nil? |
94 | raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil? | 134 | raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil? |
95 | 135 | ||
@@ -101,17 +141,7 @@ class User < ActiveRecord::Base | @@ -101,17 +141,7 @@ class User < ActiveRecord::Base | ||
101 | @user.update_attributes(:extern_uid => uid, :provider => provider) | 141 | @user.update_attributes(:extern_uid => uid, :provider => provider) |
102 | @user | 142 | @user |
103 | else | 143 | else |
104 | - logger.info "Creating user from LDAP login {uid => #{uid}, name => #{name}, email => #{email}}" | ||
105 | - password = Devise.friendly_token[0, 8].downcase | ||
106 | - @user = User.create( | ||
107 | - :extern_uid => uid, | ||
108 | - :provider => provider, | ||
109 | - :name => name, | ||
110 | - :email => email, | ||
111 | - :password => password, | ||
112 | - :password_confirmation => password, | ||
113 | - :projects_limit => Gitlab.config.default_projects_limit | ||
114 | - ) | 144 | + create_from_omniauth(auth) |
115 | end | 145 | end |
116 | end | 146 | end |
117 | 147 | ||
@@ -148,4 +178,3 @@ end | @@ -148,4 +178,3 @@ end | ||
148 | # bio :string(255) | 178 | # bio :string(255) |
149 | # blocked :boolean(1) default(FALSE), not null | 179 | # blocked :boolean(1) default(FALSE), not null |
150 | # | 180 | # |
151 | - |
@@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +<% unless ldap_enable? -%> | ||
2 | + | ||
3 | + <%= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f| %> | ||
4 | + <%= image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo" %> | ||
5 | + | ||
6 | + <%= f.text_field :email, :class => "text top", :placeholder => "Email" %> | ||
7 | + <%= f.password_field :password, :class => "text bottom", :placeholder => "Password" %> | ||
8 | + | ||
9 | + <% if devise_mapping.rememberable? -%> | ||
10 | + <div class="clearfix inputs-list"> <label class="checkbox remember_me" for="user_remember_me"><%= f.check_box :remember_me %><span>Remember me</span></label></div> | ||
11 | + <% end -%> | ||
12 | + <br/> | ||
13 | + <%= f.submit "Sign in", :class => "primary btn" %> | ||
14 | + <div class="right"> <%= render :partial => "devise/shared/links" %></div> | ||
15 | + | ||
16 | + <%- if devise_mapping.omniauthable? %> | ||
17 | + <hr/> | ||
18 | + <div class="auth_methods"> | ||
19 | + <ul> | ||
20 | + <%- resource_class.omniauth_providers.each do |provider| %> | ||
21 | + <li><%= link_to authbutton(provider), | ||
22 | + omniauth_authorize_path(resource_name, provider) %></li> | ||
23 | + <% end -%> | ||
24 | + </ul> | ||
25 | + </div> | ||
26 | + <% end -%> | ||
27 | + | ||
28 | + <% end %> | ||
29 | + | ||
30 | +<% else %> | ||
31 | + <%= render :partial => 'devise/sessions/new_ldap' %> | ||
32 | +<% end %> |
app/views/layouts/profile.html.haml
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | = link_to "Profile", profile_path | 10 | = link_to "Profile", profile_path |
11 | 11 | ||
12 | %li{class: tab_class(:password)} | 12 | %li{class: tab_class(:password)} |
13 | - = link_to "Password", profile_password_path | 13 | + = link_to "Authentication", profile_password_path |
14 | 14 | ||
15 | %li{class: tab_class(:ssh_keys)} | 15 | %li{class: tab_class(:ssh_keys)} |
16 | = link_to keys_path do | 16 | = link_to keys_path do |
app/views/profile/password.html.haml
1 | %h3.page_title Password | 1 | %h3.page_title Password |
2 | %hr | 2 | %hr |
3 | + | ||
3 | = form_for @user, url: profile_password_path, method: :put do |f| | 4 | = form_for @user, url: profile_password_path, method: :put do |f| |
4 | - .data | ||
5 | - %p.slead After successful password update you will be redirected to login page where you should login with new password | ||
6 | - -if @user.errors.any? | ||
7 | - .alert-message.block-message.error | ||
8 | - %ul | ||
9 | - - @user.errors.full_messages.each do |msg| | ||
10 | - %li= msg | 5 | + .row |
6 | + .span7 | ||
7 | + .data | ||
8 | + %p.slead After successful password update you will be redirected to login page where you should login with new password | ||
9 | + -if @user.errors.any? | ||
10 | + .alert-message.block-message.error | ||
11 | + %ul | ||
12 | + - @user.errors.full_messages.each do |msg| | ||
13 | + %li= msg | ||
14 | + | ||
15 | + .clearfix | ||
16 | + = f.label :password | ||
17 | + .input= f.password_field :password | ||
18 | + .clearfix | ||
19 | + = f.label :password_confirmation | ||
20 | + .input= f.password_field :password_confirmation | ||
11 | 21 | ||
12 | - .clearfix | ||
13 | - = f.label :password | ||
14 | - .input= f.password_field :password | ||
15 | - .clearfix | ||
16 | - = f.label :password_confirmation | ||
17 | - .input= f.password_field :password_confirmation | 22 | + - if Settings.omniauth.enabled |
23 | + .span5.right | ||
24 | + .auth_methods.alert.alert-info | ||
25 | + %strong Tip: Use one of the following sites to login | ||
26 | + %ul | ||
27 | + - User.omniauth_providers.each do |provider| | ||
28 | + %li= link_to authbutton(provider), | | ||
29 | + omniauth_authorize_path(User, provider) | | ||
18 | .actions | 30 | .actions |
19 | = f.submit 'Save', class: "btn save-btn" | 31 | = f.submit 'Save', class: "btn save-btn" |
app/views/profile/show.html.haml
@@ -50,6 +50,13 @@ | @@ -50,6 +50,13 @@ | ||
50 | %strong Tip: | 50 | %strong Tip: |
51 | You can change your avatar at gravatar.com | 51 | You can change your avatar at gravatar.com |
52 | 52 | ||
53 | + - if Settings.omniauth.enabled && @user.provider? | ||
54 | + %h4 | ||
55 | + Omniauth Providers: | ||
56 | + = link_to "Change", profile_password_path, class: "btn small right" | ||
57 | + You can login through #{@user.provider.titleize}! | ||
58 | + = authbutton(@user.provider, 32) | ||
59 | + | ||
53 | %h4 | 60 | %h4 |
54 | Personal projects: | 61 | Personal projects: |
55 | %small.right | 62 | %small.right |
config/gitlab.yml.example
@@ -50,3 +50,21 @@ git: | @@ -50,3 +50,21 @@ git: | ||
50 | git_max_size: 5242880 # 5.megabytes | 50 | git_max_size: 5242880 # 5.megabytes |
51 | # Git timeout to read commit, in seconds | 51 | # Git timeout to read commit, in seconds |
52 | git_timeout: 10 | 52 | git_timeout: 10 |
53 | + | ||
54 | +# Omniauth configuration | ||
55 | +omniauth: | ||
56 | + enabled: false | ||
57 | + providers: | ||
58 | + allow_single_sign_on: false | ||
59 | + block_auto_created_users: true | ||
60 | + | ||
61 | +# omniauth: | ||
62 | +# enabled: true | ||
63 | +# providers: | ||
64 | +# - { name: 'google_oauth2', app_id: 'YOUR APP ID', | ||
65 | +# app_secret: 'YOUR APP SECRET', | ||
66 | +# args: { access_type: 'offline', approval_prompt: '' } } | ||
67 | +# - { name: 'twitter', app_id: 'YOUR APP ID', | ||
68 | +# app_secret: 'YOUR APP SECRET'} | ||
69 | +# - { name: 'github', app_id: 'YOUR APP ID', | ||
70 | +# app_secret: 'YOUR APP SECRET' } |
config/initializers/1_settings.rb
@@ -6,7 +6,7 @@ class Settings < Settingslogic | @@ -6,7 +6,7 @@ class Settings < Settingslogic | ||
6 | self.web['protocol'] ||= web.https ? "https" : "http" | 6 | self.web['protocol'] ||= web.https ? "https" : "http" |
7 | end | 7 | end |
8 | 8 | ||
9 | - def web_host | 9 | + def web_host |
10 | self.web['host'] ||= 'localhost' | 10 | self.web['host'] ||= 'localhost' |
11 | end | 11 | end |
12 | 12 | ||
@@ -14,11 +14,11 @@ class Settings < Settingslogic | @@ -14,11 +14,11 @@ class Settings < Settingslogic | ||
14 | self.email['from'] ||= ("notify@" + web_host) | 14 | self.email['from'] ||= ("notify@" + web_host) |
15 | end | 15 | end |
16 | 16 | ||
17 | - def url | 17 | + def url |
18 | self['url'] ||= build_url | 18 | self['url'] ||= build_url |
19 | - end | 19 | + end |
20 | 20 | ||
21 | - def web_port | 21 | + def web_port |
22 | if web.https | 22 | if web.https |
23 | web['port'] = 443 | 23 | web['port'] = 443 |
24 | else | 24 | else |
@@ -36,7 +36,7 @@ class Settings < Settingslogic | @@ -36,7 +36,7 @@ class Settings < Settingslogic | ||
36 | raw_url << web_host | 36 | raw_url << web_host |
37 | 37 | ||
38 | if web_custom_port? | 38 | if web_custom_port? |
39 | - raw_url << ":#{web_port}" | 39 | + raw_url << ":#{web_port}" |
40 | end | 40 | end |
41 | 41 | ||
42 | raw_url | 42 | raw_url |
@@ -120,6 +120,14 @@ class Settings < Settingslogic | @@ -120,6 +120,14 @@ class Settings < Settingslogic | ||
120 | app['backup_keep_time'] || 0 | 120 | app['backup_keep_time'] || 0 |
121 | end | 121 | end |
122 | 122 | ||
123 | + def omniauth_enabled? | ||
124 | + omniauth['enabled'] || false | ||
125 | + end | ||
126 | + | ||
127 | + def omniauth_providers | ||
128 | + omniauth['providers'] || [] | ||
129 | + end | ||
130 | + | ||
123 | def disable_gravatar? | 131 | def disable_gravatar? |
124 | app['disable_gravatar'] || false | 132 | app['disable_gravatar'] || false |
125 | end | 133 | end |
1.89 KB
4.34 KB
1.58 KB
3.37 KB
1.41 KB
3.3 KB