Added Categories, Search

This commit is contained in:
saurabhbhatia 2014-01-10 16:48:23 +08:00
parent ba465ae4d0
commit 276e0fd885
32 changed files with 408 additions and 74 deletions

View File

@ -5,8 +5,13 @@ gem 'rails', '4.0.2'
gem 'mongoid', github: 'mongoid/mongoid'
gem 'bson_ext'
gem 'mongoid-elasticsearch'
gem 'devise'
gem 'warden'
gem 'doorkeeper', github: 'shinzui/doorkeeper'
gem 'cancan'
gem 'rolify', :github => 'EppO/rolify'
gem 'mongoid_slug', github: 'digitalplaywright/mongoid-slug'
gem 'carrierwave'
@ -21,7 +26,6 @@ gem "font-awesome-rails", github: "bokmann/font-awesome-rails"
gem 'rmagick'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
gem 'apipie-rails'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

View File

@ -1,3 +1,9 @@
GIT
remote: git://github.com/EppO/rolify.git
revision: 45de8cf4bf51e60accddee3385829a2266709cb0
specs:
rolify (3.3.0.rc5)
GIT
remote: git://github.com/ahoward/mongoid-grid_fs.git
revision: 059012a2c2a9e0a5d6e67137752c3e918689c88a
@ -40,6 +46,13 @@ GIT
origin (~> 2.0)
tzinfo (~> 0.3.37)
GIT
remote: git://github.com/shinzui/doorkeeper.git
revision: 8f67bd06945983cf9fd1b883a09cb51bc9ffe32e
specs:
doorkeeper (1.0.0.rc1)
railties (>= 3.1)
GEM
remote: https://rubygems.org/
specs:
@ -67,14 +80,13 @@ GEM
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
apipie-rails (0.0.24)
rails (>= 3.0.10)
arel (4.0.1)
atomic (1.1.14)
bcrypt-ruby (3.1.2)
bson (2.0.0)
bson_ext (1.5.1)
builder (3.1.4)
cancan (1.6.10)
carrierwave (0.9.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
@ -96,8 +108,18 @@ GEM
railties (>= 3.2.6, < 5)
thread_safe (~> 0.1)
warden (~> 1.2.3)
elasticsearch (0.4.5)
elasticsearch-api (= 0.4.5)
elasticsearch-transport (= 0.4.5)
elasticsearch-api (0.4.5)
multi_json
elasticsearch-transport (0.4.5)
faraday
multi_json
erubis (2.7.0)
execjs (2.0.2)
faraday (0.8.9)
multipart-post (~> 1.2.0)
hike (1.2.3)
i18n (0.6.9)
jbuilder (1.5.3)
@ -112,11 +134,15 @@ GEM
treetop (~> 1.4.8)
mime-types (1.25.1)
minitest (4.7.5)
mongoid-elasticsearch (0.4.3)
elasticsearch (~> 0.4.1)
mongoid (~> 4.0.0.alpha1)
moped (2.0.0.beta4)
bson (~> 2.0)
connection_pool (~> 1.2)
optionable (~> 0.2.0)
multi_json (1.8.2)
multipart-post (1.2.0)
optionable (0.2.0)
origin (2.0.0)
orm_adapter (0.5.0)
@ -182,22 +208,26 @@ PLATFORMS
DEPENDENCIES
anjlab-bootstrap-rails!
apipie-rails
bson_ext
cancan
carrierwave
carrierwave-mongoid
coffee-rails (~> 4.0.0)
devise
doorkeeper!
font-awesome-rails!
jbuilder (~> 1.2)
jquery-rails
mongoid!
mongoid-elasticsearch
mongoid-grid_fs!
mongoid_slug!
puma
rails (= 4.0.2)
rmagick
rolify!
sass-rails (~> 4.0.0)
sdoc
turbolinks
uglifier (>= 1.3.0)
warden

View File

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

View File

@ -1,69 +0,0 @@
body {
background-color: #fff;
color: #333;
font-family: verdana, arial, helvetica, sans-serif;
font-size: 13px;
line-height: 18px;
}
p, ol, ul, td {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 13px;
line-height: 18px;
}
pre {
background-color: #eee;
padding: 10px;
font-size: 11px;
}
a {
color: #000;
&:visited {
color: #666;
}
&:hover {
color: #fff;
background-color: #000;
}
}
div {
&.field, &.actions {
margin-bottom: 10px;
}
}
#notice {
color: green;
}
.field_with_errors {
padding: 2px;
background-color: red;
display: table;
}
#error_explanation {
width: 450px;
border: 2px solid red;
padding: 7px;
padding-bottom: 0;
margin-bottom: 20px;
background-color: #f0f0f0;
h2 {
text-align: left;
font-weight: bold;
padding: 5px 5px 5px 15px;
font-size: 12px;
margin: -7px;
margin-bottom: 0px;
background-color: #c00;
color: #fff;
}
ul li {
font-size: 12px;
list-style: square;
}
}

View File

