Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Versioned apis #222

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ script:
- RAILS_ENV=test bundle exec rake --trace db:migrate test
before_script:
- gem install mysql2
- mysql -e 'create database quadbase_test'
- mysql -e 'create database quadbase_test'
notifications:
email:
- [email protected]
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ gem 'therubyracer', '~> 0.10.1'

gem 'bullring', '~> 0.8.3'

gem 'doorkeeper', '~> 0.6.0'

group :development, :test do
gem 'sqlite3', '~> 1.3.6'
gem 'debugger', '~> 1.1.4'
Expand All @@ -56,6 +58,7 @@ group :development, :test do
gem 'thin', '~> 1.3.1'
gem 'quiet_assets', '~> 1.0.1'
gem 'rvm-capistrano'
gem 'oauth2'
end

gem 'single_test', '~> 0.5.1'
Expand Down
16 changes: 16 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ GEM
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
doorkeeper (0.6.1)
railties (~> 3.1)
erubis (2.7.0)
eventmachine (0.12.10)
execjs (1.4.0)
Expand All @@ -79,8 +81,11 @@ GEM
railties (>= 3.0.0)
faker (1.0.1)
i18n (~> 0.4)
faraday (0.8.4)
multipart-post (~> 1.1)
highline (1.6.13)
hike (1.2.1)
httpauth (0.2.0)
i18n (0.6.0)
journey (1.0.4)
jquery-rails (2.0.2)
Expand All @@ -92,13 +97,16 @@ GEM
jsonify-rails (0.3.2)
actionpack
jsonify (< 0.4.0)
jwt (0.1.5)
multi_json (>= 1.0)
libv8 (3.3.10.4)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.19)
multi_json (1.3.6)
multipart-post (1.1.5)
mysql2 (0.3.11)
mysql2 (0.3.11-x86-mingw32)
net-scp (1.0.4)
Expand All @@ -108,6 +116,12 @@ GEM
net-ssh (2.5.2)
net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
oauth2 (0.8.0)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
orm_adapter (0.4.0)
paperclip (3.0.4)
activemodel (>= 3.0.0)
Expand Down Expand Up @@ -204,6 +218,7 @@ DEPENDENCIES
coffee-rails (~> 3.2.2)
debugger (~> 1.1.4)
devise (~> 2.1.0)
doorkeeper (~> 0.6.0)
execjs (~> 1.4.0)
factory_girl_rails (~> 3.4.0)
faker (~> 1.0.1)
Expand All @@ -212,6 +227,7 @@ DEPENDENCIES
jsonify-rails (~> 0.3.2)
mime-types (~> 1.18)
mysql2 (~> 0.3.11)
oauth2
paperclip (~> 3.0.4)
parslet (~> 1.4.0)
quiet_assets (~> 1.0.1)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Quadbase
========

[![Build Status](https://secure.travis-ci.org/lml/quadbase.png)](http://travis-ci.org/lml/quadbase)
[![Build Status](https://secure.travis-ci.org/lml/quadbase.png?branch=master)](http://travis-ci.org/lml/quadbase)

Quadbase is an open homework and test question bank, where questions are written
by the community and access is free.
Expand Down
24 changes: 24 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,27 @@ function hide_question_until_loaded() {
$(".question-wrapper").fadeIn('500');
});
}

function open_specified_dialog(name, is_modal, height, width, title, body) {
$('#' + name + '_dialog_errors').html('');

$("#" + name + "_dialog_body").html(body);

$("#" + name + "_dialog").dialog({
autoOpen: false,
modal: is_modal,
height: height,
width: width,
title: title,
position: 'center'
});

refresh_buttons();
$("#" + name + "_dialog").dialog('open');
$("#" + name + "_dialog").scrollTop(0);
$("#" + name + "_dialog").dialog('open').closeOnClickOutside();
}

function open_message_dialog(is_modal, height, width, title, body) {
open_specified_dialog('message', is_modal, height, width, title, body);
}
42 changes: 42 additions & 0 deletions app/controllers/api/v1/api_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module Api
module V1
class ApiController < ApplicationController
skip_before_filter :authenticate_user!

respond_to :json

rescue_from Exception, :with => :rescue_from_exception

private

def current_user
@current_user ||= doorkeeper_token ?
User.find(doorkeeper_token.resource_owner_id) :
AnonymousUser.instance
end

def rescue_from_exception(exception)
# See https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L453 for error names/symbols

error = :internal_server_error
send_email = true

case exception
when SecurityTransgression
error = :forbidden
send_email = false
when ActiveRecord::RecordNotFound,
ActionController::RoutingError,
ActionController::UnknownController,
AbstractController::ActionNotFound
error = :not_found
send_email = false
end

DeveloperErrorNotifier.exception_email(exception, request, present_user) if send_email
head error
end

end
end
end
11 changes: 11 additions & 0 deletions app/controllers/api/v1/questions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Api
module V1
class QuestionsController < ApiController
def show
@question = Question.from_param(params[:id])
raise SecurityTransgression unless current_user.can_read?(@question)
end

end
end
end
19 changes: 19 additions & 0 deletions app/controllers/api/v1/solutions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Api
module V1
class SolutionsController < ApiController

def index
# debugger
@question = Question.from_param(params[:question_id])
raise SecurityTransgression unless current_user.can_read?(@question)
@solutions = Vote.order_by_votes(@question.valid_solutions_visible_for(current_user))
end

def show
@solution = Solution.find(params[:id])
raise SecurityTransgression unless current_user.can_read?(@solution)
end

end
end
end
10 changes: 6 additions & 4 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ class ApplicationController < ActionController::Base

helper_method :user_is_disabled?,
:site_in_maintenance?,
:user_is_admin?,
# :user_is_admin?,
:present_user,
:get_error_messages,
:protect_form,
:view_dir

respond_to :html, :js

include SharedApplicationMethods

unless Quadbase::Application.config.consider_all_requests_local
rescue_from Exception, :with => :rescue_from_exception
end
Expand Down Expand Up @@ -97,9 +99,9 @@ def site_not_in_maintenance!
redirect_maintenance
end

def user_is_admin?
user_signed_in? && current_user.is_administrator?
end
# def user_is_admin?
# user_signed_in? && current_user.is_administrator?
# end

def authenticate_admin!
user_is_admin? || redirect_not_admin
Expand Down
3 changes: 3 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
require 'digest/md5'

module ApplicationHelper

include SharedApplicationMethods

def trash_icon
image_tag("trash.gif", {:border => 0, :alt => "Delete", :title => "Delete"})
#{}"<span class=\"trashIcon\"></span>".html_safe
Expand Down
12 changes: 12 additions & 0 deletions app/helpers/jquery_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,16 @@ def reload_mathjax(element_id="")
element_id + '")]);').html_safe
end

def message_dialog(title=nil, options={}, &block)
specified_dialog("message", title, options, &block)
end

def specified_dialog(name=nil, title=nil, options={}, &block)
@name ||= name
@title ||= title
@options = options
@body = capture(&block)
render :template => 'shared/specified_dialog'
end

end
4 changes: 2 additions & 2 deletions app/models/solution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class Solution < ActiveRecord::Base
scope :visible_for, lambda { |user|
joins{question}.where{(creator_id == user.id) |
(is_visible == true) |
( question.version == nil &&
question.id.in(Question.visible_for(user).select{id}) )}
( (question.version == nil) &
(question.id.in(Question.visible_for(user).select{id})) )}
}

