├── Gemfile
├── README.rdoc
├── app
├── controllers
│ ├── oauth_clients_controller.rb
│ └── oauth_controller.rb
├── models
│ ├── access_token.rb
│ ├── client_application.rb
│ ├── oauth2_token.rb
│ ├── oauth2_verifier.rb
│ ├── oauth_nonce.rb
│ ├── oauth_token.rb
│ └── request_token.rb
└── views
│ ├── oauth
│ ├── authorize.html.erb
│ ├── authorize_failure.html.erb
│ ├── authorize_success.html.erb
│ └── oauth2_authorize.html.erb
│ └── oauth_clients
│ ├── _form.html.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ ├── new.html.erb
│ └── show.html.erb
├── assets
└── stylesheets
│ └── application.css
├── config
├── locales
│ ├── en.yml
│ ├── ja.yml
│ └── zh.yml
└── routes.rb
├── db
└── migrate
│ └── 001_create_oauth_tables.rb
├── init.rb
├── lib
└── oauth_provider_user_patch.rb
└── test
├── fixtures
├── client_applications.yml
├── oauth_nonces.yml
└── oauth_tokens.yml
├── test_helper.rb
└── unit
├── client_application_test.rb
├── oauth_nonce_test.rb
└── oauth_token_test.rb
/Gemfile:
--------------------------------------------------------------------------------
1 | gem "oauth-plugin", "~> 0.5.1"
2 |
--------------------------------------------------------------------------------
/README.rdoc:
--------------------------------------------------------------------------------
1 | = Redmine OAuth Provider
2 |
3 | == Requirements
4 |
5 | Redmine 2.3 or later
6 |
7 | == Installation
8 |
9 | Type below commands:
10 |
11 | $ cd $RAILS_ROOT/plugins
12 | $ git clone git://github.com/suer/redmine_oauth_provider.git
13 |
14 | Create database tables:
15 | rake redmine:plugins:migrate RAILS_ENV=production
16 |
17 | Then, restart your Redmine.
18 |
19 | == Manage your client applications
20 |
21 | Access to
22 |
23 | http://your.redmine.host/oauth_clients/
24 |
25 | And register your applications.
26 |
27 | == OAuth URL
28 |
29 | * Request Token URL:
30 |
31 | http://your.redmine.host/oauth/request_token
32 |
33 | * Access Token URL:
34 |
35 | http://your.redmine.host/oauth/access_token
36 |
37 | * Authorize URL:
38 |
39 | http://your.redmine.host/oauth/authorize
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/controllers/oauth_clients_controller.rb:
--------------------------------------------------------------------------------
1 | class OauthClientsController < ApplicationController
2 | unloadable
3 |
4 | before_filter :get_user
5 | before_filter :get_client_application, :only => [:show, :edit, :update, :destroy]
6 |
7 | def index
8 | @client_applications = @user.client_applications
9 | @tokens = @user.tokens.where('oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null')
10 | end
11 |
12 | def new
13 | @client_application = ClientApplication.new
14 | end
15 |
16 | def create
17 | @client_application = @user.client_applications.build(params[:client_application])
18 | if @client_application.save
19 | flash[:notice] = l("Registered the information successfully")
20 | redirect_to :action => "show", :id => @client_application.id
21 | else
22 | render :action => "new"
23 | end
24 | end
25 |
26 | def show
27 | end
28 |
29 | def edit
30 | end
31 |
32 | def update
33 | if @client_application.update_attributes(params[:client_application])
34 | flash[:notice] = l("Updated the client information successfully")
35 | redirect_to :action => "show", :id => @client_application.id
36 | else
37 | render :action => "edit"
38 | end
39 | end
40 |
41 | def destroy
42 | @client_application.destroy
43 | flash[:notice] = l("Destroyed the client application registration")
44 | redirect_to :action => "index"
45 | end
46 |
47 | private
48 |
49 | def get_user
50 | render_403 unless User.current.logged?
51 |
52 | if params[:user_id] && params[:user_id] != User.current.id.to_s
53 | if User.current.admin?
54 | @user = User.find(params[:user_id])
55 | else
56 | render_403
57 | end
58 | else
59 | @user = User.current
60 | end
61 | end
62 |
63 | def get_client_application
64 | unless @client_application = @user.client_applications.find(params[:id])
65 | flash.now[:error] = l("Wrong application id")
66 | raise ActiveRecord::RecordNotFound
67 | end
68 | end
69 | end
70 |
--------------------------------------------------------------------------------
/app/controllers/oauth_controller.rb:
--------------------------------------------------------------------------------
1 | require 'oauth/controllers/provider_controller'
2 | class OauthController < ApplicationController
3 | unloadable
4 | skip_filter :check_if_login_required
5 | include OAuth::Controllers::ProviderController
6 |
7 | before_filter :login_or_oauth_required, :only => [:user_info]
8 |
9 | def logged_in?
10 | User.current.logged?
11 | end
12 |
13 | def login_required
14 | raise Unauthorized unless User.current.logged?
15 | end
16 |
17 | def user_info
18 | user_hash = { :user => {} }
19 | user = User.find(session[:user_id])
20 | if user
21 | hash = user.attributes
22 | hash.delete(:hashed_password)
23 | hash.delete(:salt)
24 | hash.merge!(:mail => user.mail)
25 | user_hash = { :user => hash }
26 | end
27 | respond_to do |format|
28 | format.json { render :json => user_hash }
29 | end
30 | end
31 |
32 | def current_user
33 | User.find(session[:user_id])
34 | end
35 |
36 | def current_user=(user)
37 | start_user_session(user)
38 | end
39 |
40 | def authorize_with_allow
41 | params[:authorize] = '1' if params[:allow]
42 | authorize_without_allow
43 | end
44 | alias_method_chain :authorize, :allow
45 | end
46 |
--------------------------------------------------------------------------------
/app/models/access_token.rb:
--------------------------------------------------------------------------------
1 | class AccessToken < OauthToken
2 | unloadable
3 |
4 | validates_presence_of :user, :secret
5 | before_create :set_authorized_at
6 | attr_accessible :user
7 |
8 | # Implement this to return a hash or array of the capabilities the access token has
9 | # This is particularly useful if you have implemented user defined permissions.
10 | # def capabilities
11 | # {:invalidate=>"/oauth/invalidate",:capabilities=>"/oauth/capabilities"}
12 | # end
13 |
14 | protected
15 |
16 | def set_authorized_at
17 | self.authorized_at = Time.now
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/app/models/client_application.rb:
--------------------------------------------------------------------------------
1 | require 'oauth'
2 | class ClientApplication < ActiveRecord::Base
3 | unloadable
4 |
5 | belongs_to :user
6 | has_many :tokens, :class_name => "OauthToken"
7 | has_many :access_tokens
8 | has_many :oauth2_verifiers
9 | has_many :oauth_tokens
10 | validates_presence_of :name, :url, :key, :secret
11 | validates_uniqueness_of :key
12 | before_validation :generate_keys, :on => :create
13 | attr_accessible :name, :url, :callback_url, :support_url
14 |
15 | validates_format_of :url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i
16 | validates_format_of :support_url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
17 | validates_format_of :callback_url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
18 |
19 | attr_accessor :token_callback_url
20 |
21 | def self.find_token(token_key)
22 | token = OauthToken.find_by_token(token_key, :include => :client_application)
23 | if token && token.authorized?
24 | token
25 | else
26 | nil
27 | end
28 | end
29 |
30 | def self.verify_request(request, options = {}, &block)
31 | begin
32 | signature = OAuth::Signature.build(request, options, &block)
33 | return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
34 | value = signature.verify
35 | value
36 | rescue OAuth::Signature::UnknownSignatureMethod => e
37 | false
38 | end
39 | end
40 |
41 | def oauth_server
42 | @oauth_server ||= OAuth::Server.new("http://your.site")
43 | end
44 |
45 | def credentials
46 | @oauth_client ||= OAuth::Consumer.new(key, secret)
47 | end
48 |
49 | # If your application requires passing in extra parameters handle it here
50 | def create_request_token(params={})
51 | RequestToken.create :client_application => self, :callback_url=>self.token_callback_url
52 | end
53 |
54 | protected
55 |
56 | def generate_keys
57 | self.key = OAuth::Helper.generate_key(40)[0,40]
58 | self.secret = OAuth::Helper.generate_key(40)[0,40]
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/app/models/oauth2_token.rb:
--------------------------------------------------------------------------------
1 | class Oauth2Token < AccessToken
2 | unloadable
3 |
4 | attr_accessor :state
5 | def as_json(options={})
6 | d = {:access_token=>token, :token_type => 'bearer'}
7 | d[:expires_in] = expires_in if expires_at
8 | d
9 | end
10 |
11 | def to_query
12 | q = "access_token=#{token}&token_type=bearer"
13 | q << "&state=#{URI.escape(state)}" if @state
14 | q << "&expires_in=#{expires_in}" if expires_at
15 | q << "&scope=#{URI.escape(scope)}" if scope
16 | q
17 | end
18 |
19 | def expires_in
20 | expires_at.to_i - Time.now.to_i
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/app/models/oauth2_verifier.rb:
--------------------------------------------------------------------------------
1 | class Oauth2Verifier < OauthToken
2 | unloadable
3 |
4 | validates_presence_of :user
5 | attr_accessor :state
6 |
7 | def exchange!(params={})
8 | OauthToken.transaction do
9 | token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
10 | invalidate!
11 | token
12 | end
13 | end
14 |
15 | def code
16 | token
17 | end
18 |
19 | def redirect_url
20 | callback_url
21 | end
22 |
23 | def to_query
24 | q = "code=#{token}"
25 | q << "&state=#{URI.escape(state)}" if @state
26 | q
27 | end
28 |
29 | protected
30 |
31 | def generate_keys
32 | self.token = OAuth::Helper.generate_key(20)[0,20]
33 | self.expires_at = 10.minutes.from_now
34 | self.authorized_at = Time.now
35 | end
36 |
37 | end
38 |
--------------------------------------------------------------------------------
/app/models/oauth_nonce.rb:
--------------------------------------------------------------------------------
1 | # Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
2 | # Thus you can use the same nonce with a different timestamp and viceversa.
3 | class OauthNonce < ActiveRecord::Base
4 | unloadable
5 |
6 | attr_accessible :nonce, :timestamp
7 | validates_presence_of :nonce, :timestamp
8 | validates_uniqueness_of :nonce, :scope => :timestamp
9 |
10 | # Remembers a nonce and it's associated timestamp. It returns false if it has already been used
11 | def self.remember(nonce, timestamp)
12 | oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp)
13 | return false if oauth_nonce.new_record?
14 | oauth_nonce
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/app/models/oauth_token.rb:
--------------------------------------------------------------------------------
1 | class OauthToken < ActiveRecord::Base
2 | unloadable
3 |
4 | belongs_to :client_application
5 | belongs_to :user
6 | validates_uniqueness_of :token
7 | validates_presence_of :client_application, :token
8 | before_validation :generate_keys, :on => :create
9 | attr_accessible :client_application, :callback_url
10 |
11 | def invalidated?
12 | invalidated_at != nil
13 | end
14 |
15 | def invalidate!
16 | update_attribute(:invalidated_at, Time.now)
17 | end
18 |
19 | def authorized?
20 | authorized_at != nil && !invalidated?
21 | end
22 |
23 | def to_query
24 | "oauth_token=#{token}&oauth_token_secret=#{secret}"
25 | end
26 |
27 | protected
28 |
29 | def generate_keys
30 | self.token = OAuth::Helper.generate_key(40)[0,40]
31 | self.secret = OAuth::Helper.generate_key(40)[0,40]
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/app/models/request_token.rb:
--------------------------------------------------------------------------------
1 | class RequestToken < OauthToken
2 | unloadable
3 |
4 | attr_accessor :provided_oauth_verifier
5 |
6 | def authorize!(user)
7 | return false if authorized?
8 | self.user = user
9 | self.authorized_at = Time.now
10 | self.verifier=OAuth::Helper.generate_key(20)[0,20] unless oauth10?
11 | self.save
12 | end
13 |
14 | def exchange!
15 | return false unless authorized?
16 | return false unless oauth10? || verifier==provided_oauth_verifier
17 |
18 | RequestToken.transaction do
19 | access_token = AccessToken.create(:user => user, :client_application => client_application)
20 | invalidate!
21 | access_token
22 | end
23 | end
24 |
25 | def to_query
26 | if oauth10?
27 | super
28 | else
29 | "#{super}&oauth_callback_confirmed=true"
30 | end
31 | end
32 |
33 | def oob?
34 | callback_url.nil? || callback_url.downcase == 'oob'
35 | end
36 |
37 | def oauth10?
38 | (defined? OAUTH_10_SUPPORT) && OAUTH_10_SUPPORT && self.callback_url.blank?
39 | end
40 |
41 | end
42 |
--------------------------------------------------------------------------------
/app/views/oauth/authorize.html.erb:
--------------------------------------------------------------------------------
1 |
<%= l(:oauth_authorize_tilte) %>
2 | <%= l(:oauth_authorize_comment) %>
3 |
4 | <%= link_to(@token.client_application.name, @token.client_application.url) %>
5 | (<%= link_to(@token.client_application.url, @token.client_application.url) %>)
6 |
7 | <%= form_tag authorize_url do %>
8 | <%= hidden_field_tag "oauth_token", @token.token %>
9 | <%- if params[:oauth_callback] -%>
10 | <%= hidden_field_tag "oauth_callback", params[:oauth_callback] %>
11 | <%- end -%>
12 |
13 | <%= submit_tag(l(:oauth_allow), :name => :allow, :autofocus => true) %>
14 | <%= submit_tag(l(:oauth_deny), :name => :deny) %>
15 |
16 | <% end %>
17 |
--------------------------------------------------------------------------------
/app/views/oauth/authorize_failure.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:oauth_deny_message) %>
2 |
--------------------------------------------------------------------------------
/app/views/oauth/authorize_success.html.erb:
--------------------------------------------------------------------------------
1 | You have allowed this request
--------------------------------------------------------------------------------
/app/views/oauth/oauth2_authorize.html.erb:
--------------------------------------------------------------------------------
1 | Authorize access to your account
2 | Would you like to authorize <%= link_to @token.client_application.name,@token.client_application.url %> (<%= link_to @token.client_application.url,@token.client_application.url %>) to access your account?
3 | <% form_tag authorize_url do %>
4 | <%= hidden_field_tag "response_type", params[:response_type]%>
5 | <%= hidden_field_tag "client_id", params[:client_id]%>
6 | <%= hidden_field_tag "redirect_uri", params[:redirect_uri]%>
7 | <%= hidden_field_tag "state", params[:state]%>
8 | <%= hidden_field_tag "scope", params[:scope]%>
9 |
10 |
11 | <%= check_box_tag 'authorize' %> authorize access
12 |
13 |
14 | <%= submit_tag %>
15 |
16 | <% end %>
17 |
--------------------------------------------------------------------------------
/app/views/oauth_clients/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= error_messages_for @client_application %>
2 |
3 |
4 | <%= l(:field_name) %>*
5 | <%= f.text_field :name %>
6 |
7 |
8 | <%= l(:oauth_main_application_url) %>*
9 | <%= f.text_field :url %>
10 |
11 |
12 | <%= l(:oauth_callback_url) %>*
13 | <%= f.text_field :callback_url %>
14 |
15 |
16 | <%= l(:oauth_support_url) %>
17 | <%= f.text_field :support_url %>
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/views/oauth_clients/edit.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:oauth_edit_application) %>
2 | <%= form_for @client_application, :url => oauth_client_path(@client_application), :html => {:method => :put} do |f| %>
3 | <%= render :partial => "form", :locals => { :f => f } %>
4 | <%= submit_tag l(:button_edit) %>
5 | <% end %>
6 | <%= link_to l(:button_show), oauth_client_path(@client_application) %> |
7 | <%= link_to l(:button_back), oauth_clients_path %>
8 |
--------------------------------------------------------------------------------
/app/views/oauth_clients/index.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:oauth_client_applications) %>
2 | <% unless @client_applications.empty? %>
3 |
4 |
5 |
6 | <%= l(:field_name) %>
7 |
8 |
9 |
10 |
11 |
12 | <% @client_applications.each do |client|%>
13 |
14 | <%= link_to client.name, oauth_client_path(client) %>
15 | <%= link_to l(:button_edit), edit_oauth_client_path(client), :class => "icon icon-edit" %>
16 | <%= link_to l(:button_delete), oauth_client_path(client), :confirm => l(:text_are_you_sure), :method => :delete, :class => "icon icon-del" %>
17 |
18 | <% end %>
19 |
20 |
21 | <% end %>
22 | <%= link_to l(:oauth_register_application), { :action => :new }, :class => "icon icon-add" %>
23 |
24 | <%= stylesheet_link_tag 'application.css', :plugin => 'redmine_oauth_provider' %>
25 |
--------------------------------------------------------------------------------
/app/views/oauth_clients/new.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:oauth_register_application) %>
2 | <%= form_for :client_application, :url => { :action => :create } do |f| %>
3 | <%= render :partial => "form", :locals => { :f => f } %>
4 | <%= submit_tag l(:label_register) %>
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/app/views/oauth_clients/show.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:oauth_detail, :name => @client_application.name) %>
2 |
3 | <%= l(:oauth_consumer_key) %>:
4 | <%=@client_application.key %>
5 |
6 |
7 | <%= l(:oauth_consumer_secret) %>:
8 | <%=@client_application.secret %>
9 |
10 |
11 | <%= l(:oauth_request_token_url) %>
12 | http<%='s' if request.ssl? %>://<%= request.host_with_port %><%= request_token_path %>
13 |
14 |
15 | <%= l(:oauth_access_token_url) %>
16 | http<%='s' if request.ssl? %>://<%= request.host_with_port %><%= access_token_path %>
17 |
18 |
19 | <%= l(:oauth_authorize_url) %>
20 | http<%='s' if request.ssl? %>://<%= request.host_with_port %><%= authorize_path %>
21 |
22 |
23 | <%= link_to l(:button_edit), edit_oauth_client_path(@client_application) %> |
24 | <%= link_to l(:button_back), oauth_clients_path %>
25 |
--------------------------------------------------------------------------------
/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | .list.oauth-clients {
2 | width: 400px;
3 | }
4 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # English strings go here for Rails i18n
2 | en:
3 | field_support_url: Support URL
4 | field_callback_url: Callback URL
5 | oauth_allow: "Allow"
6 | oauth_deny: "Deny"
7 | oauth_authorize_tilte: Authorize access to your account
8 | oauth_authorize_comment: Would you like to authorize a following application to access your account?
9 | oauth_deny_message: You have disallowed this request
10 | oauth_client_applications: OAuth Client Applications
11 | oauth_main_application_url: Main Application URL
12 | oauth_callback_url: Callback URL
13 | oauth_support_url: Support URL
14 | oauth_edit_application: Edit your application
15 | oauth_register_application: Register a new application
16 | oauth_detail: OAuth details for %{name}
17 | oauth_consumer_key: Consumer Key
18 | oauth_consumer_secret: Consumer Secret
19 | oauth_request_token_url: Request Token URL
20 | oauth_access_token_url: Access Token URL
21 | oauth_authorize_url: Authorize URL
22 |
23 | "Registered the information successfully": "Registered the information successfully"
24 | "Updated the client information successfully": "Updated the client information successfully"
25 | "Destroyed the client application registration": "Destroyed the client application registration"
26 | "Wrong application id": "Wrong application id"
27 |
--------------------------------------------------------------------------------
/config/locales/ja.yml:
--------------------------------------------------------------------------------
1 | ja:
2 | field_support_url: サポート URL
3 | field_callback_url: コールバック URL
4 | oauth_allow: 許可
5 | oauth_deny: 許可しない
6 | oauth_authorize_tilte: 認証
7 | oauth_authorize_comment: 以下のアプリケーションへのアクセスを許可しますか?
8 | oauth_deny_message: リクエストは許可されませんでした
9 | oauth_client_applications: OAuth クライアントアプリケーション
10 | oauth_main_application_url: メインアプリケーション URL
11 | oauth_callback_url: コールバック URL
12 | oauth_support_url: サポート URL
13 | oauth_edit_application: アプリケーションの編集
14 | oauth_register_application: アプリケーションの登録
15 | oauth_detail: OAuth %{name} の詳細
16 | oauth_consumer_key: Consumer Key
17 | oauth_consumer_secret: Consumer Secret
18 | oauth_request_token_url: Request Token URL
19 | oauth_access_token_url: Access Token URL
20 | oauth_authorize_url: Authorize URL
21 |
22 | "Registered the information successfully": 登録に成功しました
23 | "Updated the client information successfully": 更新に成功しました
24 | "Destroyed the client application registration": クライアントアプリケーションを削除しました
25 | "Wrong application id": アプリケーション ID が誤っています
26 |
--------------------------------------------------------------------------------
/config/locales/zh.yml:
--------------------------------------------------------------------------------
1 | # English strings go here for Rails i18n
2 | zh:
3 | oauth_allow: "允許"
4 | oauth_deny: "拒絕"
5 | oauth_authorize_tilte: 帳號存取驗證
6 | oauth_authorize_comment: 您是否同意下列應用程式存取您的帳號?
7 | oauth_deny_message: 您已拒絕此要求
8 | oauth_client_applications: OAuth客戶端應用程式
9 | oauth_main_application_url: 應用程式URL
10 | oauth_callback_url: Callback URL
11 | oauth_support_url: Support URL
12 | oauth_edit_application: 編輯
13 | oauth_register_application: 註冊新應用程式
14 | oauth_detail: OAuth %{name} 的詳細內容
15 | oauth_consumer_key: Consumer Key
16 | oauth_consumer_secret: Consumer Secret
17 | oauth_request_token_url: Request Token URL
18 | oauth_access_token_url: Access Token URL
19 | oauth_authorize_url: Authorize URL
20 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | resources :oauth_clients
2 | match 'oauth/test_request', :to => 'oauth#test_request', :as => :test_request, :via => [:get, :post]
3 | match 'oauth/token', :to => 'oauth#token', :as => :token, :via => [:get, :post]
4 | match 'oauth/access_token', :to => 'oauth#access_token', :as => :access_token, :via => [:get, :post]
5 | match 'oauth/request_token', :to => 'oauth#request_token', :as => :request_token, :via => [:get, :post]
6 | match 'oauth/authorize', :to => 'oauth#authorize', :as => :authorize, :via => [:get, :post]
7 | match 'oauth/revoke', :to => 'oauth#revoke', :as => :revoke, :via => [:get, :post]
8 | match 'oauth', :to => 'oauth#index', :as => :oauth, :via => [:get, :post]
9 | match 'oauth/current_user', :to => 'oauth#current_user', :as => :current_user, :via => [:get, :post]
10 | match 'oauth/user_info', :to => 'oauth#user_info', :as => :user_info, :via => [:get, :post]
11 |
--------------------------------------------------------------------------------
/db/migrate/001_create_oauth_tables.rb:
--------------------------------------------------------------------------------
1 | class CreateOauthTables < ActiveRecord::Migration
2 | def self.up
3 | create_table :client_applications do |t|
4 | t.string :name
5 | t.string :url
6 | t.string :support_url
7 | t.string :callback_url
8 | t.string :key, :limit => 40
9 | t.string :secret, :limit => 40
10 | t.integer :user_id
11 |
12 | t.timestamps
13 | end
14 | add_index :client_applications, :key, :unique => true
15 |
16 | create_table :oauth_tokens do |t|
17 | t.integer :user_id
18 | t.string :type, :limit => 20
19 | t.integer :client_application_id
20 | t.string :token, :limit => 40
21 | t.string :secret, :limit => 40
22 | t.string :callback_url
23 | t.string :verifier, :limit => 20
24 | t.string :scope
25 | t.timestamp :authorized_at, :invalidated_at, :expires_at
26 | t.timestamps
27 | end
28 |
29 | add_index :oauth_tokens, :token, :unique => true
30 |
31 | create_table :oauth_nonces do |t|
32 | t.string :nonce
33 | t.integer :timestamp
34 |
35 | t.timestamps
36 | end
37 | add_index :oauth_nonces,[:nonce, :timestamp], :unique => true
38 |
39 | end
40 |
41 | def self.down
42 | drop_table :client_applications
43 | drop_table :oauth_tokens
44 | drop_table :oauth_nonces
45 | end
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | # -*- encoding : utf-8 -*-
2 | require 'redmine'
3 |
4 | module RedmineApp
5 | class Application < Rails::Application
6 | require 'oauth/rack/oauth_filter'
7 | config.middleware.use OAuth::Rack::OAuthFilter
8 | end
9 | end
10 |
11 | # Patches to the Redmine core.
12 | Rails.configuration.to_prepare do
13 | require_dependency 'project'
14 | require_dependency 'user'
15 |
16 | User.send(:include, OauthProviderUserPatch)
17 | end
18 |
19 | Redmine::Plugin.register :redmine_oauth_provider do
20 | name 'Redmine Oauth Provider plugin'
21 | author 'Jana Dvořáková'
22 | description 'Oauth Provider plugin for Redmine'
23 | version '0.0.5'
24 | url 'https://github.com/Virtualmaster/redmine-oauth-provider'
25 | author_url 'http://www.jana4u.net/'
26 | end
27 |
--------------------------------------------------------------------------------
/lib/oauth_provider_user_patch.rb:
--------------------------------------------------------------------------------
1 | # Patches Redmine's Users dynamically.
2 | module OauthProviderUserPatch
3 | def self.included(base) # :nodoc:
4 | base.class_eval do
5 | unloadable
6 |
7 | has_many :client_applications
8 | has_many :tokens, -> {includes(:client_application).order("authorized_at desc")}, {:class_name => "OauthToken"}
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/test/fixtures/client_applications.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 | one:
3 | id: 1
4 | name: MyString
5 | url: http://test.com
6 | support_url: http://test.com/support
7 | callback_url: http://test.com/callback
8 | key: one_key
9 | secret: MyString
10 | user_id: 1
11 | created_at: 2007-11-17 16:56:51
12 | updated_at: 2007-11-17 16:56:51
13 | two:
14 | id: 2
15 | name: MyString
16 | url: http://test.com
17 | support_url: http://test.com/support
18 | callback_url: http://test.com/callback
19 | key: two_key
20 | secret: MyString
21 | user_id: 1
22 | created_at: 2007-11-17 16:56:51
23 | updated_at: 2007-11-17 16:56:51
24 |
--------------------------------------------------------------------------------
/test/fixtures/oauth_nonces.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 | one:
3 | id: 1
4 | nonce: a_nonce
5 | timestamp: 1
6 | created_at: 2007-11-25 17:27:04
7 | updated_at: 2007-11-25 17:27:04
8 | two:
9 | id: 2
10 | nonce: b_nonce
11 | timestamp: 2
12 | created_at: 2007-11-25 17:27:04
13 | updated_at: 2007-11-25 17:27:04
14 |
--------------------------------------------------------------------------------
/test/fixtures/oauth_tokens.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 | one:
3 | id: 1
4 | user_id: 1
5 | client_application_id: 1
6 | token: one
7 | secret: MyString
8 | created_at: 2007-11-19 07:31:46
9 | updated_at: 2007-11-19 07:31:46
10 | two:
11 | id: 2
12 | user_id: 1
13 | client_application_id: 1
14 | token: two
15 | secret: MyString
16 | created_at: 2007-11-19 07:31:46
17 | updated_at: 2007-11-19 07:31:46
18 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Load the normal Rails helper
2 | require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
3 |
4 | # Ensure that we are using the temporary fixture path
5 | Engines::Testing.set_fixture_path
6 |
--------------------------------------------------------------------------------
/test/unit/client_application_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
2 | module OAuthHelpers
3 |
4 | def create_consumer
5 | @consumer=OAuth::Consumer.new(@application.key,@application.secret,
6 | {
7 | :site=>@application.oauth_server.base_url
8 | })
9 | end
10 |
11 | end
12 |
13 | class ClientApplicationTest < ActiveSupport::TestCase
14 | include OAuthHelpers
15 | fixtures :users,:client_applications,:oauth_tokens
16 |
17 | def setup
18 | @application = ClientApplication.create :name => "Agree2", :url => "http://agree2.com", :user => users(:users_001)
19 | create_consumer
20 | end
21 |
22 | def test_should_be_valid
23 | assert @application.valid?
24 | end
25 |
26 |
27 | def test_should_not_have_errors
28 | assert_equal [], @application.errors.full_messages
29 | end
30 |
31 | def test_should_have_key_and_secret
32 | assert_not_nil @application.key
33 | assert_not_nil @application.secret
34 | end
35 |
36 | def test_should_have_credentials
37 | assert_not_nil @application.credentials
38 | assert_equal @application.key, @application.credentials.key
39 | assert_equal @application.secret, @application.credentials.secret
40 | end
41 |
42 | end
--------------------------------------------------------------------------------
/test/unit/oauth_nonce_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
2 | require 'oauth/helper'
3 |
4 | class ClientNoneTest < ActiveSupport::TestCase
5 | include OAuth::Helper
6 |
7 | def setup
8 | @oauth_nonce = OauthNonce.remember(generate_key,Time.now.to_i)
9 | end
10 |
11 | def test_should_be_valid
12 | assert @oauth_nonce.valid?
13 | end
14 |
15 | def test_should_not_have_errors
16 | assert_equal [], @oauth_nonce.errors.full_messages
17 | end
18 |
19 | def test_should_not_be_a_new_record
20 | assert !@oauth_nonce.new_record?
21 | end
22 |
23 | def test_shuold_not_allow_a_second_one_with_the_same_values
24 | assert_equal false, OauthNonce.remember(@oauth_nonce.nonce, @oauth_nonce.timestamp)
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/unit/oauth_token_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
2 |
3 | class RequestTokenTest < ActiveSupport::TestCase
4 |
5 | fixtures :client_applications, :users, :oauth_tokens
6 |
7 | def setup
8 | @token = RequestToken.create :client_application=>client_applications(:one)
9 | end
10 |
11 | def test_should_be_valid
12 | assert @token.valid?
13 | end
14 |
15 | def test_should_not_have_errors
16 | assert @token.errors.empty?
17 | end
18 |
19 | def test_should_have_a_token
20 | assert_not_nil @token.token
21 | end
22 |
23 | def test_should_have_a_secret
24 | assert_not_nil @token.secret
25 | end
26 |
27 | def test_should_not_be_authorized
28 | assert !@token.authorized?
29 | end
30 |
31 | def test_should_not_be_invalidated
32 | assert !@token.invalidated?
33 | end
34 |
35 | def test_should_authorize_request
36 | @token.authorize!(users(:users_001))
37 | assert @token.authorized?
38 | assert_not_nil @token.authorized_at
39 | assert_equal users(:users_001), @token.user
40 | end
41 |
42 | def test_should_not_exchange_without_approval
43 | assert_equal false, @token.exchange!
44 | assert_equal false, @token.invalidated?
45 | end
46 |
47 | def test_should_exchange_with_approval
48 | @token.authorize!(users(:users_001))
49 | @token.provided_oauth_verifier = @token.verifier
50 | @access = @token.exchange!
51 | assert_not_equal false, @access
52 | assert @token.invalidated?
53 |
54 | assert_equal users(:users_001), @access.user
55 | assert @access.authorized?
56 | end
57 |
58 | end
59 |
--------------------------------------------------------------------------------