From a64aff2f1c1ddc77b00211489d74fbc23c0c2fa2 Mon Sep 17 00:00:00 2001
From: Florian Unglaub <florian.unglaub@nix-wie-weg.de>
Date: Fri, 3 Aug 2012 17:27:39 +0200
Subject: [PATCH] Omniauth Support

---
 Gemfile                                       |   4 ++
 Gemfile.lock                                  |  32 +++++++++++++++
 app/assets/stylesheets/auth_methods.scss      |  10 +++++
 app/assets/stylesheets/main.scss              |  26 ++++++------
 .../omniauth_callbacks_controller.rb          |  32 ++++++++++++++-
 app/helpers/application_helper.rb             |  11 +++--
 app/views/devise/sessions/new.html.erb        |  13 ++++--
 app/views/layouts/profile.html.haml           |   2 +-
 app/views/profile/password.html.haml          |  38 ++++++++++++------
 app/views/profile/show.html.haml              |   7 ++++
 config/gitlab.yml.example                     |  22 +++++++---
 config/initializers/1_settings.rb             |  19 ++++++---
 ...803152018_add_provider_and_uid_to_users.rb |   6 +++
 db/schema.rb                                  |  32 ++++++++-------
 .../assets/images/authbuttons/github_32.png   | Bin 0 -> 1931 bytes
 .../assets/images/authbuttons/github_64.png   | Bin 0 -> 4447 bytes
 .../assets/images/authbuttons/google_32.png   | Bin 0 -> 1615 bytes
 .../assets/images/authbuttons/google_64.png   | Bin 0 -> 3446 bytes
 .../assets/images/authbuttons/twitter_32.png  | Bin 0 -> 1439 bytes
 .../assets/images/authbuttons/twitter_64.png  | Bin 0 -> 3384 bytes
 20 files changed, 194 insertions(+), 60 deletions(-)
 create mode 100644 app/assets/stylesheets/auth_methods.scss
 create mode 100644 db/migrate/20120803152018_add_provider_and_uid_to_users.rb
 create mode 100644 vendor/assets/images/authbuttons/github_32.png
 create mode 100644 vendor/assets/images/authbuttons/github_64.png
 create mode 100644 vendor/assets/images/authbuttons/google_32.png
 create mode 100644 vendor/assets/images/authbuttons/google_64.png
 create mode 100644 vendor/assets/images/authbuttons/twitter_32.png
 create mode 100644 vendor/assets/images/authbuttons/twitter_64.png

diff --git a/Gemfile b/Gemfile
index d2a5728f97c5a..12610b6582118 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,6 +8,10 @@ gem "mysql2"
 
 # Auth
 gem "devise", "~> 2.1.0"
+gem 'omniauth'
+gem 'omniauth-google-oauth2'
+gem 'omniauth-twitter'
+gem 'omniauth-github'
 
 # GITLAB patched libs
 gem "grit",          :git => "https://github.com/gitlabhq/grit.git",            :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
diff --git a/Gemfile.lock b/Gemfile.lock
index 7356c35ede085..b34f401b1c4c9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -166,6 +166,8 @@ GEM
     eventmachine (0.12.10)
     execjs (1.4.0)
       multi_json (~> 1.0)
+    faraday (0.8.1)
+      multipart-post (~> 1.1)
     ffaker (1.14.0)
     ffi (1.0.11)
     foreman (0.47.0)
@@ -191,6 +193,7 @@ GEM
     httparty (0.8.3)
       multi_json (~> 1.0)
       multi_xml
+    httpauth (0.1)
     i18n (0.6.0)
     journey (1.0.4)
     jquery-rails (2.0.2)
@@ -200,6 +203,8 @@ GEM
       jquery-rails
       railties (>= 3.1.0)
     json (1.7.4)
+    jwt (0.1.5)
+      multi_json (>= 1.0)
     kaminari (0.13.0)
       actionpack (>= 3.0.0)
       activesupport (>= 3.0.0)
@@ -223,12 +228,35 @@ GEM
       sprockets (~> 2.0)
     multi_json (1.3.6)
     multi_xml (0.5.1)
+    multipart-post (1.1.5)
     mysql2 (0.3.11)
     net-ldap (0.2.2)
     nokogiri (1.5.3)