before_save :auto_subscribe
Expand Down
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class User < ActiveRecord::Base
has_many :deputizers,
:through => :received_deputizations

has_one :api_key, :dependent => :destroy

validates_presence_of :first_name, :last_name, :username, :user_profile
validates_uniqueness_of :username, :case_sensitive => false
validates_length_of :username, :in => 3..40
Expand Down
34 changes: 34 additions & 0 deletions app/views/api/v1/multipart_questions/_show.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
# License version 3 or later. See the COPYRIGHT file for details.

json.multipart_question do
json.ingest! (render :partial => 'questions/common',
:locals => {:question => @question})

qs = @question.question_setup
unless qs.nil?
json.introduction do
json.markup qs.content
json.html qs.content_html
end
end

json.parts(@question.child_question_parts) do |part|
child_question = part.child_question

json.prerequisites(child_question.prerequisite_questions) do |pq|
json.id pq.to_param
end

json.supported_by(child_question.supporting_questions) do |sq|
json.id sq.to_param
end

json.ingest! (render :partial => 'simple_questions/show',
:locals => {:question => child_question,
:skip_question_setup => true,
:skip_attribution => true})
end

json.ingest! (render :partial => 'questions/attribution')
end
5 changes: 5 additions & 0 deletions app/views/api/v1/multipart_questions/show.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
# License version 3 or later. See the COPYRIGHT file for details.

json.ingest! (render :partial => 'multipart_questions/show',
:locals => {:question => question})
24 changes: 24 additions & 0 deletions app/views/api/v1/questions/_attribution.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
# License version 3 or later. See the COPYRIGHT file for details.

collaborators = @question.question_collaborators

authors = collaborators.select{|c| c.is_author}
copyright_holders = collaborators.select{|c| c.is_copyright_holder}

json.attribution do
json.authors(authors) do |author|
json.id author.user.id
json.name author.user.full_name
end

json.copyright_holders(copyright_holders) do |copyright_holder|
json.id copyright_holder.user.id
json.name copyright_holder.user.full_name
end

json.license do
json.name @question.license.long_name
json.url @question.license.url
end
end
5 changes: 5 additions & 0 deletions app/views/api/v1/questions/_common.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
# License version 3 or later. See the COPYRIGHT file for details.

json.id question.to_param
json.url question_url(question)
10 changes: 10 additions & 0 deletions app/views/api/v1/questions/show.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
# License version 3 or later. See the COPYRIGHT file for details.

if @question.errors.none?
json.ingest! (render :partial => "#{view_dir(@question)}/show",
:locals => {:question => @question})
else
json.ingest! (render :partial => 'shared/errors',
:locals => {:errors => @question.errors})
end
15 changes: 15 additions & 0 deletions app/views/api/v1/simple_questions/_content_and_answers.jsonify
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

json.content do
json.markup question.content
json.html question.variated_content_html
end

if !question.answer_choices.empty?
json.answer_choices(question.answer_choices) do |answer_choice|
json.markup answer_choice.content
json.html answer_choice.variated_content_html
json.credit answer_choice.credit
end
end

json.answer_can_be_sketched question.answer_can_be_sketched
Loading