Project

General

Profile

Feature #24808 » 0003-Add-OAuth2-provider-capability-using-doorkeeper-gem.patch

Jan from Planio www.plan.io, 2017-01-29 16:23

View differences:

Gemfile
15 15
gem "actionpack-xml_parser"
16 16
gem "roadie-rails"
17 17
gem "mimemagic"
18
gem "doorkeeper", "~>4.2.0"
19
gem "doorkeeper-i18n", "~>4.0.0"
18 20

  
19 21
gem "nokogiri", "~> 1.6.8"
20 22

  
app/controllers/application_controller.rb
112 112
      if (key = api_key_from_request)
113 113
        # Use API key
114 114
        user = User.find_by_api_key(key)
115
      elsif access_token = Doorkeeper.authenticate(request)
116
        if access_token.accessible?
117
          user = User.active.find_by_id(access_token.resource_owner_id)
118
        else
119
          doorkeeper_render_error
120
        end
115 121
      elsif request.authorization.to_s =~ /\ABasic /i
116 122
        # HTTP Basic, either username/password or API key/random
117 123
        authenticate_with_http_basic do |username, password|
app/views/my/account.html.erb
1 1
<div class="contextual">
2 2
<%= additional_emails_link(@user) %>
3 3
<%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %>
4
<%= link_to(t('doorkeeper.applications.index.title'), oauth_authorized_applications_path, :class => 'icon icon-applications') if Setting.rest_api_enabled? %>
4 5
<%= call_hook(:view_my_account_contextual, :user => @user)%>
5 6
</div>
6 7

  
config/initializers/doorkeeper.rb
1
Doorkeeper.configure do
2
  use_refresh_token
3
  reuse_access_token
4
  realm           Redmine::Info.app_name
5
  default_scopes  :public
6

  
7
  resource_owner_authenticator do
8
    if Setting.rest_api_enabled?
9
      User.active.find_by_id(session[:user_id]) || redirect_to(signin_path(:back_url => request.original_url))
10
    else
11
      render(:text => 'Forbidden', :status => 403)
12
    end
13
  end
14

  
15
  admin_authenticator do
16
    if !Setting.rest_api_enabled? || !User.active.where(admin: true).find_by_id(session[:user_id])
17
      render(:text => 'Forbidden', :status => 403)
18
    end
19
  end
20

  
21
end
config/routes.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
Rails.application.routes.draw do
19

  
20
  use_doorkeeper
21

  
22
  root :to => 'welcome#index'
19 23
  root :to => 'welcome#index', :as => 'home'
20 24

  
21 25
  match 'login', :to => 'account#login', :as => 'signin', :via => [:get, :post]
db/migrate/20170107092155_create_doorkeeper_tables.rb
1
class CreateDoorkeeperTables < ActiveRecord::Migration
2
  def change
3
    create_table :oauth_applications do |t|
4
      t.string  :name,         null: false
5
      t.string  :uid,          null: false
6
      t.string  :secret,       null: false
7
      t.text    :redirect_uri, null: false
8
      t.text    :scopes,       null: false
9
      t.timestamps             null: false
10
    end
11

  
12
    add_index :oauth_applications, :uid, unique: true
13

  
14
    create_table :oauth_access_grants do |t|
15
      t.integer  :resource_owner_id, null: false
16
      t.references :application,     null: false
17
      t.string   :token,             null: false
18
      t.integer  :expires_in,        null: false
19
      t.text     :redirect_uri,      null: false
20
      t.datetime :created_at,        null: false
21
      t.datetime :revoked_at
22
      t.text     :scopes
23
    end
24

  
25
    add_index :oauth_access_grants, :token, unique: true
26
    add_foreign_key(
27
      :oauth_access_grants,
28
      :oauth_applications,
29
      column: :application_id
30
    )
31
    add_foreign_key(
32
      :oauth_access_grants,
33
      :users,
34
      column: :resource_owner_id
35
    )
36

  
37
    create_table :oauth_access_tokens do |t|
38
      t.integer  :resource_owner_id
39
      t.references :application
40

  
41
      t.string   :token,                  null: false
42

  
43
      t.string   :refresh_token
44
      t.integer  :expires_in
45
      t.datetime :revoked_at
46
      t.datetime :created_at,             null: false
47
      t.text     :scopes
48

  
49
      t.string   :previous_refresh_token, null: false, default: ""
50
    end
51

  
52
    add_index :oauth_access_tokens, :token, unique: true
53
    add_index :oauth_access_tokens, :resource_owner_id
54
    add_index :oauth_access_tokens, :refresh_token, unique: true
55

  
56
    add_foreign_key(
57
      :oauth_access_tokens,
58
      :oauth_applications,
59
      column: :application_id
60
    )
61
    add_foreign_key(
62
      :oauth_access_tokens,
63
      :users,
64
      column: :resource_owner_id
65
    )
66
  end
67
end
lib/redmine.rb
245 245
            :html => {:class => 'icon icon-server-authentication'}
246 246
  menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true,
247 247
            :html => {:class => 'icon icon-plugins'}
248
  menu.push :applications, {:controller => 'doorkeeper/applications', :action => 'index'}, :last => true,
249
            :if => Proc.new { Setting.rest_api_enabled? },
250
            :caption => :'doorkeeper.layouts.admin.nav.applications',
251
            :html => {:class => 'icon icon-applications'}
248 252
  menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true,
249 253
            :html => {:class => 'icon icon-help'}
250 254
end
public/stylesheets/application.css
1264 1264
.icon-workflows { background-image: url(../images/ticket_go.png); }
1265 1265
.icon-custom-fields { background-image: url(../images/textfield.png); }
1266 1266
.icon-plugins { background-image: url(../images/plugin.png); }
1267
.icon-applications { background-image: url(../images/application_view_tile.png); }
1267 1268
.icon-news { background-image: url(../images/news.png); }
1268 1269
.icon-issue-closed { background-image: url(../images/ticket_checked.png); }
1269 1270
.icon-issue-note { background-image: url(../images/ticket_note.png); }
test/unit/lib/redmine/i18n_test.rb
184 184
  def test_languages_options
185 185
    options = languages_options
186 186
    assert options.is_a?(Array)
187
    assert_equal valid_languages.size, options.size
187
    assert_equal valid_languages.select {|locale| ::I18n.exists?(:general_lang_name, locale)}.size, options.size
188 188
    assert_nil options.detect {|option| !option.is_a?(Array)}
189 189
    assert_nil options.detect {|option| option.size != 2}
190 190
    assert_nil options.detect {|option| !option.first.is_a?(String) || !option.last.is_a?(String)}
......
205 205

  
206 206
  def test_locales_validness
207 207
    lang_files_count = Dir["#{Rails.root}/config/locales/*.yml"].size
208
    assert_equal lang_files_count, valid_languages.size
208
    assert_equal lang_files_count, valid_languages.select {|locale| ::I18n.exists?(:general_lang_name, locale)}.size
209 209
    valid_languages.each do |lang|
210 210
      assert set_language_if_valid(lang)
211 211
    end
(11-11/24)