Category Archives: Programming

Fade-in animation at UIView’s drawRect

Although UIView’s animateWithDuration:animations: method is quite useful, if you want a view to animate a drawing code written in drawRect method, you can’t use this method.

CABasicAnimation class is suitable for solving this problem like this.

- (void)drawRect:(CGRect)rect
{
    CABasicAnimation *animation;

    animation = [CABasicAnimation animation];
    [animation setDuration:0.5];

    [[self layer] addAnimation:animation
                        forKey:@"contents"];

    // drawing code
}

Reference

How to use Xcode 3 color themes in Xcode 4

I’m using either MyBlackboard (In Japanese) or Railscasts color themes in Xcode 3, these color themes, however, couldn’t be used in Xcode 4.

I want to convert 3’s xccolortheme files into 4’s dvtcolortheme files, and found the just script which converted it.
mrevilme’s gist: 488120 — Gist

The usage of this tiny python script is very simple like the following command.

$ xcode3_theme_to_xcode4.py MyBlackBoard.xcolortheme

This step is very quick, and finally, I moved the dvtcolortheme file to the directory.

mkdir -p ~/Library/Developer/Xcode/UserData/FontAndColorThemes/
mv MyBlackBoard.dvtcolortheme ~/Library/Developer/Xcode/UserData/FontAndColorThemes/

If you’ve already started Xcode, restart it and you’ll find the theme at the preference of Xcode.

References

How to create OAuth / xAuth Service Provider in Ruby on Rails with devise

At previous entiry I wrote a sample how to support xAuth in Ruby Application.

In this entry, I write how to create the OAuth/xAuth Service Provider in Ruby on Rails project which uses devise plugin for authentication.

OAuth support when you use devise plugin

Installation

First of all, I’m about to write the way of supporting OAuth using OAuth plugin.
pelle/oauth-plugin – GitHub

OAuth plugin supports Rails 3 after version 0.4.0.pre1, and add Gemfile the following line.

gem "oauth-plugin", ">=0.4.0.pre1"

The installation tutorials are written in the github plugin page.

devise plugin support

In addition, to use OAuth plugin in the project which utilize devise, you need to support two methods “login_required” and “logged_in?” Devise uses such helper methods as “authenticate_#{model_name}” and “#{model_name}_signed_in?”, I wrote two helper methods.

[lib/lindoc/oauth_helpers.rb]

module Lindoc
  module OauthHelpers
    def self.included(recipient)
      recipient.extend(ClassMethods)
      recipient.class_eval do
        include InstanceMethods
      end
    end

    module InstanceMethods
      def login_required
        authenticate_user!
      end

      def logged_in?
        user_signed_in?
      end
    end
  end
end

At the controllers associated with OAuth, add this helper methods like the this.

[$RAILS_ROOT/app/oauth_clients_controller.rb]

class OauthClientsController < ApplicationController
  include Lindoc::OauthHelpers
  ...
end

[$RAILS_ROOT/app/oauth_controller.rb]

require 'oauth/controllers/provider_controller'

class OauthController < ApplicationController
  include OAuth::Controllers::ProviderController
  include Lindoc::OauthHelpers
  ...
end

Since I want to use OAuth / xAuth authentication at API of our service, also added :oauth_required filter.

[app/controllers/api/v1/api_controller.rb]

class Api::V1::ApiController < ApplicationController
  include Lindoc::OauthHelpers

  before_filter :oauth_required
  ...
end

Rails nested parameters support

Client applications often post data in nested parameters like “foo[bar]=baz” to Rails application, but OAuth plugin doesn’t currently support this type of parameters. The reason why OAuth plugin doesn’t, is that this plugin doesn’t consider this type when it calculates a signature the way of which is written in the specification of OAuth, and answers a bad/invalid signature. So, you need to add support by overriding the method which helps calculate it.

This solution is written at Issue page of OAuth plugin.
parameter normalisation issues Nesting parameters causes problems.

[config/initializers/oauth.rb]

module OAuth
  module Helper
    # see https://github.com/pelle/oauth/issues#issue/8
    def normalize(params)
      params.sort.map do |k, values|
        if values.is_a?(Array)
          # multiple values were provided for a single key
          values.sort.collect do |v|
            [escape(k),escape(v)] * "="
          end
        elsif values.is_a?(Hash)
          key = k
          values.sort.collect do |k, v|
            [escape("#{key}[#{k}]"),escape(v)] * "="
          end
        else
          [escape(k),escape(values)] * "="
        end
      end * "&"
    end
  end
end]

xAuth support

