diff --git a/.rvmrc b/.rvmrc new file mode 100644 index 000000000..c9b4fc507 --- /dev/null +++ b/.rvmrc @@ -0,0 +1 @@ +rvm ruby-1.9.2-p180@rails31rc4 diff --git a/:q b/:q deleted file mode 100644 index d0083d8e9..000000000 --- a/:q +++ /dev/null @@ -1,45 +0,0 @@ -<%= stylesheet_link_tag "design_temp" %> -<%= javascript_include_tag "design_temp" %> -

-<%= f.label :title, t('admin.title') %> -<%= f.text_field :title, :class => 'text' %> -

- -

-<%= f.label :author, t('admin.author') %> -<%= f.text_field :author, :class => 'text' %> -

- -

-<%= f.label :intro, t('admin.intro') %> -<%= f.text_field :intro, :class => 'text' %> -

- -

-<%= f.label "layout", t('admin.layout') %> -<% if @design.layout.blank? %> - <%= f.file_field :layout_file %> - <% else%> - <% debugger %> - <%= File.basename (@design.layout.url) %> -<% end %> -

-

-<%= f.label "structure_css", t('admin.structure_css') %> -<% if @design.structure_css.blank? %> - <%= f.file_field :structure_css %> - <% else%> - <%= File.basename (Design.all.last.structure_css.url) %> -<% end %> -

-

-<%= render :partial => 'design_file' ,:locals => { :fieldname=>"themes",:object=>@design ,:f=>f,:rtype=>'stylesheets',:item_destroy=>true,:item_editable=>true } %> -

- -

-<%= render :partial => 'design_file' ,:locals => { :fieldname=>"javascript",:object=>@design ,:f=>f,:rtype=>'javascripts' ,:item_destroy=>true,:item_editable=>true} %> -

- -

-<%= render :partial => 'design_file' ,:locals => { :fieldname=>"image",:object=>@design ,:f=>f,:rtype=>'images' ,:item_destroy=>true,:item_snapshot=>true} %> -

