login
home|faq|help|terms

Introduction

Preallowed is a restful service implemented in Ruby on Rails. Any resource that is accessible via a browser is also available via programmatic interface in XML format. Ruby on Rails offers a simple elegant way for accessing restful resources called Active Resource (see examples below). Accessing it from Java or any other language capable of accessing resources via http is just as simple (see a Java example).

Initial setup

Although the service is extremely easy to use, it requires some basic configuration.


Registering profile

You have to Register a Profile. It takes only few seconds and is absolutely free.

During the registration process all fields are required. Here is an explanation of the fields meaning:

Client Name -- this is how we keep the users separate from each other. The client name should describe your software and can be something like mycompany.com, or dev.mycompany.com, or mywebsite etc... All the service requests are made within a clients scope. You will need to know the client id to access the service.

User name, password, password confirmation -- you will use this user name and password combination to access resources for your client name. Currently there is only one Client per User, but it might eventually change based on requests we get from you.

Email -- we only need it to communicate back to you about service alerts and notifications, so please make sure to provide existing email address.

Once the profile is registered, you can login and create your subjects, roles, resources. We expect that the subject most of the times will be created programmatically, while the roles and resources most likely will be configured through preallowed.com interface (this is just a suggested use of our service based on our assessment and common sense, but we leave it totally up to the user -- you can create subjects, roles and resources programmatically from your application or through the preallowed.com admin interface).

environment.rb

After registering a profile, you need to configure your application to be able to access the service through your profile. The key configuration file is environment.rb
# Include your application configuration below
  
PREALLOWED_LOGIN = 'your_user_login' # this is the same login/password combination you are using to log in to the preallowed.com site. You configured it during registering a profile.
PREALLOWED_PASSWORD = 'your_password'

CLIENT_ID = "2" # to find client_id login and click on a client from a list. The url will look like this http://www.preallowed.com/clients/2 . The number 2 is your client id.
USER_ROLE_ID = "3" # we assuming that the number of roles for your application is fixed and is known ahead of time. Each role has id in preallowed system. You will access roles by there id.
TEAM_CAPTAIN_ROLE_ID = "4"
ADMIN_ROLE_ID = "5"
PREALLOWED_HOST = "http://www.preallowed.com"
CLIENTS_URI = PREALLOWED_HOST + "/clients/" + CLIENT_ID


Accessing service from Ruby on Rails client (Active Resource)

We need to create few "Active Resource" model classes.

Client.rb

class Client < ActiveResource::Base
  self.site = PREALLOWED_HOST
  self.user = PREALLOWED_LOGIN
  self.password = PREALLOWED_PASSWORD
end

Subject.rb

class Subject < ActiveResource::Base
  self.site = CLIENTS_URI
  self.user = PREALLOWED_LOGIN
  self.password = PREALLOWED_PASSWORD
end

Role.rb

class Role < ActiveResource::Base
  self.site = CLIENTS_URI
  self.user = PREALLOWED_LOGIN
  self.password = PREALLOWED_PASSWORD
end

preallowed.com routes.rb

We thought it would be beneficial for Rails developers to see our routes file. We will be opensourcing all of the source code soon -- stay tuned.
    1 ActionController::Routing::Routes.draw do |map|
    2   map.resources :clients, :member => {:subject_id_from_name => :get}#TODO: write functional test    
    3   map.resources :clients do |client|
    4     client.resources :subjects,
    5     :member => {
    6       :has_access => :get,    # the url should look like this  /clients/:client_id/subjects/:id/has_access  params[:resource]=(resoruce string described by REG EXP)
    7       :is_subject_in_role => :get,
    8       :add_role => :put,
    9       :remove_role => :put      
   10     }     
   11     client.resources :roles,
   12     :member => {
   13       :add_subject => :put,
   14       :remove_subject => :put,
   15       :add_resource => :put,
   16       :remove_resource => :put
   17     }
   18     client.resources :resources,
   19     :member => {
   20       :add_role => :put,
   21       :remove_role => :put      
   22     }     
   23     
   24   end
   25 
   26   map.resources :profiles
   27 
   28 end

Accessing subject after login

Once your user loges into your application, you can programmatically access corresponding subject from preallowed service, if the subject does not yet exist, you can create it right from your rails app. As an example, we use restful authentication plugin, and once current_user is initialized, we call following line:
    # check preallowed_id and resolve if necessery
    current_user.add_to_preallowed if current_user.preallowed_id == nil || current_user.preallowed_id == 0
implementation of add_to_preallowed in user.rb
  def add_to_preallowed
    self.preallowed_id = find_or_create_preallowed_id
    self.save
    add_user_to_role(USER_ROLE_ID)
  end
  
  #this methods will try to find a subject in preallowed by login, or will create a new one, will return a preallowed_id or nil
  def find_or_create_preallowed_id
    # first lets see if such seubject already eixst to avoid dups
    preallowed_id = Client.find(CLIENT_ID).get(:subject_id_from_name, :subject_name => login)
        
    if preallowed_id != nil and preallowed_id != "0"
      return preallowed_id
    end
    
    #otherwise create a new one
    subject = Subject.create(:name => self.login)
    return subject.id
  end

add_user_to_role, remove_user_from_role

  # return true in case of success, false otherwise
  def add_user_to_role(role_id)
    # subject = Subject.find(preallowed_id)
    role = Role.find(role_id)

    # put :add_subject, :id => role.id, :subject_id => @subject.id, :client_id => @subject.client.id
    res = role.put(:add_subject, :id => role.id, :subject_id => preallowed_id, :client_id => CLIENT_ID)

    case res
    when Net::HTTPSuccess, Net::HTTPRedirection
      logger.debug "successfully added preallowed_user to role"
      return true
    else
      logger.error "error adding preallowed_user to role"        
      return false
    end
  end
  # return true in case of success, false otherwise
  def remove_user_from_role(role_id)
    # subject = Subject.find(preallowed_id)
    role = Role.find(role_id)

    # put :remove_subject, :id => role.id, :subject_id => @subject.id, :client_id => @subject.client.id
    res = role.put(:remove_subject, :id => role.id, :subject_id => preallowed_id, :client_id => CLIENT_ID)
    
    case res
    when Net::HTTPSuccess, Net::HTTPRedirection
      logger.debug "successfully removed preallowed_user from role"
      return true
    else
      logger.error "error removing preallowed_user from role"        
      return false
    end
  end

is_user_in_role

  def is_user_in_role(role_id)
    subject = Subject.find(self.preallowed_id)
    # get :is_subject_in_role, :id => @subject.id, :role_id => @role.id , :client_id => @subject.client.id # this should fail if the subject was not added to role first
    
    res = subject.get(:is_subject_in_role, :role_id => role_id)
    
    if res == "1"
      true
    else
      false
    end
  end

Example of use of has_access

  def check_authorization
    if(current_user != nil)
      
      subject = Subject.find(current_user.preallowed_id)
      
      res = subject.get(:has_access, :resource => request.request_uri)

      if res == "1"
        true
      else
        flash[:notice] =    "Insufficient privileges"      
        redirect_to :controller => "home", :action => "insufficient"
      end
    else # user not logged in
      logger.error "failed check authorization -- connection problem!!!!"
      redirect_to :controller => "users", :action => "signin"
    end

  end

Accessing service from Java client

coming soon...