Tool Integration
Purpose
A tool can be any kind of Web application that is integrated with Breakout. Integrating a tool with Breakout is a good idea if you want to manage a team in Breakout and make the tool available to team members. An integrated tool will apply permissions so that the right team members have access to the tool.
Tools appear as extra tabs that are added to a space. Space owners can optionally add tools to any space.
Tools can also be integrated with Breakout flows. If the tool can output RSS, then the when an tool is added Breakout can pick up those RSS feeds in the related space.
Tools can be Internal - optional Space components that are part of Breakout. Or, they can be External - separate applications with integrated permissions. External tools include Subversion, Trac, Typo, and Apache Webdav. We have some documentation for setting up the Typo Tool and the Trac Tool.
Architecture and Components
This picture shows how an external tool is integrated with simple Web services.
How to add a Tool
First, you have to create a model for the tool that is a subclass of Tool.
A tool model has at least three methods that are called during specific circumstances:
- on_create -- called when a user wants to add the tool to a space. This creates a tool instance and sets up the related data. If the tool is external, it will call a Web service to request a new instance, and get a URL back. It should throw an exception if it fails.
- on_destroy -- called when a user wants to remove a tool from a space. This should destroy the tool instance and related data. If the tool is external, it will call a Web service.
- show -- Called when the user selects the tool tab on the space. This should return a Ruby command that the tool_show action of SpacesController? can execute. It will usually render a template, or redirect to the tool. This is optional, because the base Tool object has a default view.
For instance:
class ExampleTool < Tool
def on_create
end
def on_destroy
end
def show
'render(:action=>"example_view"'
end
end
You should also create create an entry for it in the tools table. You should use the migrations for this purpose.
For instance:
$ ruby script/generate migration AddExampleTool
And now, in db/migrate/XXX_add_example_tool.rb:
class AddExampleTool < ActiveRecord::Migration
def self.up
tool = ExampleTool.new
tool.save!
end
def self.down
ExampleTool.delete_all
end
end
The tools table is used to create a list of available tools which a Space owner can find on the Admin page. When a Space owner decides to instantiate a tool, Breakout will make a new entry in the spaces_tools table, and call the Tool model to create an instance of the tool.
Add an Internal Tool
An internal Tool is a tool that runs inside the Breakout application. It gives the space a new tab with optional features.
Therefore, the only special requirement that should be meet during creationg of an internal tool, is setting embedded field in the database entry, to true. The rest is writing Ruby code in the hooks.
Add an External Tool
An External tool is a separate application that is linked to a Space. External tools are more complicated than internal tools. We usually use Web services communicating with a simple control server to instantiate these external applications.
Add a control plugin
When you add an external tool, you have to write a plugin for the control server. It will work on the remote side, so you can call shell commands etc.
It has three methods, hooks:
- on_create
- on_destroy
- show
Depending on the Tool, they take zero or more parameters.
Unlike the tools, the control plugins are normal classes:
class Example def self.on_create(name, space_tool_id, secret_key) end def self.on_destroy(params) end def self.show(params) end end
Add an external tool plugin
Now you have to write the proper hooks to call the control server from a tool model.
In the existing model, you have to add the following code:
require 'drb'
class ExampleTool < Tool
after_initialize :set_defaults
attr_accessor :control
def set_defaults
self.control = DRbObject.new(nil, 'druby://localhost:8887')
end
...
end
Having this, you can call the remote methods this way:
def on_create(spaces_tool)
self.control.on_create('example')
end
First argument means name of a tool, in this case example, but as mentioned above, you can specify more parameters.
How to access Breakout from and External Tool for permissioning
Because we want the tool users and permissions to match the users and permissions for the related Space, external tools should call Breakout to authenticate the user and get permission information. If the external tool has its own user database, the external tool should add or update a user record in its user database after every successful login. Most applications can be integrated in this way.
Methods
We offer Breakout authorization throught Web Services API, XML-RPC.
To integrate an external tool, you will need to modify the login code. This code should log the user in by making a Web services call to Breakout. It should then create or update a local user that has the appropriate permissions (All, View, or Edit).
To implement single-sign on, the tool authentication should be customized with the following behavior: * Check the user session for the Breakout session cookie, _session_id. If this is present, the user is already logged in. Retrieve account information and permission with getSession. * If the application does authentication with a Web form, redirect to the breakout login page with Get argument redirect_to=<the current URL>. The user will log in and be returned with a session cookie. * If the application does not use authentication with a Web form, collect the username and password, and submit the username and password to getUser to retrieve account information and permission.
There are three methods:
- getUser -- gets a user with a login and a password, returns UserStructs::User.
- getSession -- gets a user with session_id, returns UserStructs::User.
- closeSession -- closes the remote session, returns true or false.
getUser takes four parameters:
- spaces_tool_id -- ID of an entry of a tool for the specific space. Every tool that is instantiated for a space gets an entry in the spaces_tools table. The ID of this entry, and the secret key, should be passed to the external tool on create
- secret_key -- as name describes, secret key used for authorization; it's stored in spaces_tool table
- login -- the user login name
- password -- the user password
getSession takes three parameters:
- spaces_tool_id -- ID of an entry of a tool for the specific space. Every tool that is instantiated for a space gets an entry in the spaces_tools table. The ID of this entry, and the secret key, should be passed to the external tool on create
- secret_key -- as name describes, secret key used for authorization; it's stored in spaces_tool table
- session_id -- ID of the session, usually available in the cookie _session_id
closeSession takes the same parameters as getSession.
The structure UserStructs::User looks the following:
module UserStructs
class User < ActionWebService::Struct
member :name, :string
member :login, :string
member :email, :string
member :permission, :integer
end
end
They can be accessed in any programming languages, but for instance, in Rails it may look like this:
user_api = ActionWebService::Client::XmlRpc.new(UserApi, 'http://localhost:3001/backend/user')
user = user_api.getUser(1, 'top secret', 'maurycy', 'ycyruam')
Obviously before calling this code, you need to copy user_api.rb to app/apis/.
The permission field describes the permissions of the user for the space that is related to the tool. The external application should interpret these values in an appropriate way. It can have four values:
- PERMISSION_NONE = 0
- PERMISSION_VIEW = 1
- PERMISSION_EDIT = 2
- PERMISSION_ALL = 3
In the most cases, you should use session ID to ask Web Services about a user. Breakout saves session ID in the _session_id cookie.
Attachments
- tool_services.JPG (17.3 kB) -
Web services for an external tool
, added by andy on 02/12/06 22:39:06.