+    oauth (0.4.6)
+    oauth2 (0.8.0)
+      faraday (~> 0.8)
+      httpauth (~> 0.1)
+      jwt (~> 0.1.4)
+      multi_json (~> 1.0)
+      rack (~> 1.2)
     omniauth (1.1.0)
       hashie (~> 1.2)
       rack
+    omniauth-github (1.0.1)
+      omniauth (~> 1.0)
+      omniauth-oauth2 (~> 1.0)
+    omniauth-google-oauth2 (0.1.13)
+      omniauth (~> 1.0)
+      omniauth-oauth2
+    omniauth-oauth (1.0.1)
+      oauth
+      omniauth (~> 1.0)
+    omniauth-oauth2 (1.1.0)
+      oauth2 (~> 0.8.0)
+      omniauth (~> 1.0)
+    omniauth-twitter (0.0.12)
+      multi_json (~> 1.3)
+      omniauth-oauth (~> 1.0)
     orm_adapter (0.3.0)
     polyglot (0.3.3)
     posix-spawn (0.3.6)
@@ -411,7 +439,11 @@ DEPENDENCIES
   minitest (>= 2.10)
   modernizr (= 2.5.3)
   mysql2
+  omniauth
+  omniauth-github
+  omniauth-google-oauth2
   omniauth-ldap!
+  omniauth-twitter
   pry
   pygments.rb!
   rack-mini-profiler
diff --git a/app/assets/stylesheets/auth_methods.scss b/app/assets/stylesheets/auth_methods.scss
new file mode 100644
index 0000000000000..ed6f5b0fe2dc9
--- /dev/null
+++ b/app/assets/stylesheets/auth_methods.scss
@@ -0,0 +1,10 @@
+.auth_methods {
+  &ul {
+    margin: 0;
+    text-align:center;
+    padding: 5px;
+    &li {
+      display: inline;
+    }
+  }
+}
diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss
index 5613f1e82d883..0e3de4e83fe7a 100644
--- a/app/assets/stylesheets/main.scss
+++ b/app/assets/stylesheets/main.scss
@@ -3,8 +3,8 @@
 
 /** GITLAB colors **/
 $text_color:#222;
-$lite_text_color: #666; 
-$link_color:#2A79A3; 
+$lite_text_color: #666;
+$link_color:#2A79A3;
 $active_link_color:#2FA0BB;
 $active_bg_color:#79C3E0;
 $active_bd_color: #2FA0BB;
@@ -31,7 +31,7 @@ $hover: #FDF5D9;
   box-shadow: 0 0 3px #ddd;
 }
 