xAuth is the authentication method which is used in twitter to support desktop/mobile applications. If you want to know how to use xAuth in your applications, you should read this document.
Using xAuth | dev.twitter.com

client application restriction

Like twitter, I want to restrict client applications which can use xAuth authentication, and I add column to decide it.

[db/migrate/xxx_create_oauth_table.rb]

class CreateOauthTables < ActiveRecord::Migration
  def self.up
    create_table :client_applications do |t|
      ...
      t.boolean :xauth_enabled, :default => false

      t.timestamps
    end
    ...
  end
end

/oauth/access_token signature verification method change

In OAuth 1.0 specification, service provider must verify a signature which consists of both Authentication header and GET or POST parameters called “Signature Base String”, and signed by both Consumer Secret and Access Token Secret. This verification step is implemented as filter “two_legged” or “oauth10_request_token” in OAuth plugin, OAuth::Controllers::ProviderController.

[oauth-plugin/lib/oauth/controllers/provider_controller.rb]

module OAuth
  module Controllers
   
    module ProviderController
      def self.included(controller)
        controller.class_eval do
          ...
          oauthenticate :strategies => :two_legged, :interactive => false, :only => [:request_token]
          oauthenticate :strategies => :oauth10_request_token, :interactive => false, :only => [:access_token]
          ...

The simplified difference of these two methods is to use or not to use request token. You need to change signature verification method of /oauth/access_token when you request Access Token by xAuth, because unlike OAuth clients, xAuth clients don’t have request token.

For that reason, to support xAuth, if request has “x_auth_mode=client_auth” in POST parametes which indicate client applications want to authenticate by xAuth, “two_legged” filter should be applied. I used “alias_method_chain” to seperate xAuth and OAuth authentication.

[config/initializers/oauth.rb]

module OAuth
  module Controllers
    module ApplicationControllerMethods
      class Authenticator
        def oauth10_request_token_with_xauth
          if params[:x_auth_mode] == 'client_auth'
            # xAuth authentication
            two_legged
          else
            # OAuth authentication
            oauth10_request_token_without_xauth
          end
        end

        alias_method_chain :oauth10_request_token, :xauth
      end
    end
  end
end

/oauth/access_token user verification

In /oauth/access_token request, you also verify the user using his username and password. If there is a “x_auth_mode=client_auth” POST parameter in request, verify the user and response Access Token.

[$RAILS_ROOT/app/oauth_controller.rb]

require 'oauth/controllers/provider_controller'

class OauthController < ApplicationController
  include OAuth::Controllers::ProviderController
  include Lindoc::OauthHelpers
  ....

  private
  def access_token_with_xauth
    # To use custom failure response with devise, you need the following line.
    # see https://github.com/plataformatec/devise/wiki/How-To:-Provide-a-custom-failure-response-with-Warden
    warden.custom_failure!

    if params[:x_auth_mode] == 'client_auth'
      render_unauthorized = Proc.new do
        render :nothing => true, :status => 401
      end

      # We support screen name and email to login
      user = User.find_for_database_authentication({ :screen_name_or_email => params[:x_auth_username] })
      if user &&
        user.valid_password?(params[:x_auth_password]) &&
        current_client_application.xauth_enabled

        @token = AccessToken.where(:user_id.eq => user,
                                   :client_application_id.eq => current_client_application,
                                   :invalidated_at.eq => nil).limit(1).first
        @token = AccessToken.create(:user => user, :client_application => current_client_application) if @token.blank?

        if @token
          render :text => @token.to_query
        else
          render_unauthorized.call
        end
      else
        render_unauthorized.call
      end
    else
      access_token_without_xauth
    end
  end

  alias_method_chain :access_token, :xauth
end

References

How to support OAuth in ASIHTTPRequest

ASIHTTPRequest is a brilliant library, when you want to handle HTTP requests.
At this time, however, this library doesn’t support OAuth.

You can support it easily with OAuthCore library which is developed by atebits who is the developer of Tweetie a.k.a. Twitter for Mac/iPhone.
atebits / OAuthCore / overview – Bitbucket

A sample code is following.

#import "OAuthCore.h"

NSString * const CONSUMER_KEY = @"YOUR_CONSUMER_KEY";
NSString * const CONSUMER_SECRET = @"YOUR_CONSUMER_SECRET";
NSString * const ACCESS_TOKEN = @"YOUR_ACCESS_TOKEN";
NSString * const ACCESS_TOKEN_SECRET = @"YOUR_ACCESS_TOKEN_SECRET";

NSURL *URL = [NSURL URLWithString:@"http://example.com/api"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:URL];

[request setPostValue:@"test" forKey:@"test_value"];
[request buildPostBody];

NSString *header = OAuthorizationHeader([request url],
                                        [request requestMethod],
                                        [request postBody],
                                        CONSUMER_KEY,
                                        CONSUMER_SECRET,
                                        ACCESS_TOKEN,
                                        ACCESS_TOKEN_SECRET);


[request addRequestHeader:@"Authorization" value:header];

If you want to get “Access Token” and “Access Toke Secret”, such as you authorize with xAuth, you should set both ACCESS_TOKEN and ACCESS_TOKEN_SECRET, not nil but @””.

References

xAuth Consumer Sample using Ruby

I’m developing OAuth/xAuth Service Provider using OAuth / OAuth-Plugin.
pelle/oauth-plugin – GitHub

Since OAuth-Plugin doesn’t support xAuth, I decided to create a program to support it.
I’ll write an entry about xAuth support, before that, I write this entry about sample of using xAuth in Ruby.

You need to install Ruby OAuth Gem.

require 'oauth'

CONSUMER_KEY = 'Your-Consumer-Key'
CONSUMER_SECRET = 'Your-Consumer-Secret'

def get_access_token
  consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => 'Your-OAUTH-Provider-URL')
  access_token = consumer.get_access_token(nil, {}, { :x_auth_mode => 'client_auth', :x_auth_username => 'Your-User-Name', :x_auth_password => 'Your-Password' })

  [access_token.token, access_token.secret]
end

def access_api(token, secret)
  consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => 'Your-OAuth-Provider-URL')
  access_token = OAuth::AccessToken.new(consumer, token, secret)

  access_token.get('Your-API-URL')
end

token, secret = get_access_token
p "token: #{token}"
p "secret: #{secret}"

response = access_api(token, secret)
p response

References

Find Skype Chat ID with rb-skypemac

Each Skype chat has an unique chat ID like “#hogehoge/XXXXXXXXXXXXXXXX”.
This ID has very important role when you handle Skype with another programs/scripts like rb-skypemac (Ruby Gem).
rb skypemac

There is a very simple method to find IDs with rb-skypemac.

irb > require 'rb-skypemac'
 => true
irb > SkypeMac::Skype.send_(:command => 'SEARCH RECENTCHATS')
 => "CHATS #hogehoge/XXXXXXXXXXXXXXXX, #piyopiyo/XXXXXXXXXXXXXXXX"

After this command, you should select the appropriate ID.

Installing Chef Server with RVM

Chef is a systems integration framework, built to bring the benefits of configuration management to your entire infrastructure.

The tutorials of install, and basic usage are written here.

I want to use it with RVM’s Ruby on Ubuntu Server 10.10.

RVM Installation

I use RVM with system wide install, whose instruction is here.
RVM: Ruby Version Manager – Installing RVM System Wide

chef-server# apt-get install curl git-core
chef-server# bash < <( curl -L http://bit.ly/rvm-install-system-wide )

Ruby 1.9.2 Installation

After installed RVM, you need to install Ruby 1.9.2 with RVM.

chef-server# apt-get install build-essential libssl-dev zlib1g-dev libreadline-dev
chef-server# source '/usr/local/lib/rvm'
chef-server# rvm install 1.9.2 -C --with-readline-dir=/usr --with-openssl-dir=/usr --with-zlib-dir=/usr

Bootstrap Chef-Server Installation

Now, you are prepared for installing Chef.
There is a nice tutorial for bootstrap installation of Chef-Server.
Bootstrap Chef RubyGems Installation – Chef – Opscode Open Source Wiki

Chef Solo Attributes Configuration

chef-server$ vi ~/chef.json
{
  "chef": {
    "server_url": "http://localhost:4000"
  },
  "run_list": [ "recipe[chef::bootstrap_server]" ]
}

Temporary PATH configuration

Before using Rubygems, you should set PATH configuration temporary, because I want to use chef to set all configurations.

chef-server# source '/usr/local/lib/rvm'
chef-server# rvm use 1.9.2
chef-server# gem install chef

Other Necessary Packages Installation

chef-server# apt-get install wget ssl-cert
chef-server# gem install chef

Chef Solo Installation

chef-server# mkdir -p /etc/chef
chef-server# vi /etc/chef/solo.rb

The content of “/etc/chef/solo.rb” is following.

file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"

You can use `chef-solo` command to install chef-server.

chef-server# chef-solo -c /etc/chef/solo.rb -j ~/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz

chef-client, chef-server, chef-solr, chef-solr-indexer run script PATH configuration

Having finished installing, you will notice that chef-* fail to start on looking at logs “/etc/sv/chef-*/logs/main/current”.
The reason of this failure is that Ruby and Gems PATH are not set correctly, so you should set them like this.