diff --git a/Gemfile b/Gemfile index 052637c80..05a549e38 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ gem 'ckeditor' gem 'devise' gem 'mini_magick' gem 'rubyzip' +gem 'sinatra' gem 'mongoid' diff --git a/Gemfile.lock b/Gemfile.lock index 79f319986..00b661971 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -131,6 +131,9 @@ GEM archive-tar-minitar (>= 0.5.2) rubyzip (0.9.4) shoulda-matchers (1.0.0.beta2) + sinatra (1.2.6) + rack (~> 1.1) + tilt (>= 1.2.2, < 2.0) sprockets (2.0.0.beta.10) hike (~> 1.0) rack (~> 1.0) @@ -168,5 +171,6 @@ DEPENDENCIES ruby-debug19 rubyzip shoulda-matchers + sinatra watchr yajl-ruby diff --git a/app/controllers/admin/purchases_controller.rb b/app/controllers/admin/purchases_controller.rb new file mode 100644 index 000000000..82b6a92b0 --- /dev/null +++ b/app/controllers/admin/purchases_controller.rb @@ -0,0 +1,88 @@ +class Admin::PurchasesController < ApplicationController + require "net/http" + require "uri" + require 'zip/zip' + + def index + @purchases = Purchase.all.entries + end + + def download + @purchase = Purchase.first(:conditions => {:id => params[:id]}) + download_purchase(@purchase, request.env['REQUEST_URI'].split('admin')[0].chop) + @purchase.downloaded = true + @purchase.save + redirect_to admin_purchases_url + end + + protected + + def download_purchase(purchase, url) + uri = URI.parse("http://localhost:3001/download/design") + http = Net::HTTP.new(uri.host, uri.port) + request = Net::HTTP::Post.new(uri.request_uri) + + public_key = OpenSSL::PKey::RSA.new(File.read(APP_CONFIG['main_public_key'])) + encrypted_data = public_key.public_encrypt({:purchase_id => purchase.purchase_id, + :roaming_id => Site.find(session[:site]).roaming_id, + :url => url}.to_json) + + request.set_form_data({ :purchase => encrypted_data}) + response = http.request(request) + temp_file = Tempfile.new("temp_file") + temp_file.binmode + temp_file.write response.body + temp_file.rewind + zip_name = response['content-disposition'].split('filename=')[1].gsub(/[\\\"]|.zip/, '') rescue '' + debugger + unzip_design(temp_file, zip_name) + temp_file.close + temp_file.unlink + end + + def unzip_design(file, zip_name) + Zip::ZipFile.open(file) do |zip_file| + encrypted = {} + ['encrypted_data', 'encrypted_key', 'encrypted_iv'].each do |e| + encrypted.merge!(e => zip_file.read(e)) + end + orig_file = decrypt_data(encrypted['encrypted_data'], encrypted['encrypted_key'], encrypted['encrypted_iv']) + + temp_file = Tempfile.new("temp_file_zip") + temp_file.binmode + temp_file.write orig_file + temp_file.rewind + + Zip::ZipFile.open(temp_file) { |orig_zip| + design = Design.new.from_json(orig_zip.read("#{zip_name}/#{zip_name}.json")) + Dir.mktmpdir('f_path') { |dir| + + title = design.layout.file_filename + temp = File.new(dir + '/' + title, 'w+') + temp.write orig_zip.read(zip_name + '/' + title) + design.layout.file = temp + + title = design.structure_css_filename + temp = File.new(dir + '/' + title, 'w+') + temp.write orig_zip.read(zip_name + '/' + title) + design.layout.file = temp + + ['themes', 'javascripts', 'images'].each do |type| + eval("design.#{type}").each do |object| + title = object.file_filename + temp = File.new(dir + '/' + title, 'w+') + temp.write orig_zip.read(zip_name + '/' + type + '/' + title) + object.file = temp + object.to_save = true + end + end + } + temp_file.close + temp_file.unlink + design.save + } + + end + end + +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2dd99b4a0..7bda19c48 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -25,6 +25,8 @@ class ApplicationController < ActionController::Base end end + protected + # Set I18n.locale def set_locale # update session if passed @@ -55,5 +57,21 @@ class ApplicationController < ActionController::Base def set_current_item session[:current_page] = params[:id] || @item.id rescue nil end + + def decrypt_data(encrypted_data, encrypted_key, encrypted_iv) + site = Site.find(session[:site]) + if encrypted_data + private_key = OpenSSL::PKey::RSA.new(site.private_key) + cipher = OpenSSL::Cipher.new('aes-256-cbc') + cipher.decrypt + cipher.key = private_key.private_decrypt(encrypted_key) + cipher.iv = private_key.private_decrypt(encrypted_iv) + + decrypted_data = cipher.update(encrypted_data) + decrypted_data << cipher.final + else + '' + end + end end diff --git a/app/controllers/gridfs_controller.rb b/app/controllers/gridfs_controller.rb new file mode 100644 index 000000000..be276673f --- /dev/null +++ b/app/controllers/gridfs_controller.rb @@ -0,0 +1,16 @@ +require 'mongo' + +class GridfsController < ActionController::Metal + def serve + gridfs_path = env["PATH_INFO"].gsub("/gridfs/", "") + begin + gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r') + self.response_body = gridfs_file.read + self.content_type = gridfs_file.content_type + rescue + self.status = :file_not_found + self.content_type = 'text/plain' + self.response_body = '' + end + end +end \ No newline at end of file diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index cb820fbb1..a81377152 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -4,11 +4,7 @@ class SitesController < ApplicationController def index @site = Site.first - if @site - @title = "site" - else - redirect_to :action => :new - end + redirect_to :action => :new unless @site end def new diff --git a/app/models/design.rb b/app/models/design/design.rb similarity index 100% rename from app/models/design.rb rename to app/models/design/design.rb diff --git a/app/models/design_file.rb b/app/models/design/design_file.rb similarity index 100% rename from app/models/design_file.rb rename to app/models/design/design_file.rb diff --git a/app/models/image.rb b/app/models/design/image.rb similarity index 100% rename from app/models/image.rb rename to app/models/design/image.rb diff --git a/app/models/javascript.rb b/app/models/design/javascript.rb similarity index 100% rename from app/models/javascript.rb rename to app/models/design/javascript.rb diff --git a/app/models/layout.rb b/app/models/design/layout.rb similarity index 100% rename from app/models/layout.rb rename to app/models/design/layout.rb diff --git a/app/models/layout_part.rb b/app/models/design/layout_part.rb similarity index 100% rename from app/models/layout_part.rb rename to app/models/design/layout_part.rb diff --git a/app/models/stylesheet.rb b/app/models/design/stylesheet.rb similarity index 100% rename from app/models/stylesheet.rb rename to app/models/design/stylesheet.rb diff --git a/app/models/theme.rb b/app/models/design/theme.rb similarity index 100% rename from app/models/theme.rb rename to app/models/design/theme.rb diff --git a/app/models/purchase/p_design.rb b/app/models/purchase/p_design.rb new file mode 100644 index 000000000..427fe4f53 --- /dev/null +++ b/app/models/purchase/p_design.rb @@ -0,0 +1,3 @@ +class PDesign < Purchase + +end \ No newline at end of file diff --git a/app/models/purchase/purchase.rb b/app/models/purchase/purchase.rb new file mode 100644 index 000000000..760724a27 --- /dev/null +++ b/app/models/purchase/purchase.rb @@ -0,0 +1,11 @@ +class Purchase + include Mongoid::Document + include Mongoid::Timestamps + + field :purchase_id + field :title + field :author + field :intro + field :downloaded + +end diff --git a/app/models/site.rb b/app/models/site.rb index 6cd490daa..11d1c768f 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -6,4 +6,21 @@ class Site field :in_use_locales, :type => Array field :valid_locales, :type => Array + field :roaming_id + field :private_key, :type => Binary + field :public_key, :type => Binary + + field :school + field :department + + def generate_keys + private_key = OpenSSL::PKey::RSA.generate(2048) + self.public_key = private_key.public_key.to_s + self.private_key = private_key.to_s + end + + def registered? + !self.roaming_id.blank? + end + end diff --git a/app/models/attribute_model.rb b/app/models/user/attribute_model.rb similarity index 100% rename from app/models/attribute_model.rb rename to app/models/user/attribute_model.rb diff --git a/app/models/attribute_value.rb b/app/models/user/attribute_value.rb similarity index 100% rename from app/models/attribute_value.rb rename to app/models/user/attribute_value.rb diff --git a/app/models/user.rb b/app/models/user/user.rb similarity index 100% rename from app/models/user.rb rename to app/models/user/user.rb diff --git a/app/models/user_attribute.rb b/app/models/user/user_attribute.rb similarity index 100% rename from app/models/user_attribute.rb rename to app/models/user/user_attribute.rb diff --git a/app/models/user_attribute_model.rb b/app/models/user/user_attribute_model.rb similarity index 100% rename from app/models/user_attribute_model.rb rename to app/models/user/user_attribute_model.rb diff --git a/app/models/user_info.rb b/app/models/user/user_info.rb similarity index 100% rename from app/models/user_info.rb rename to app/models/user/user_info.rb diff --git a/app/models/user_info_model.rb b/app/models/user/user_info_model.rb similarity index 100% rename from app/models/user_info_model.rb rename to app/models/user/user_info_model.rb diff --git a/app/models/user_role.rb b/app/models/user/user_role.rb similarity index 100% rename from app/models/user_role.rb rename to app/models/user/user_role.rb diff --git a/app/models/user_role_model.rb b/app/models/user/user_role_model.rb similarity index 100% rename from app/models/user_role_model.rb rename to app/models/user/user_role_model.rb diff --git a/app/views/admin/purchases/index.html.erb b/app/views/admin/purchases/index.html.erb new file mode 100644 index 000000000..cfeffa908 --- /dev/null +++ b/app/views/admin/purchases/index.html.erb @@ -0,0 +1,10 @@ +<% @purchases.each do |purchase| %> + <%= purchase.title %> | + <%= purchase.intro %> | + <%= purchase.author %> | + <% if purchase.downloaded %> + Downloaded + <% else %> + <%= link_to 'Download', download_admin_purchase_path(purchase) %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index 461f3fb28..5add9003a 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -51,12 +51,6 @@

Rulingcom

- -<%= javascript_include_tag "jquery", - "jquery-ui", - "rails", - "easy", - "application", :cache => 'all' %> <%= yield :page_specific_javascript %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 1d9014b70..653300feb 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -5,12 +5,8 @@ R4 <%= yield :page_specific_link %> - <%= stylesheet_link_tag "easy", "main", "devise", :media => "screen, projection" %> - <%= stylesheet_link_tag "easyprint", :media => "print" %> - - <%= yield :page_specific_css %> + <%= stylesheet_link_tag "application" %> + <%= javascript_include_tag "application" %> <%= csrf_meta_tag %> @@ -36,12 +32,6 @@

Rulingcom

- -<%#= javascript_include_tag "jquery", - "jquery-ui", - "rails", - "easy", - "application", :cache => 'all' %> <%= yield :page_specific_javascript %> diff --git a/app/views/layouts/panel.html.erb b/app/views/layouts/panel.html.erb index 86db42eb1..b21c66cb0 100644 --- a/app/views/layouts/panel.html.erb +++ b/app/views/layouts/panel.html.erb @@ -5,13 +5,8 @@ R4 <%= yield :page_specific_link %> - <%= stylesheet_link_tag "rulingcom/easy", :media => "screen, projection" %> - <%= stylesheet_link_tag "rulingcom/easyprint", :media => "print" %> - <%= stylesheet_link_tag "application", :media => "screen, projection" %> - - <%= yield :page_specific_css %> + <%= stylesheet_link_tag "application" %> + <%= javascript_include_tag "application" %> <%= csrf_meta_tag %> @@ -46,12 +41,6 @@

Rulingcom

- -<%= javascript_include_tag "jquery", - "jquery-ui", - "rails", - "easy", - "application", :cache => 'all' %> <%= yield :page_specific_javascript %> diff --git a/app/views/sites/index.html.erb b/app/views/sites/index.html.erb index 7ff38a427..bd12502ad 100644 --- a/app/views/sites/index.html.erb +++ b/app/views/sites/index.html.erb @@ -1 +1,7 @@ -<%= @title %> \ No newline at end of file +<% if @site && @site.registered? %> + registered +<% else %> + <%= link_to 'register', 'http://localhost:3001/user/sites/register?' + + {:site => {:school => @site.school, :department => @site.department}}.to_query, + :target => '_blank' %> +<% end %> \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index 1f7649ca7..421687cfd 100644 --- a/config/application.rb +++ b/config/application.rb @@ -24,8 +24,11 @@ module PrototypeR4 # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) - config.autoload_paths = %W(#{config.root}/lib) + config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += %W( #{config.root}/app/models/ckeditor ) + config.autoload_paths += %W(#{config.root}/app/models/design) + config.autoload_paths += %W(#{config.root}/app/models/purchase) + config.autoload_paths += %W(#{config.root}/app/models/user) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. @@ -53,7 +56,7 @@ module PrototypeR4 config.filter_parameters += [:password] # Enable the asset pipeline - config.assets.enabled = false + config.assets.enabled = true end end diff --git a/config/config.yml b/config/config.yml new file mode 100644 index 000000000..6a8bdb921 --- /dev/null +++ b/config/config.yml @@ -0,0 +1,5 @@ +defaults: &defaults + main_public_key: 'lib/main_public_key.pem' + +development: + <<: *defaults \ No newline at end of file diff --git a/config/initializers/load_config.rb b/config/initializers/load_config.rb new file mode 100644 index 000000000..46b175b5f --- /dev/null +++ b/config/initializers/load_config.rb @@ -0,0 +1 @@ +APP_CONFIG = YAML.load_file("#{Rails.root}/config/config.yml")[Rails.env] \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index e99fbd1ed..12b38e2f3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,48 +2,16 @@ PrototypeR4::Application.routes.draw do devise_for :users - # The priority is based upon order of creation: - # first created -> highest priority. - - # Sample of regular route: - # match 'products/:id' => 'catalog#view' - # Keep in mind you can assign values other than :controller and :action - - # Sample of named route: - # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase - # This route can be invoked with purchase_url(:id => product.id) - - # Sample resource route (maps HTTP verbs to controller actions automatically): - # resources :products resources :sites - - # Sample resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Sample resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end + + # routes for sinatra app + match '/site/set_registered', :to => CentralServerExchangeApp + match '/site/public_key', :to => CentralServerExchangeApp + match '/purchase/design', :to => CentralServerExchangeApp + + # routes for admin namespace :admin do resources :assets - resources :items do - member do - put :up - put :down - end - - end - resources :layouts resources :designs do get 'upload_package' ,:on => :collection post 'upload_package' ,:on => :collection @@ -52,7 +20,8 @@ PrototypeR4::Application.routes.draw do get 'delete' end end - + resources :items + resources :layouts resources :links do member do get 'delete' @@ -64,59 +33,31 @@ PrototypeR4::Application.routes.draw do end end resources :page_parts + resources :purchases do + member do + get 'download' + end + end resources :homes resources :snippets resources :translations resources :user_info_models resources :user_role_models end + # end admin namespace :panel do resources :users end - # Patch Mongo::GridIO to contain an each method. - require File.join Rails.root, 'lib/grid_io' - Mongo::GridIO.send(:include, PrototypeR4::GridIO) - match "/gridfs/*path", :via => :get, :to => proc { |env| - gridfs_path = env["PATH_INFO"].gsub("/gridfs/", "") - begin - gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r') - [ 200, { 'Content-Type' => gridfs_file.content_type, 'Content-Length' => gridfs_file.file_length.to_s }, gridfs_file ] - rescue - message = 'Grid file not found.' - [ 404, { 'Content-Type' => 'text/plain', 'Content-Length' => message.size.to_s }, message ] - end - } + # routes for gridfs files + match "/gridfs/*path" => "gridfs#serve" + # routes for pages to generate match '*page_name' => 'pages#show', :as => :page, :constraints => lambda{|request| !request.path.starts_with?("/panel") } - # Sample resource route with more complex sub-resources - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', :on => :collection - # end - # end - - # Sample resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end - - # You can have the root of your site routed with "root" - # just remember to delete public/index.html. - # root :to => "welcome#index" root :to => 'pages#index' - - # See how all your routes lay out with "rake routes" - - # This is a legacy wild controller route that's not recommended for RESTful applications. - # Note: This route will make all actions in every controller accessible via GET requests. - # match ':controller(/:action(/:id(.:format)))' end diff --git a/lib/central_server_exchange_app.rb b/lib/central_server_exchange_app.rb new file mode 100644 index 000000000..5a650c1cb --- /dev/null +++ b/lib/central_server_exchange_app.rb @@ -0,0 +1,42 @@ +class CentralServerExchangeApp < Sinatra::Base + + before do + @site = Site.first + end + + + post "/site/set_registered" do + begin + private_key = OpenSSL::PKey::RSA.new(@site.private_key) + roaming_id = private_key.private_decrypt(request.params['roaming_id']) + @site.update_attributes(:roaming_id => roaming_id) + body 'true' + rescue + body 'false' + end + end + + get '/site/public_key' do + begin + if @site.public_key.nil? + @site.generate_keys + @site.save + end + body @site.public_key + rescue + body 'false' + end + end + + post '/purchase/design' do + begin + private_key = OpenSSL::PKey::RSA.new(@site.private_key) + design = PDesign.new.from_json(private_key.private_decrypt(request.params['purchase'])) + design.save + body 'true' + rescue + body 'false' + end + end + +end \ No newline at end of file diff --git a/lib/grid_io.rb b/lib/grid_io.rb deleted file mode 100644 index 068a79e9f..000000000 --- a/lib/grid_io.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'mongo' - -module PrototypeR4 - module GridIO - - def self.included(base) - base.class_eval do - - def size - (file_length / chunk_size) + (file_length % chunk_size > 0 ? 1 : 0) - end - - def each(&block) - size.times { block.call(read(chunk_size)) } - end - - end - end - - end -end - diff --git a/lib/layout_support.rb b/lib/layout_support.rb deleted file mode 100644 index 822ada138..000000000 --- a/lib/layout_support.rb +++ /dev/null @@ -1,7 +0,0 @@ -module LayoutSupport - - def layout - Layout.find_by_name(self.layout_name) - end - -end \ No newline at end of file diff --git a/lib/main_public_key.pem b/lib/main_public_key.pem new file mode 100644 index 000000000..2a1ece5f0 --- /dev/null +++ b/lib/main_public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ymPDAHpTOtg0xs1D8Uz +8k6Vyzb4NeTZ2R/5KkG0HxQr6aseuzJPs6BO1/txTBrKgjsDH1r6HfTIQTtKf+dI +xKAzhwf913iofUmWCjDuOJw9yPd1LtY97xPTVI8UdZqztIbgKfGTNt81bV8/Q/0Z +Cr9E0PeP4AZbspuFwiDXe0ZfqfTfJDSLQDTUi1BgJgSydzpn1fqAVnxLY87Kq4sc +2SIdALGrmxDOquir0zTDrs6BTCi2lPp2gbAqxkfDvM+QQ6bdgQ5RaVLCMPi9r+c1 +/TkWKAdIPKPZspE6vmoPz7sl/3lKmrUiDCv/TXXeBb1hb2Z62+3fE0zEZ9SBII/+ +YwIDAQAB +-----END PUBLIC KEY----- diff --git a/lib/tasks/site.rake b/lib/tasks/site.rake new file mode 100644 index 000000000..da450a49b --- /dev/null +++ b/lib/tasks/site.rake @@ -0,0 +1,13 @@ +# encoding: utf-8 + +namespace :site do + + task :build => :environment do + + Site.delete_all + + Site.create( :school => 'The Best School', :department => 'Awesome', :valid_locales => [ 'en', 'zh_tw' ], :in_use_locales => [ 'zh_tw', 'en' ]) + + end + +end