-@mixin solid_shade { 
+@mixin solid_shade {
   -moz-box-shadow: 0 0 0 3px #eee;
   -webkit-box-shadow: 0 0 0 3px #eee;
   box-shadow: 0 0 0 3px #eee;
@@ -73,21 +73,21 @@ $hover: #FDF5D9;
 
 
 /**
- * Header of application. 
+ * Header of application.
  * Contain application logo, search panel, profile icon
  */
 @import "sections/header.scss";
 
 /**
- * Navigation menu of application. 
+ * Navigation menu of application.
  * Panel with links to pages depends on project, profile or admin area
  */
 @import "sections/nav.scss";
 
 /**
- * This file represent some UI that can be changed 
- * during web app restyle or theme select. 
- * 
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
+ *
  * Next items should be placed there
  * - link, button colors
  * - header restyles
@@ -118,11 +118,11 @@ $hover: #FDF5D9;
  * Most of application styles placed here.
  * This file represent common UI that should not be changed between themes
  * or project restyling like form width or user avatar class or commit title
- * 
+ *
  * TODO: clean it
  */
 @import "common.scss";
-
+@import "auth_methods.scss";
 
 /**
  * Styles related to specific part of app
@@ -140,17 +140,17 @@ $hover: #FDF5D9;
 @import "ref_select.scss";
 
 /**
- * Code (files list) styles. Browsing project files there 
+ * Code (files list) styles. Browsing project files there
  */
 @import "sections/tree.scss";
 
 /**
- * This file represent notes(comments) styles 
+ * This file represent notes(comments) styles
  */
 @import "sections/notes.scss";
 
 /**
- * Devise styles 
+ * Devise styles
  */
 @import "sections/login.scss";
 
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index d19931e93d77d..84e578a386509 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -9,7 +9,7 @@ def failure_message
     error ||= env["omniauth.error.type"].to_s
     error.to_s.humanize if error
   end
- 
+
   def ldap
     # We only find ourselves here if the authentication to LDAP was successful.
     info = request.env["omniauth.auth"]["info"]
@@ -20,4 +20,34 @@ def ldap
     sign_in_and_redirect @user
   end
 
+   Settings.omniauth_providers.each do |provider|
+    define_method provider['name'] do
+      handle_omniauth
+    end
+  end
+
+  private
+
+  def handle_omniauth
+    oauth = request.env['omniauth.auth']
+    provider, uid = oauth['provider'], oauth['uid']
+
+    if current_user
+      # Change a logged-in user's authentication method:
+      current_user.uid = uid
+      current_user.provider = provider
+      current_user.save
+      redirect_to profile_path
+    else
+      @user = User.find_by_provider_and_uid(provider, uid)
+
+      if @user
+        sign_in_and_redirect @user
+      else
+        flash[:notice] = "There's no such user!"
+        redirect_to new_user_session_path
+      end
+    end
+  end
+
 end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 51569b0635eb0..8a457cea70fe3 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -75,16 +75,16 @@ def app_theme
   end
 
   def show_last_push_widget?(event)
-    event && 
+    event &&
       event.last_push_to_non_root? &&
       !event.rm_ref? &&
-      event.project && 
+      event.project &&
       event.project.merge_requests_enabled
   end
 
   def tab_class(tab_key)
     active = case tab_key
-             
+
              # Project Area
              when :wall; wall_tab?
              when :wiki; controller.controller_name == "wikis"
@@ -123,4 +123,9 @@ def tab_class(tab_key)
   def hexdigest(string)
     Digest::SHA1.hexdigest string
   end
+
+  def authbutton(provider, size = 64)
+    image_tag("authbuttons/#{provider.to_s.split('_').first}_#{size}.png",
+               alt: "Sign in with #{provider.to_s.titleize}" )
+  end
 end
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index a03838669cf9c..6b334b8733560 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -14,10 +14,15 @@
     <div class="right"> <%= render :partial => "devise/shared/links" %></div>
 
     <%- if devise_mapping.omniauthable? %>
-      <%- resource_class.omniauth_providers.each do |provider| %>
-        <hr/>
-        <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), :class => "btn primary" %><br />
-      <% end -%>
+      <hr/>
+      <div class="auth_methods">
+        <ul>
+          <%- resource_class.omniauth_providers.each do |provider| %>
+          <li><%= link_to authbutton(provider),
+                   omniauth_authorize_path(resource_name, provider) %></li>
+          <% end -%>
+        </ul>
+      </div>
     <% end -%>
 
   <% end %>
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index b624415dfe119..810b346f1cdf5 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -10,7 +10,7 @@
           = link_to "Profile", profile_path
 
         %li{class: tab_class(:password)}
-          = link_to "Password", profile_password_path
+          = link_to "Authentication", profile_password_path
 
         %li{class: tab_class(:ssh_keys)}
           = link_to keys_path do
diff --git a/app/views/profile/password.html.haml b/app/views/profile/password.html.haml
index 257dacb1ad37b..1d4d468c38b0d 100644
--- a/app/views/profile/password.html.haml
+++ b/app/views/profile/password.html.haml
@@ -1,19 +1,31 @@
 %h3.page_title Password
 %hr
+
 = form_for @user, url: profile_password_path, method: :put do |f|
-  .data
-    %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
+  .row
+    .span7
+      .data
+        %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
+        .clearfix
+          = f.label :password_confirmation
+          .input= f.password_field :password_confirmation
 
-    .clearfix
-      = f.label :password
-      .input= f.password_field :password
-    .clearfix
-      = f.label :password_confirmation
-      .input= f.password_field :password_confirmation
+    - if Settings.omniauth.enabled
+      .span5.right
+        .auth_methods.alert.alert-info
+          %strong Tip: Use one of the following sites to login
+          %ul
+            - User.omniauth_providers.each do |provider|
+              %li= link_to authbutton(provider), |
+                   omniauth_authorize_path(User, provider) |
   .actions
     = f.submit 'Save', class: "btn primary"
diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml
index 95cce2bb6b6c4..4d89cd3dcb333 100644
--- a/app/views/profile/show.html.haml
+++ b/app/views/profile/show.html.haml
@@ -49,6 +49,13 @@
         %strong Tip:
         You can change your avatar at gravatar.com
 
+      - if Settings.omniauth.enabled && @user.provider?
+        %h4
+          Omniauth Providers:
+        = link_to "Change", profile_password_path, class: "btn small right"
+        You can login through #{@user.provider.titleize}!
+        = authbutton(@user.provider, 32)
+
       %h4
         Personal projects:
         %small.right
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 1818f2c0d0101..622ac9ec560c3 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1,4 +1,4 @@
-# # # # # # # # # # # # # # # # # # 
+# # # # # # # # # # # # # # # # # #
 # Gitlab application config file  #
 # # # # # # # # # # # # # # # # # #
 
@@ -19,14 +19,14 @@ email:
 
 # Application specific settings
 # Like default project limit for user etc
-app: 
-  default_projects_limit: 10 
+app:
+  default_projects_limit: 10
   # backup_path: "/vol/backups"   # default: Rails.root + backups/
   # backup_keep_time: 604800      # default: 0 (forever) (in seconds)
 
 
-# 
-# 2. Advanced settings: 
+#
+# 2. Advanced settings:
 # ==========================
 
 # Git Hosting configuration
@@ -49,3 +49,15 @@ git:
   git_max_size: 5242880 # 5.megabytes
   # Git timeout to read commit, in seconds
   git_timeout: 10
+
+# Omniauth configuration
+# omniauth:
+#   enabled: true
+#   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' }
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 5c5987a8857a9..741a29d51bebe 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -6,7 +6,7 @@ def web_protocol
       self.web['protocol'] ||= web.https ? "https" : "http"
     end
 
-    def web_host 
+    def web_host
       self.web['host'] ||= 'localhost'
     end
 
@@ -14,11 +14,11 @@ def email_from
       self.email['from'] ||= ("notify@" + web_host)
     end
 
-    def url 
+    def url
       self['url'] ||= build_url
-    end 
+    end
 
-    def web_port 
+    def web_port
       if web.https
         web['port'] = 443
       else
@@ -36,7 +36,7 @@ def build_url
       raw_url << web_host
 
       if web_custom_port?
-        raw_url << ":#{web_port}" 
+        raw_url << ":#{web_port}"
       end
 
       raw_url
@@ -111,5 +111,14 @@ def backup_path
     def backup_keep_time
       app['backup_keep_time'] || 0
     end
+
+    def omniauth_enabled?
+      omniauth['enabled'] || false
+    end
+
+    def omniauth_providers
+      omniauth['providers'] || []
+    end
+
   end
 end
diff --git a/db/migrate/20120803152018_add_provider_and_uid_to_users.rb b/db/migrate/20120803152018_add_provider_and_uid_to_users.rb
new file mode 100644
index 0000000000000..14f53e4ee231f
--- /dev/null
+++ b/db/migrate/20120803152018_add_provider_and_uid_to_users.rb
@@ -0,0 +1,6 @@
+class AddProviderAndUidToUsers < ActiveRecord::Migration
+  def change
+    add_column :users, :provider, :string
+    add_column :users, :uid, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index c4c54f562a3ec..5ac159d8facdb 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20120712080407) do
+ActiveRecord::Schema.define(:version => 20120803152018) do
 
   create_table "events", :force => true do |t|
     t.string   "target_type"
@@ -146,31 +146,33 @@
   end
 
   create_table "users", :force => true do |t|
-    t.string   "email",                                 :default => "",    :null => false
-    t.string   "encrypted_password",     :limit => 128, :default => "",    :null => false
+    t.string   "email",                  :default => "",    :null => false
+    t.string   "encrypted_password",     :default => "",    :null => false
     t.string   "reset_password_token"
     t.datetime "reset_password_sent_at"
     t.datetime "remember_created_at"
-    t.integer  "sign_in_count",                         :default => 0
+    t.integer  "sign_in_count",          :default => 0
     t.datetime "current_sign_in_at"
     t.datetime "last_sign_in_at"
     t.string   "current_sign_in_ip"
     t.string   "last_sign_in_ip"
-    t.datetime "created_at",                                               :null => false
-    t.datetime "updated_at",                                               :null => false
+    t.datetime "created_at",                                :null => false
+    t.datetime "updated_at",                                :null => false
     t.string   "name"
-    t.boolean  "admin",                                 :default => false, :null => false
-    t.integer  "projects_limit",                        :default => 10
-    t.string   "skype",                                 :default => "",    :null => false
-    t.string   "linkedin",                              :default => "",    :null => false
-    t.string   "twitter",                               :default => "",    :null => false
+    t.boolean  "admin",                  :default => false, :null => false
+    t.integer  "projects_limit",         :default => 10
+    t.string   "skype",                  :default => "",    :null => false
+    t.string   "linkedin",               :default => "",    :null => false
+    t.string   "twitter",                :default => "",    :null => false
     t.string   "authentication_token"
