Add "assignee" JSON callback

The callback reports the assignee of a package in a platform given.
Used for integration with external bug trackers.
This commit is contained in:
Pavel Shved 2012-05-31 15:43:40 +04:00 committed by George Vinogradov
parent 5317427662
commit e75a676895
3 changed files with 68 additions and 4 deletions

View File

@ -1,13 +1,53 @@
# -*- encoding : utf-8 -*-
class Platforms::MaintainersController < ApplicationController
# External callbacks from bugzilla
ET_CALLBACKS = [:assignee]
before_filter :authenticate_user!, :except => ET_CALLBACKS
load_and_authorize_resource :platform, :except => ET_CALLBACKS
# external callbacks are authorized with a lightweight scheme: they should only come from a specified IP addresses
before_filter :authenticate_external_tracker!, :only => ET_CALLBACKS
def index
# Let's build a relation to query maintainers via 'build_list_packages' table
@maintainers = BuildList::Package.maintainers.where(:platform_id => @platform).order('lower(name) ASC').includes(:project).paginate(:page => params[:page])
end
# Given platform_id, and the string that contains source or binary package name, or project name, find the email of the assignee of the project that contains the given package under the platform specified.
def assignee
ret = {}
# NOTE that platform is looked up here to handle the error of platform being not found
@platform = Platform.find(params[:platform_id]) rescue ''
@package = params[:package]
if @platform.blank?
ret[:error] = "ABF platform ##{params[:platform_id]} not found!"
elsif @package.blank?
# TODO: maybe, it should be the special case for "default" maintainer for the platform?
ret[:error] = "Package not specified"
else
# Ok, find a maintainer, and return it, if any. If source and binary package have the same name, we do not distinguish because most likely they'll have same assignee.
if maintainer = BuildList::Package.maintainers.where(:platform_id => @platform, :name => @package).includes(:project).first
ret[:assignee] = maintainer.assignee.email
# Package is not found; look for a project for this platform
elsif proj_id = @platform.repositories.joins(:projects).where(["projects.name = ?",@package]).select('projects.id').map(&:id).first
# Try to find a project?
begin
ret[:assignee] = Project.find(proj_id).assignee.email
rescue
ret[:error] = 'Not found'
end
else
ret[:error] = 'Not found'
end
end
render :json => ret
end
protected
def authenticate_external_tracker!
if request.remote_ip != APP_CONFIG['external_tracker_ip']
render :nothing => true, :status => 403
end
end
end

View File

@ -48,6 +48,10 @@ Rosa::Application.routes.draw do
get :search, :on => :collection
end
# Maintainer Database API
# (package name may contain dots, numbers, and all kinds of weird symbols, hence the :constraints relaxation)
match 'api/json/maintdb/assignee/:platform_id/:package' => 'platforms/maintainers#assignee', :format => :json, :constraints => { :package => /.*/ }
scope :module => 'platforms' do
resources :platforms do
resources :private_users, :except => [:show, :destroy, :update]

View File

@ -19,17 +19,37 @@ shared_examples_for 'guest user' do
end
describe Platforms::MaintainersController do
before(:each) do
before(:each) do
stub_symlink_methods
@platform = FactoryGirl.create(:platform)
@platform.visibility = 'open'
end
context 'for guest' do
it_should_behave_like 'guest user'
@assignee_rq = { :platform_id => @platform.id, :package => 'test' }
end
context 'for guest' do
it_should_behave_like 'guest user'
it 'should not be able to get api' do
get :assignee, @assignee_rq
puts response.headers.inspect
response.response_code.should equal(403)
end
end
context 'for bugzilla' do
before(:each) do
request.remote_addr = APP_CONFIG['external_tracker_ip']
end
it_should_behave_like 'guest user'
it 'should be able to get api' do
get :assignee, @assignee_rq
response.response_code.should equal(200)
end
end
end