Permalink
Browse files

Beta oauth support added to the runk

  • Loading branch information...
1 parent 7ca3953 commit 42e166e18681fc3af020c600edae7c1863091ce1 @aitor aitor committed Dec 11, 2008
@@ -0,0 +1,47 @@
+class OauthClientsController < ApplicationController
+ before_filter :login_required
+
+ def index
+ @client_applications=current_user.client_applications
+ @tokens=current_user.tokens.find :all, :conditions=>'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
+ end
+
+ def new
+ @client_application=ClientApplication.new
+ end
+
+ def create
+ @client_application=current_user.client_applications.build(params[:client_application])
+ if @client_application.save
+ flash[:notice]="Registered the information successfully"
+ redirect_to :action=>"show",:id=>@client_application.id
+ else
+ render :action=>"new"
+ end
+ end
+
+ def show
+ @client_application=current_user.client_applications.find(params[:id])
+ end
+
+ def edit
+ @client_application=current_user.client_applications.find(params[:id])
+ end
+
+ def update
+ @client_application=current_user.client_applications.find(params[:id])
+ if @client_application.update_attributes(params[:client_application])
+ flash[:notice]="Updated the client information successfully"
+ redirect_to :action=>"show",:id=>@client_application.id
+ else
+ render :action=>"edit"
+ end
+ end
+
+ def destroy
+ @client_application=current_user.client_applications.find(params[:id])
+ @client_application.destroy
+ flash[:notice]="Destroyed the client application registration"
+ redirect_to :action=>"index"
+ end
+end
@@ -0,0 +1,62 @@
+class OauthController < ApplicationController
+ before_filter :login_required,:except=>[:request_token,:access_token,:test_request]
+ before_filter :login_or_oauth_required,:only=>[:test_request]
+ before_filter :verify_oauth_consumer_signature, :only=>[:request_token]
+ before_filter :verify_oauth_request_token, :only=>[:access_token]
+ # Uncomment the following if you are using restful_open_id_authentication
+ # skip_before_filter :verify_authenticity_token
+
+ def request_token
+ @token=current_client_application.create_request_token
+ if @token
+ render :text=>@token.to_query
+ else
+ render :nothing => true, :status => 401
+ end
+ end
+
+ def access_token
+ @token=current_token.exchange!
+ if @token
+ render :text=>@token.to_query
+ else
+ render :nothing => true, :status => 401
+ end
+ end
+
+ def test_request
+ render :text=>params.collect{|k,v|"#{k}=#{v}"}.join("&")
+ end
+
+ def authorize
+ @token=RequestToken.find_by_token params[:oauth_token]
+ unless @token.invalidated?
+ if request.post?
+ if params[:authorize]=='1'
+ @token.authorize!(current_user)
+ redirect_url=params[:oauth_callback]||@token.client_application.callback_url
+ if redirect_url
+ redirect_to redirect_url+"?oauth_token=#{@token.token}"
+ else
+ render :action=>"authorize_success"
+ end
+ elsif params[:authorize]=="0"
+ @token.invalidate!
+ render :action=>"authorize_failure"
+ end
+ end
+ else
+ render :action=>"authorize_failure"
+ end
+ end
+
+ def revoke
+ @token=current_user.tokens.find_by_token params[:token]
+ if @token
+ @token.invalidate!
+ flash[:notice]="You've revoked the token for #{@token.client_application.name}"
+ end
+ redirect_to oauth_clients_url
+ end
+
+end
@@ -0,0 +1,2 @@
+module OauthClientsHelper
+end
@@ -0,0 +1,2 @@
+module OauthHelper
+end
@@ -0,0 +1,10 @@
+class AccessToken<OauthToken
+ validates_presence_of :user
+ before_create :set_authorized_at
+
+ protected
+
+ def set_authorized_at
+ self.authorized_at=Time.now
+ end
+end
@@ -0,0 +1,51 @@
+require 'oauth'
+class ClientApplication < ActiveRecord::Base
+ belongs_to :user
+ has_many :tokens,:class_name=>"OauthToken"
+ validates_presence_of :name,:url,:key,:secret
+ validates_uniqueness_of :key
+ before_validation_on_create :generate_keys
+
+ def self.find_token(token_key)
+ token=OauthToken.find_by_token(token_key, :include => :client_application)
+ logger.info "Loaded #{token.token} which was authorized by (user_id=#{token.user_id}) on the #{token.authorized_at}"
+ return token if token.authorized?
+ nil
+ end
+
+ def self.verify_request(request, options = {}, &block)
+ begin
+ signature=OAuth::Signature.build(request,options,&block)
+ logger.info "Signature Base String: #{signature.signature_base_string}"
+ logger.info "Consumer: #{signature.send :consumer_key}"
+ logger.info "Token: #{signature.send :token}"
+ return false unless OauthNonce.remember(signature.request.nonce,signature.request.timestamp)
+ value=signature.verify
+ logger.info "Signature verification returned: #{value.to_s}"
+ value
+ rescue OAuth::Signature::UnknownSignatureMethod=>e
+ logger.info "ERROR"+e.to_s
+ false
+ end
+ end
+
+ def oauth_server
+ @oauth_server||=OAuth::Server.new "http://your.site"
+ end
+
+ def credentials
+ @oauth_client||=OAuth::Consumer.new key,secret
+ end
+
+ def create_request_token
+ RequestToken.create :client_application=>self
+ end
+
+ protected
+
+ def generate_keys
+ @oauth_client=oauth_server.generate_consumer_credentials
+ self.key=@oauth_client.key
+ self.secret=@oauth_client.secret
+ end
+end
@@ -0,0 +1,13 @@
+# Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
+# Thus you can use the same nonce with a different timestamp and viceversa.
+class OauthNonce < ActiveRecord::Base
+ validates_presence_of :nonce,:timestamp
+ validates_uniqueness_of :nonce,:scope=>:timestamp
+
+ # Remembers a nonce and it's associated timestamp. It returns false if it has already been used
+ def self.remember(nonce,timestamp)
+ oauth_nonce=OauthNonce.create(:nonce=>nonce,:timestamp=>timestamp)
+ return false if oauth_nonce.new_record?
+ oauth_nonce
+ end
+end
@@ -0,0 +1,32 @@
+class OauthToken < ActiveRecord::Base
+ belongs_to :client_application
+ belongs_to :user
+ validates_uniqueness_of :token
+ validates_presence_of :client_application,:token,:secret
+ before_validation_on_create :generate_keys
+
+ def invalidated?
+ invalidated_at!=nil
+ end
+
+ def invalidate!
+ update_attribute(:invalidated_at,Time.now)
+ end
+
+ def authorized?
+ authorized_at!=nil && !invalidated?
+ end
+
+ def to_query
+ "oauth_token=#{token}&oauth_token_secret=#{secret}"
+ end
+
+ protected
+
+ def generate_keys
+ @oauth_token=client_application.oauth_server.generate_credentials
+ self.token=@oauth_token[0]
+ self.secret=@oauth_token[1]
+ end
+
+end
@@ -0,0 +1,18 @@
+class RequestToken<OauthToken
+
+ def authorize!(user)
+ return false if authorized?
+ self.user=user
+ self.authorized_at=Time.now
+ self.save
+ end
+
+ def exchange!
+ return false unless authorized?
+ RequestToken.transaction do
+ access_token=AccessToken.create(:user=>user,:client_application=>client_application)
+ invalidate!
+ access_token
+ end
+ end
+end
@@ -0,0 +1,40 @@
+# Tog::Oauth provides a simple way to create a consumer for an oauth provider.
+
+module Oauth
+
+ # This method uses Tog::Plugins settings to autoconfigure an oauth consumer for a given service.
+ # So if you want to request info from fireeagle you will have to set at least the following info:
+ #
+ # Tog::Plugins.settings :tog_social, "oauth.fireeagle.key" => "OAUTH_KEY_HERE",
+ # "oauth.fireeagle.secret" => "OAUTH_SECRET_HERE",
+ # "oauth.fireeagle.site" => "https://fireeagle.yahooapis.com",
+ # ==== Attributes
+ #
+ # * <tt>:service</tt> - The service you want to use this consumer for.
+ #
+ def self.consumer(service)
+
+ key = setting_for_service(service, "key")
+ secret = setting_for_service(service, "secret")
+ site = setting_for_service(service, "site")
+
+ OAuth::Consumer.new(key, secret, {:site=>site})
+ end
+
+ protected
+
+ def self.setting_for_service(service, setting)
+ setting_key = "oauth.#{service}.#{setting}"
+ value = Tog::Plugins.settings(:tog_social, setting_key)
+ RAILS_DEFAULT_LOGGER.warn <<-WARNING
+
+ **************************************************************************************************************************************************
+ OAUTH WARNING: #{setting_key} setting is nil and this could potentially create problem in the oauth process.
+ **************************************************************************************************************************************************
+
+ WARNING
+ ) unless value
+ value
+ end
+
+end
View
@@ -15,6 +15,11 @@ class User < ActiveRecord::Base
has_many :moderated_groups, :through => :moderator_memberships,
:conditions => "memberships.state='active' and groups.state='active'", :source => :group
+ # => oauth support
+ has_many :client_applications
+ has_many :tokens, :class_name=>"OauthToken", :order=>"authorized_at desc", :include=>[:client_application]
+ # => oauth support
+
protected
def create_profile
@@ -0,0 +1,14 @@
+<h1>Authorize access to your account</h1>
+<p>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?</p>
+<%form_tag authorize_url do %>
+<%=hidden_field_tag "oauth_token",@token.token%>
+<%-if params[:oauth_callback]-%>
+<%=hidden_field_tag "oauth_callback", params[:oauth_callback]%>
+<%-end-%>
+<p>
+ <%=check_box_tag 'authorize'%> authorize access
+</p>
+<p>
+ <%=submit_tag%>
+</p>
+<%end%>
@@ -0,0 +1 @@
+<h1>You have disallowed this request</h1>
@@ -0,0 +1 @@
+<h1>You have allowed this request</h1>
@@ -0,0 +1,16 @@
+<div class="field">
+ <label for="client_application_name">Name*</label><br/>
+ <%=f.text_field :name%>
+</div>
+<div class="field">
+ <label for="client_application_url">Main Application URL*</label><br/>
+ <%=f.text_field :url%>
+</div>
+<div class="field">
+ <label for="client_application_callback_url">Callback URL*</label><br/>
+ <%=f.text_field :callback_url%>
+</div>
+<div class="field">
+ <label for="client_application_support_url">Support URL</label><br/>
+ <%=f.text_field :support_url%>
+</div>
@@ -0,0 +1,40 @@
+<div class="flash"><%=flash[:notice]%></div>
+<h1>OAuth Client Applications</h1>
+<%unless @tokens.empty?%>
+<p>The following tokens have been issued to applications in your name</p>
+<table>
+ <tr><th>Application</th><th>Issued</th><th>&nbsp;</th></tr>
+ <%@tokens.each do |token|%>
+ <%content_tag_for :tr,token do%>
+ <td><%=link_to token.client_application.name,token.client_application.url%></td>
+ <td><%=token.authorized_at%></td>
+ <td>
+ <%form_tag :controller=>'oauth',:action=>'revoke' do%>
+ <%=hidden_field_tag 'token',token.token%>
+ <%=submit_tag "Revoke!"%>
+ <%end%>
+ </td>
+ <%end%>
+ <%end%>
+
+</table>
+<%end%>
+<h3>Application Developers</h3>
+<%if @client_applications.empty?%>
+ <p>
+ Do you have an application you would like to register for use with us using the <a href="http://oauth.net">OAuth</a> standard?
+ </p>
+ <p>
+ You must register your web application before it can make OAuth requests to this service
+ </p>
+<%else%>
+ <p>
+ You have the following client applications registered:
+ </p>
+ <%@client_applications.each do |client|%>
+ <%div_for client do%>
+ <%=link_to client.name,:action=>:show,:id=>client.id%>
+ <%end%>
+ <%end%>
+<%end%>
+<h3><%=link_to "Register your application",:action=>:new%></h3>
@@ -0,0 +1,5 @@
+<h1>Register a new application</h1>
+<% form_for :client_application, :url => { :action => :create } do |f| %>
+ <%= render :partial => "form", :locals => { :f => f } %>
+ <%= submit_tag "Register" %>
+<% end %>
Oops, something went wrong.

0 comments on commit 42e166e

Please sign in to comment.