chef-server# vi /etc/sv/{chef-client, chef-server, chef-solr, chef-solr-indexer}/run
- PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin
---
+ export PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/rvm/gems/ruby-1.9.2-p0/bin
+ export GEM_HOME=/usr/local/rvm/gems/ruby-1.9.2-p0
+ export GEM_PATH=/usr/local/rvm/gems/ruby-1.9.2-p0

These chef processes are watched by “runit”, and after you rewrite them, all processes will start correctly.
If you want to start/stop/restart manually, use `/etc/init.d/chef-* {start/stop/restart}` command.

要は、PATH の設定だけちゃんとやっておけば RVM でインストールした Ruby でも Chef はインストールできますよということです。

References

Steak で RESTful API の受け入れテストを書く

Steak は Ruby 製の受け入れテストのためのフレームワークです。
cavalle/steak – GitHub

Github にある説明を読んでいただくとわかると思いますが Steak ではテストは RSpec のように書くことができます。
同様のツールに Cucumber もありますが、Cucumber は英語や日本語で書かなければならないので、自分の中でどうもしっくりしませんでした。
そのため、自分にとっては Steak のようにかけた方がずっと書きやすいです。
ということで、これからは Steak を使って受け入れテストを書いていこうと思っています。

そんな Steak ですが、RESTful API のテストもしたいです。
どうも Steak の裏で動いている Capybara というテストフレームワークは、 visit ‘/’ のように GET することはできるのですが、 POST PUT DELETE というような RESTful API をテストする上ではそれだけでは足りません。

以下のような方法で、POST 等のメソッドを呼び出すことが可能なようです。

$RAILS_ROOT/spec/acceptance/support/helper.rb

module HelperMethods
  def setup_driver
    @driver = Capybara.current_session.driver
  end

  def post(path, params = {})
    @driver.process :post, path, params
  end

  def put(path, params = {})
    @driver.process :put, path, params
  end

  def delete(path, params = {})
    @driver.process :delete, path, params
  end
end

$RAILS_ROOT/spec/acceptance/api/articles_spec.rb

require File.dirname(__FILE__) + '/../acceptance_helper'

feature "Articles" do
  background do
    setup_driver
  end

  scenario 'update article' do
    params = { :article => {} }
    params[:article][:title] = 'foo'
    put('/api/articles/1.json', params)
  end
end

@driver.status_code とかでレスポンスのステータスコードが取得できたりします。
ほかの情報はここなどを読むとよいでしょう。
Class: Capybara::Driver::Base

参考文献

JRuby で ActiveRecord 3 をちょこっと試す

JRuby で ActiveRecord を試してみたいと思いました。
JRuby は RVM で 1.5.6 がインストールされています。

$ echo "rvm jruby" >> .rvmrc

こんな感じで .rvmrc を使用して JRuby 環境になっているものとします。

まずは ActiveRecord のインストール。

$ gem install activerecord
Successfully installed activesupport-3.0.3
Successfully installed builder-2.1.2
Successfully installed i18n-0.5.0
Successfully installed activemodel-3.0.3
Successfully installed arel-2.0.6
Successfully installed tzinfo-0.3.23
Successfully installed activerecord-3.0.3
7 gems installed (...)

MySQL を使いたいので、普通の Ruby っぽく

$ gem install mysql

とやってみましたが、ダメでした。

$ gem install activerecord-jdbcmysql-adapter
Successfully installed activerecord-jdbc-adapter-1.0.3-java
Successfully installed jdbc-mysql-5.0.4
Successfully installed activerecord-jdbcmysql-adapter-1.0.3-java
3 gems installed (...)

こういうのを使う必要があるらしいです。
establish_connection のやり方も若干違います。

require 'rubygems'
require 'active_record'

ActiveRecord::Base.establish_connection(
  :adapter => 'jdbcmysql',
  :host => 'localhost',
  :username => 'root',
  :password => '',
  :database => 'piyopiyo_development',
  :pool => 5
)

あとは同じみたいです。

参考文献

cURL で GET/POST/PUT/DELETE

-X オプションでメソッド名 GET/POST/PUT/DELETE を指定すればよい。

curl -X PUT -d 'example[foo]=bar' -d 'example[jane]=doe' http://example.com/api/1/example/1.json

Basic 認証をしたいときにはさらに –basic –user user:password をつける。

curl --basic --user user:password -X PUT -d 'example[foo]=bar' -d 'example[jane]=doe' http://example.com/api/1/example/1.json

API を開発したいときには cURL様々!!!

参考文献