@ -0,0 +1,3 @@
// Place all the styles related to the search controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,6 +1,7 @@
module Api
module V1
class ExtensionsController < ApplicationController
doorkeeper_for :all
respond_to :json
def index

View File

@ -1,6 +1,7 @@
module Api
module V1
class TemplatesController < ApplicationController
doorkeeper_for :all, :scopes => [:public]
respond_to :json
def index

View File

@ -0,0 +1,20 @@
class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
before_filter :authenticate_user!
def index
@applications = current_user.oauth_applications
end
# only needed if each application must have some owner
def create
@application = Doorkeeper::Application.new(application_params)
@application.owner = current_user if Doorkeeper.configuration.confirm_application_owner?
if @application.save
flash[:notice] = I18n.t(:notice, :scope => [:doorkeeper, :flash, :applications, :create])
respond_with [:oauth, @application]
else
render :new
end
end
end

View File

@ -0,0 +1,7 @@
class SearchController < ApplicationController
def index
end
def show
end
end

View File

@ -0,0 +1,2 @@
module SearchHelper
end

33
app/models/ability.rb Normal file
View File

@ -0,0 +1,33 @@
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
else
can :read, Template
can :read, Extension
end
#
# The first argument to `can` is the action you are giving the user
# permission to do.
# If you pass :manage it will apply to every action. Other common actions
# here are :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on.
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
# class of the resource.
#
# The third argument is an optional hash of conditions to further filter the
# objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details:
# https://github.com/ryanb/cancan/wiki/Defining-Abilities
end
end

8
app/models/category.rb Normal file
View File

@ -0,0 +1,8 @@
class Category
include Mongoid::Document
field :title, type: String
field :type, type: String
has_many :templates
has_many :extensions
end

View File

@ -0,0 +1,13 @@
module CategoryFilter
extend ActiveSupport::Concern
included do
scope :all_category, where(type: name.to_s)
end
# module ClassMethods
# def filter_by_category(category_id)
# product_"#{name}" = name.where(category_id: category_id)
# end
# end
end

View File

@ -0,0 +1,30 @@
module Doorkeeper
class Application
include Mongoid::Document
include Mongoid::Timestamps
self.store_in collection: :oauth_applications
field :name, :type => String
field :uid, :type => String
field :secret, :type => String
field :redirect_uri, :type => String
field :owner_id, :type => String
field :owner_type, :type => String
index({
uid: 1,
owner_id: 1,
owner_type: 1
},
{ unique: true })
has_many :authorized_tokens, :class_name => "Doorkeeper::AccessToken"
def self.authorized_for(resource_owner)
ids = AccessToken.where(:resource_owner_id => resource_owner.id, :revoked_at => nil).map(&:application_id)
find(ids)
end
end
end

View File

@ -2,14 +2,23 @@ class Extension
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
include Mongoid::Elasticsearch
include CategoryFilter
field :title, type: String
field :author, type: String
field :preview, type: String
field :extension, type: String
field :description, type: String
field :category_id, type: String
slug :title, history: true
belongs_to :category
mount_uploader :preview, ImageUploader
mount_uploader :extension, ProductUploader
elasticsearch!
end

16
app/models/role.rb Normal file
View File

@ -0,0 +1,16 @@
class Role
include Mongoid::Document
has_and_belongs_to_many :users
belongs_to :resource, :polymorphic => true
field :name, :type => String
index({
:name => 1,
:resource_type => 1,
:resource_id => 1
},
{ :unique => true})
scopify
end

View File

@ -1,14 +1,21 @@
class Template
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
include Mongoid::Elasticsearch
field :title, type: String
field :author, type: String
field :preview, type: String
field :template, type: String
field :category_id, type: String
slug :title, history: true
belongs_to :category
mount_uploader :preview, ImageUploader
mount_uploader :template, ProductUploader
elasticsearch!
end

View File

@ -1,5 +1,6 @@
class User
include Mongoid::Document
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
@ -33,4 +34,5 @@ class User
# field :failed_attempts, :type => Integer, :default => 0 # Only if lock strategy is :failed_attempts
# field :unlock_token, :type => String # Only if unlock strategy is :email or :both
# field :locked_at, :type => Time
has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner
end

View File

@ -0,0 +1,2 @@
<h1>Search#index</h1>
<p>Find me in app/views/search/index.html.erb</p>

View File

@ -0,0 +1,2 @@
<h1>Search#show</h1>
<p>Find me in app/views/search/show.html.erb</p>

View File

@ -0,0 +1,67 @@
Doorkeeper.configure do
# Change the ORM that doorkeeper will use.
# Currently supported options are :active_record, :mongoid2, :mongoid3, :mongo_mapper
orm :mongoid4
# This block will be called to check whether the resource owner is authenticated or not.
resource_owner_from_credentials do |routes|
request.params[:user] = {:email => request.params[:username], :password => request.params[:password]}
request.env["devise.allow_params_authentication"] = true
request.env["warden"].authenticate!(:scope => :user)
end
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
admin_authenticator do
# # Put your admin authentication logic here.
# # Example implementation:
redirect_to root_url unless current_user.try(:has_role?, :admin)
# Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url)
end
# Authorization Code expiration time (default 10 minutes).
# authorization_code_expires_in 10.minutes
# Access token expiration time (default 2 hours).
# If you want to disable expiration, set this to nil.
# access_token_expires_in 2.hours
# Issue access tokens with refresh token (disabled by default)
# use_refresh_token
# Provide support for an owner to be assigned to each registered application (disabled by default)
# Optional parameter :confirmation => true (default false) if you want to enforce ownership of
# a registered application
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
enable_application_owner :confirmation => false
# Define access token scopes for your provider
# For more information go to https://github.com/applicake/doorkeeper/wiki/Using-Scopes
# default_scopes :public
# optional_scopes :write, :update
# Change the way client credentials are retrieved from the request object.
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
# falls back to the `:client_id` and `:client_secret` params from the `params` object.
# Check out the wiki for more information on customization
# client_credentials :from_basic, :from_params
# Change the way access token is authenticated from the request object.
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
# falls back to the `:access_token` or `:bearer_token` params from the `params` object.
# Check out the wiki for more information on customization
# access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
# Change the test redirect uri for client apps
# When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
# The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
# (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
#
# test_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
# Under some circumstances you might want to have applications auto-approved,
# so that the user skips the authorization step.
# For example if dealing with trusted a application.
# skip_authorization do |resource_owner, client|
# client.superapp? or resource_owner.admin?
# end
end

View File

@ -0,0 +1,8 @@
Rolify.configure do |config|
# By default ORM adapter is ActiveRecord. uncomment to use mongoid
config.use_mongoid
# Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false
# Enable this feature _after_ running rake db:migrate as it relies on the roles table
# config.use_dynamic_shortcuts
end

View File

@ -0,0 +1,68 @@
en:
activerecord:
errors:
models:
application:
attributes:
redirect_uri:
fragment_present: 'cannot contain a fragment.'
has_query_parameter: 'cannot contain a query parameter.'
invalid_uri: 'must be a valid URI.'
relative_uri: 'must be an absolute URI.'
mongoid:
errors:
models:
application:
attributes:
redirect_uri:
fragment_present: 'cannot contain a fragment.'
has_query_parameter: 'cannot contain a query parameter.'
invalid_uri: 'must be a valid URI.'
relative_uri: 'must be an absolute URI.'
mongo_mapper:
errors:
models:
application:
attributes:
redirect_uri:
fragment_present: 'cannot contain a fragment.'
has_query_parameter: 'cannot contain a query parameter.'
invalid_uri: 'must be a valid URI.'
relative_uri: 'must be an absolute URI.'
doorkeeper:
errors:
messages:
# Common error messages
invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
invalid_redirect_uri: 'The redirect uri included is not valid.'
unauthorized_client: 'The client is not authorized to perform this request using this method.'
access_denied: 'The resource owner or authorization server denied the request.'
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
#configuration error messages
credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.'
resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.'
# Access grant errors
unsupported_response_type: 'The authorization server does not support this response type.'
# Access token errors
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
# Password Access token errors
invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found'
flash:
applications:
create:
notice: 'Application created.'
destroy:
notice: 'Application deleted.'
update:
notice: 'Application updated.'
authorized_applications:
destroy:
notice: 'Application revoked.'

View File

@ -2,6 +2,12 @@ require 'api_constraints'
Mtstore::Application.routes.draw do
get "search/index"
get "search/show"
use_doorkeeper do
controllers :applications => 'oauth/applications'
end
devise_for :users
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: :true) do

View File

@ -5,4 +5,5 @@
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
user = User.create :email => "orbit@rulingcom.com", :password => "bjo4xjp6", :password_confirmation => "bjo4xjp6"
user = User.create(:email => "orbit@rulingcom.com", :password => "bjo4xjp6", :password_confirmation => "bjo4xjp6")
category = Category.create([{ title: "Science", type: "Template" },{ title: "Responsive", type: "Template" },{ title: "Organizer", type: "Extension" }, { title: "Productivity", type: "Extension" }, { title: "Location", type: "Extension" }])

8
lib/tasks/run_index.rake Normal file
View File

@ -0,0 +1,8 @@
namespace :run_index do
task :once => :environment do
Extension.es.index_all
puts "Index Created for Extension"
Template.es.index_all
puts "Index Created for Templates"
end
end

View File

@ -0,0 +1,14 @@
require 'test_helper'
class SearchControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
end
test "should get show" do
get :show
assert_response :success
end
end

9
test/fixtures/categories.yml vendored Normal file
View File

@ -0,0 +1,9 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
title: MyString
type:
two:
title: MyString
type:

11
test/fixtures/roles.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value

View File

@ -0,0 +1,4 @@
require 'test_helper'
class SearchHelperTest < ActionView::TestCase
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class CategoryTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

7
test/models/role_test.rb Normal file
View File

@ -0,0 +1,7 @@
require 'test_helper'
class RoleTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end