-    t.boolean  "dark_scheme",                           :default => false, :null => false
-    t.integer  "theme_id",                              :default => 1,     :null => false
+    t.boolean  "dark_scheme",            :default => false, :null => false
+    t.integer  "theme_id",               :default => 1,     :null => false
     t.string   "bio"
-    t.boolean  "blocked",                               :default => false, :null => false
-    t.integer  "failed_attempts",                       :default => 0
+    t.boolean  "blocked",                :default => false, :null => false
+    t.integer  "failed_attempts",        :default => 0
     t.datetime "locked_at"
+    t.string   "provider"
+    t.string   "uid"
   end
 
   add_index "users", ["email"], :name => "index_users_on_email", :unique => true
diff --git a/vendor/assets/images/authbuttons/github_32.png b/vendor/assets/images/authbuttons/github_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..247e52a5f4282110243afa350cd4a13b0154c2a1
GIT binary patch
literal 1931
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
II;Vst0A0+q{r~^~

literal 0
HcmV?d00001

diff --git a/vendor/assets/images/authbuttons/github_64.png b/vendor/assets/images/authbuttons/github_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..fca7bf44652470a58edd12b410613656da95aed3
GIT binary patch
literal 4447
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

literal 0
HcmV?d00001

diff --git a/vendor/assets/images/authbuttons/google_32.png b/vendor/assets/images/authbuttons/google_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..3909e9de93b22e1f3a2e6c264f6289331412a3bb
GIT binary patch
literal 1615
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

literal 0
HcmV?d00001

diff --git a/vendor/assets/images/authbuttons/google_64.png b/vendor/assets/images/authbuttons/google_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..e55f34f1b7d57c52172eb2bab0964037c532629b
GIT binary patch
literal 3446
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

literal 0
HcmV?d00001

diff --git a/vendor/assets/images/authbuttons/twitter_32.png b/vendor/assets/images/authbuttons/twitter_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..daadcffd315f11026cface9d99409997050ab9b9
GIT binary patch
literal 1439
zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}oCO|{#S9FrogmDZn=$tn
z0|SF(iEBhjaDG}zd16s2gJVj5QmTSyZen_BP-<dIW#P$G8wLhe9Zwg>kcwMR!p~;Q
zhKksKKeuQ7jPzM*rkUJo8y$TVG+ftQZS@d;<hRON(B;lA^^&KDrh1D%TJ|6)qjgb7
zScr&rNY2(H*Ft9R+qNZhmdQ)+GskDothRZ6r~3KX-!p!k@G3Y|TmJ0a@t<?6>z<eU
zG5mYqe(UMpyD~Q>Ph5WA!qBE5;n7)x3(a2I5A0p0ES!>cu5F+Cbv0XY?RSxKpDOLP
zPYb&ymZe_*@5kMxF$~7X?@L-5)IM2VwA3b8Ph645`NA!!uRnSXi?W26c?=dtUh6T<
zx}gxO&eOI2<(+kkw$kxYGi<+KdNY&%eZ}m=WBcT!=GU#h6h3oh*zW}~Iu08>7;boP
zZ|=C3{J2*#dqO+wBOap$6~zf0g>z1n`dokW_`!`Yw@voDE9bEbWSRW#Y85!Ol<CXG
z2gUaymzo~D%;duJ*<JYCr45sfq91EKH@yGY@%%?VBaXtxchkL=9)6RvU3S8R7Y@uv
z<(Z5mKFF{v;AWJuHDU7a;XCl>lhvHLds)@G=9X*hPBD>o<-Wno$$07am!3tx&&>Vx
zXzkiH2RBSz_QK=&g%9matnTXW51zhk-ehKYMgQ~k>3NshdzF_y-tlQmQFC5|ftG6Y
z$Ayi*BWLeoZ8$h>j-Z8A!^(@cy0=XX@Ax0sQXHImVO3aE@~L@K+;;`!JbBkJ%|dz0
zfq=W4!vixkd|&7=rkZFdEjKcAW#urAUn)@)vVfOiv#7!B(_5}Ry=yyFNoMvf{uwt!
z9<%fOGGW=VaSz+`|9iL{Yy{f{HXEK|U$DiC_xH}1PM;;#h&+(^n6!Mc2-}CV`KI%8
zciz5migCI5qt5w)<x6*;54?6mz@%Jwcfy6Y`c+RiDP1mQuCiLEvnHrx)3J@({D<<s
zDoqV#WY%jtn{4d$pse<C<6#k%U7xE<-gn1mtGE>Y(mnD{F+({qc(<_r=4GE%&Hf$y
zUOd4hNqgsw5XZ0sGp;>$bLo=wj@_`8<-aYr%lF7A;mcR5!fS5roU}nGFSq+n)ng-J
zg=>FRHWj_ytlWP7trthr4GaGti)TISb-VNF(!G6)CQNakRF!{lS?NLPvX#7<TJKz(
z&K!x`v+?SiS4n%B54=8a!#4FFS7vr&(K?1zGbB|47KEOvX<jz9=ch`GPw3{`E0b8o
zvrZTMIq4ofuevNJ!fpHG-8-!dKHa{bSX#<!@NL&6+i0uOhH{0CU*{Ya2-JDMZq4EA
z#oV^bA8_}-Z@=E>b4%!*>)ONLWn@1n3YZx$)L{8o#xnn(5x;rZzju;HeiWDrSDiWA
z;-}~|->=iaMs1t<Ht7!yWe<<6{9N!WX{|a#x?aq7$);sXm)^GIHd1*qed&#??`luC
zC>hNE^Mk#n?xU5A+->&5SBsWCaeDRCRO#)`)8;EPJA-5o%xSve==9}fO0~tylqD}8
zxV3U~FT8c{M$=|*{w2G9W?g5=4?ch4cZ}}Et+}?GfkN(Ir?e!@4xDN-ar^1a>Yj_s
zHwo)&AC6lxw|B+Hd23HMZtC^$(2BSh6T8R0<i$$yQh|40r(Q^DIXUBq*`j|@Ha>TH
zGOOS1epdFif4kYgU4L%6zc+v7t$k%j$28CDZnX}L4pUyNZEWZF^Xs+$e`@vBg%?j2
z)qfRyd6d)e)R|gKcji#Ol{-|69)@L@Pn27>wR-Dn`?LQGeqFisHak3{cIuoPYV6W4
z!!)W}QdW3%hel~!S|^gB`=HeP^M!3WC)RBGGu799ip!#z?r)xT<hg&5@qQ&W`DBON
z_YeCQ9+(vG6`5*nw;^_2)@tQ-PokY7{t7yrmHWQG;*atH230i;-@an6iwq1544$rj
JF6*2Ung9o5ymbHo

literal 0
HcmV?d00001

diff --git a/vendor/assets/images/authbuttons/twitter_64.png b/vendor/assets/images/authbuttons/twitter_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..68b74530c06b558b6c4848c2637d4caeaf4c969b
GIT binary patch
literal 3384
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
V;mC$h*$fN}44$rjF6*2UngHt=Pv-yt

literal 0
HcmV?d00001

-- 
GitLab