Commit 69d81951 authored by Maxwell Salzberg's avatar Maxwell Salzberg
Browse files

wip

parent b55c2ab9
......@@ -66,7 +66,6 @@ gem 'carrierwave', '0.5.8'
gem 'fog'
gem 'fastercsv', '1.5.4', :require => false
gem 'mini_magick', '3.4'
gem 'rest-client', '1.6.7'
# JSON and API
......@@ -136,7 +135,6 @@ gem 'jquery-rails'
gem 'faraday'
gem 'faraday_middleware'
gem 'em-synchrony', '1.0.0', :platforms => :ruby_19
gem 'jasmine', :git => 'git://github.com/pivotal/jasmine-gem.git'
......@@ -148,7 +146,6 @@ group :test do
gem 'capybara', '~> 1.1.2'
gem 'cucumber-rails', '1.3.0', :require => false
gem 'database_cleaner', '0.7.1'
gem 'diaspora-client', :git => 'git://github.com/diaspora/diaspora-client.git'
gem 'timecop'
#"0.1.0", #:path => '~/workspace/diaspora-client'
......
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class ActivityStreams::PhotosController < ApplicationController
class AuthenticationFilter
def initialize(scope = nil)
@scope = scope
end
def filter(controller, &block)
if controller.params[:auth_token]
if controller.current_user
yield
else
controller.fail!
end
else
controller.request.env['oauth2'].authenticate_request! :scope => @scope do |*args|
controller.sign_in controller.request.env['oauth2'].resource_owner
block.call(*args)
end
end
end
end
around_filter AuthenticationFilter.new, :only => :create
skip_before_filter :verify_authenticity_token, :only => :create
respond_to :json
respond_to :html, :only => [:show]
def create
@photo = ActivityStreams::Photo.from_activity(params[:activity])
@photo.author = current_user.person
@photo.public = true
if @photo.save
Rails.logger.info("event=create type=activitystreams_photo")
current_user.add_to_streams(@photo, current_user.aspects)
current_user.dispatch_post(@photo, :url => post_url(@photo))
render :nothing => true, :status => 201
else
render :nothing => true, :status => 422
end
end
def show
@photo = current_user.find_visible_shareable_by_id(Photo, params[:id])
respond_with @photo
end
def fail!
render :nothing => true, :status => 401
end
end
class ApisController < ApplicationController
authenticate_with_oauth
before_filter :set_user_from_oauth
respond_to :json
def me
# debugger
@person = @user.person
render :json => {
:birthday => @person.profile.birthday,
:name => @person.name,
:uid => @user.username
}
end
private
def set_user_from_oauth
@user = request.env['oauth2'].resource_owner
end
end
class AppsController < ApplicationController
def show
@app = 'cubbies'
@posts = ActivityStreams::Photo.where(:public => true).for_a_stream(max_time, 'created_at')
@commenting_disabled = true
@people = []
@people_count = 0
end
end
require File.join(Rails.root, "app", "models", "oauth2_provider_models_activerecord_authorization")
require File.join(Rails.root, "app", "models", "oauth2_provider_models_activerecord_client")
class AuthorizationsController < ApplicationController
include OAuth2::Provider::Rack::AuthorizationCodesSupport
before_filter :authenticate_user!, :except => :token
before_filter :redirect_or_block_invalid_authorization_code_requests, :except => [:token, :index, :destroy]
skip_before_filter :verify_authenticity_token, :only => :token
def new
if params[:uid].present? && params[:uid] != current_user.username
sign_out current_user
redirect_to url_with_prefilled_session_form
else
@requested_scopes = params["scope"].split(',')
@client = oauth2_authorization_request.client
if authorization = current_user.authorizations.where(:client_id => @client.id).first
ac = authorization.authorization_codes.create(:redirect_uri => params[:redirect_uri])
redirect_to "#{params[:redirect_uri]}&code=#{ac.code}"
end
end
end
# When diaspora detects that a user is trying to authorize to an application
# as someone other than the logged in user, we want to log out current_user,
# and prefill the session form with the user that is trying to authorize
def url_with_prefilled_session_form
redirect_url = Addressable::URI.parse(request.url)
query_values = redirect_url.query_values
query_values.delete("uid")
query_values.merge!("username" => params[:uid])
redirect_url.query_values = query_values
redirect_url.to_s
end
def create
if params['confirm']
grant_authorization_code(current_user)
else
deny_authorization_code
end
end
def token
require 'jwt'
signed_string = Base64.decode64(params[:signed_string])
app_url = signed_string.split(';')[0]
if (!params[:type] == 'client_associate' && !app_url)
render :text => "bad request: #{params.inspect}", :status => 403
return
end
begin
packaged_manifest = JSON.parse(RestClient.get("#{app_url}manifest.json").body)
public_key = OpenSSL::PKey::RSA.new(packaged_manifest['public_key'])
manifest = JWT.decode(packaged_manifest['jwt'], public_key)
rescue => e
puts "DIASPORA_CONNECT there was a problem with getting a token for the following diaspora id"
puts "DIASPORA_CONNECT #{app_url}, #{public_key.to_s} #{manifest.to_s}"
raise e
end
message = verify(signed_string, Base64.decode64(params[:signature]), public_key, manifest)
if not (message =='ok')
render :text => message, :status => 403
elsif manifest["application_base_url"].match(/^https?:\/\/(localhost|chubbi\.es|www\.cubbi\.es|cubbi\.es)(:\d+)?\/$/).nil?
# This will only be temporary (less than a month) while we iron out the kinks in Diaspora Connect. Essentially,
# whatever we release people will try to work off of and it sucks to build things on top of non-stable things.
# We also started writing a gem that we'll release (around the same time) that makes becoming a Diaspora enabled
# ruby project a breeze.
render :text => "Domain (#{manifest["application_base_url"]}) currently not authorized for Diaspora OAuth", :status => 403
else
client = OAuth2::Provider.client_class.find_or_create_from_manifest!(manifest, public_key)
json = {:client_id => client.oauth_identifier,
:client_secret => client.oauth_secret,
:expires_in => 0,
:flows_supported => ""}
if params[:code]
code = client.authorization_codes.claim(params[:code],
params[:redirect_uri])
json.merge!(
:access_token => code.access_token,
:refresh_token => code.refresh_token
)
end
render :json => json
end
end
def index
@authorizations = current_user.authorizations
@applications = current_user.applications
end
def destroy
## ID is actually the id of the client
auth = current_user.authorizations.where(:client_id => params[:id]).first
auth.revoke
redirect_to authorizations_path
end
# @param [String] enc_signed_string A Base64 encoded string with app_url;pod_url;time;nonce
# @param [String] sig A Base64 encoded signature of the decoded signed_string with public_key.
# @param [OpenSSL::PKey::RSA] public_key The application's public key to verify sig with.
# @return [String] 'ok' or an error message.
def verify( signed_string, sig, public_key, manifest)
split = signed_string.split(';')
app_url = split[0]
time = split[2]
nonce = split[3]
return 'blank public key' if public_key.n.nil?
return "the app url in the manifest (#{manifest['application_base_url']}) does not match the url passed in the parameters (#{app_url})." if manifest["application_base_url"] != app_url
return 'key too small, use at least 2048 bits' if public_key.n.num_bits < 2048
return "invalid time" unless valid_time?(time)
return 'invalid nonce' unless valid_nonce?(nonce)
return 'invalid signature' unless verify_signature(signed_string, sig, public_key)
'ok'
end
def verify_signature(challenge, signature, public_key)
public_key.verify(OpenSSL::Digest::SHA256.new, signature, challenge)
end
def valid_time?(time)
time.to_i > (Time.now - 5.minutes).to_i
end
def valid_nonce?(nonce)
!OAuth2::Provider.client_class.exists?(:nonce => nonce)
end
def redirect_or_block_invalid_authorization_code_requests
begin
block_invalid_authorization_code_requests
rescue OAuth2::Provider::Rack::InvalidRequest => e
if e.message == "client_id is invalid"
redirect_to params[:redirect_uri]+"&error=invalid_client"
else
raise
end
end
end
end
class TokensController < ApplicationController
before_filter :authenticate_user!
def show
end
end
./../../Gemfile
\ No newline at end of file
./../../Gemfile.lock
\ No newline at end of file
This is a (very very) simple OAuth2 client, designed to work with the Diaspora tests. To get it running, cd to the client folder, then run:
1) bundle install
2) bundle exec rackup
This should start the client on port 9292
Assuming an example server is running (such as the one in examples/rails3-example), visit http://localhost:9292. To read content from the server you'll be asked to login (tomafro/secret) and then authorize the client. Finally some very simple content from the server will be shown.
module Chubbies
require 'active_record'
require 'jwt'
require 'diaspora-client'
require 'haml'
def self.reset_db
`rm -f #{File.expand_path('../chubbies.sqlite3', __FILE__)}`
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "chubbies.sqlite3"
)
ActiveRecord::Schema.define do
create_table :resource_servers do |t|
t.string :client_id, :limit => 40, :null => false
t.string :client_secret, :limit => 40, :null => false
t.string :host, :limit => 127, :null => false
t.timestamps
end
add_index :resource_servers, :host, :unique => true
create_table :access_tokens do |t|
t.integer :user_id, :null => false
t.integer :resource_server_id, :null => false
t.string :access_token, :limit => 40, :null => false
t.string :refresh_token, :limit => 40, :null => false
t.string :uid, :limit => 40, :null => false
t.datetime :expires_at
t.timestamps
end
add_index :access_tokens, :user_id, :unique => true
create_table :users do |t|
t.string :username, :limit => 127
t.timestamps
end
end
end
self.reset_db
class User < ActiveRecord::Base
has_one :access_token, :class_name => "DiasporaClient::AccessToken", :dependent => :destroy
end
DiasporaClient.config do |d|
d.private_key_path = File.dirname(__FILE__) + "/chubbies.private.pem"
d.public_key_path = File.dirname(__FILE__) + "/chubbies.public.pem"
d.test_mode = true
d.application_base_url = "localhost:9292/"
d.manifest_field(:name, "Chubbies")
d.manifest_field(:description, "The best way to chub.")
d.manifest_field(:icon_url, "chubbies.jpeg")
d.manifest_field(:permissions_overview, "Chubbi.es wants to post photos to your stream.")
d.permission(:profile, :read, "Chubbi.es wants to view your profile so that it can show it to other users.")
d.permission(:photos, :write, "Chubbi.es wants to write to your photos to share your findings with your contacts.")
end
class App < DiasporaClient::App
set :views, File.join(File.dirname(__FILE__), 'views')
def current_user
@user = User.first
end
def current_user= user
@user = user
end
def redirect_path
'/callback'
end
def after_oauth_redirect_path
'/account?id=1'
end
def create_account(hash)
hash[:username] = hash.delete(:diaspora_id)
User.create(hash)
end
get '/account' do
if params['id'] && user = User.where(:id => params['id']).first
if user.access_token
begin
@resource_response = user.access_token.token.get("/api/v0/me")
haml :response
rescue OAuth2::Error
"Token invalid"
end
else
"No access token."
end
else
"No user with id #{params['id']}"
end
end
get '/new' do
haml :home
end
get '/manifest.json' do
DiasporaClient.package_manifest
end
get '/reset' do
Chubbies.reset_db
end
post '/register' do
DiasporaClient::ResourceServer.create!(params)
end
get '/user_count' do
User.count.to_s
end
end
end
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA6YpLa9kYE0Uh/9fiXOFs8i64ZMR3Nyw4o7YB/X6V1QV195Co
XoLrayFZqDc1N+WTjKurHISIqXsOjOnpHfrbptXri7qXwMyLDAtgSd+NlTWSnJXJ
lP03VrdoUp+dtfKTakhDwBFNrdB+vCAzPve6+6ZEMQZGF+YZBfq7VEPG4iKZQ34C
3lZIfEZlpZQak5tUNWXS5V9uBxAEi1KgoxdQQR3uEctLfQS/QQZ4SNTNVMJsLm6c
xHVhQ5ekXqtpfjM328T8/B+EU4qv+YC2wlHuwL7ztT6/m5rcVtmeunuQVkQueOEZ
br6S6X4du2+4q1/bkmnAS0f28ZcGlnScOz+XqQIDAQABAoIBAGiZWUh3lpHi7+Rw
I+Gn0azzAgGYATFD7CZe+as5DBC5/mkgcFjMWHbGHCr8dyiO+bQSm3QNZExMYmr4
xUF5PvINdA9ERn3C3zBI1BqiNv6yXPUnHX9Onn+HbAE9nlyExkPfFAEtftYvwOOv
pGQ6fpQBlx9CCRjhJSoJb+fA544WR/ceJr5MdzP87mvuOHFpa1jp1s6YBykiiRmZ
36Qvlh2B19xMmGzwsGMeCKc+PbXYF2C5H9huZfFvs0JqjKWuGY4vOkxxTh7ExcaK
JySA9JaZRPPnVD2vVm1PA5TQbDgGMg8u362v26p5sQ8t5UzOT20zHy2Etiq1WvNt
ZhWnLxECgYEA9q35/t51/8tdpKY0CVeFwlVM9jbO9IP4G4ltNTuvaRuBKsvaeCyw
iXkzDwPcS1jzdzkXT0BYWqhMikdPbzbD51Yj9Am96Rzkn3WvHYgZj5QKw3iaQl3t
f08Y4pCU1Ln8G+D2nMPGEnyrZni4c+j0BxMpW588ILNus4Bg3x++OO0CgYEA8l06
Ab7Wr54LKAZj8fIIJk+mt+0QQ1v9OrMmkQTX0oUahcS6lKDTos8NXfkGhgMeY8HI
x/FNsmKf6WYE/VaYSSZgInW4fjJXW40kf5tbzCKhwVeq81ZuqgI4OmzdR05uM7ST
PTJ4h3OfaWoPArtuFj5TEAHxzCYA2rcLn5FJLi0CgYEAixBVSRt8hjHNns6bs1CF
9aJE+uC3Fx12t39n84SsRKLe1JOLnAgFldqfsC1K+acxydqDi4gIx0Lts160J0xG
cJodNqxvRYWmVUbw68MYNdsNnljVDekJxKWAr+k2Hh6jQ8w0+vdbKHzj26bexWlk
eMCSpjZEnWLKW6NZ+S9Z+5kCgYEA7syWg/PB2kWRXn11aoV8LCtc7GpDFOuFRZoR
DOBFumJ1cIoXAKy5+feihw3/tHlMLyRXrVF/qZztTO29StRQtfp+zFVLU+RMGKOn
66dqumcBE9xKTvrBjPck6cQr/r8za/SnAqxA/80Xq6jZY2rDnF0KQIJ5+RkUzGuA
o1dmUH0CgYEAooU8E4SCgWgnToD4fUpZKqGWsLCRhUhJeEp+S0DMGOMFpzIzjZAt
uwaLmE7tzInR0JbEayJXB5lqjv8Y6PiM3CZ3ihh6WJkJhUNRIh8cTxhrLSQSk7PW
DSSjD2mImTF2VRqjvlYQPHNeeSZUmhdxvezwHBDq1OuRfIpfRZ+7Vwc=
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA6YpLa9kYE0Uh/9fiXOFs8i64ZMR3Nyw4o7YB/X6V1QV195CoXoLr
ayFZqDc1N+WTjKurHISIqXsOjOnpHfrbptXri7qXwMyLDAtgSd+NlTWSnJXJlP03
VrdoUp+dtfKTakhDwBFNrdB+vCAzPve6+6ZEMQZGF+YZBfq7VEPG4iKZQ34C3lZI
fEZlpZQak5tUNWXS5V9uBxAEi1KgoxdQQR3uEctLfQS/QQZ4SNTNVMJsLm6cxHVh
Q5ekXqtpfjM328T8/B+EU4qv+YC2wlHuwL7ztT6/m5rcVtmeunuQVkQueOEZbr6S
6X4du2+4q1/bkmnAS0f28ZcGlnScOz+XqQIDAQAB
-----END RSA PUBLIC KEY-----
require File.dirname(__FILE__) + '/app'
require "bundler/setup"
run Chubbies::App
%html
%head
%body
%form{:action => '/', :id => 'login', :method => 'get'}
%label{:for => 'diaspora_id'}
Diaspora ID
%input{:type=>'text', :id => 'diaspora_id', :name => 'diaspora_id'}
%input{:type => 'submit', :value => "Connect to Diaspora" }
%div
The response from #{@resource_server} at path #{@url}:
%h2
Headers
%pre
=@resource_response.headers.inspect
%h2
Body
%pre
=@resource_response.inspect
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment