From 5ecc99eccb6b3d1fe6b4cae4a39a3269a436142e Mon Sep 17 00:00:00 2001 From: dmitry-ilyashevich Date: Mon, 21 Mar 2011 17:36:43 +0200 Subject: [PATCH] Friendly conferencies user base merge --- .gitignore | 1 + app/controllers/admin/friends_controller.rb | 48 ++++++++++ app/controllers/friends_controller.rb | 41 +++++++++ app/controllers/sessions_controller.rb | 2 +- app/controllers/users_controller.rb | 75 ++++++++-------- app/helpers/admin/friends_helper.rb | 23 +++++ app/helpers/users_helper.rb | 15 +--- app/models/friend.rb | 90 +++++++++++++++++++ app/views/admin/friends/_form.html.erb | 11 +++ app/views/admin/friends/_friend.html.erb | 8 ++ app/views/admin/friends/_public_key.html.erb | 5 ++ app/views/admin/friends/edit.html.erb | 5 ++ app/views/admin/friends/index.html.erb | 20 +++++ app/views/admin/friends/new.html.erb | 5 ++ app/views/layouts/partials/_top.html.erb | 2 +- app/views/users/_form.html.erb | 37 ++++++++ app/views/users/edit.html.erb | 11 +++ app/views/users/new.html.erb | 13 +++ app/views/users/signup.html.erb | 6 ++ config/initializers/menu.rb | 1 + config/locales/en.yml | 21 +++++ config/routes.rb | 4 + db/migrate/20110320184326_create_friends.rb | 14 +++ lib/tasks/friend_list_key_generator.rake | 18 ++++ vendor/plugins/country_select/MIT-LICENSE | 20 +++++ vendor/plugins/country_select/README | 14 +++ vendor/plugins/country_select/init.rb | 1 + vendor/plugins/country_select/install.rb | 2 + .../country_select/lib/country_select.rb | 88 ++++++++++++++++++ vendor/plugins/country_select/uninstall.rb | 1 + 30 files changed, 551 insertions(+), 51 deletions(-) create mode 100644 app/controllers/admin/friends_controller.rb create mode 100644 app/controllers/friends_controller.rb create mode 100644 app/helpers/admin/friends_helper.rb create mode 100644 app/models/friend.rb create mode 100644 app/views/admin/friends/_form.html.erb create mode 100644 app/views/admin/friends/_friend.html.erb create mode 100644 app/views/admin/friends/_public_key.html.erb create mode 100644 app/views/admin/friends/edit.html.erb create mode 100644 app/views/admin/friends/index.html.erb create mode 100644 app/views/admin/friends/new.html.erb create mode 100644 app/views/users/_form.html.erb create mode 100644 app/views/users/edit.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/signup.html.erb create mode 100644 db/migrate/20110320184326_create_friends.rb create mode 100644 lib/tasks/friend_list_key_generator.rake create mode 100644 vendor/plugins/country_select/MIT-LICENSE create mode 100644 vendor/plugins/country_select/README create mode 100644 vendor/plugins/country_select/init.rb create mode 100644 vendor/plugins/country_select/install.rb create mode 100644 vendor/plugins/country_select/lib/country_select.rb create mode 100644 vendor/plugins/country_select/uninstall.rb diff --git a/.gitignore b/.gitignore index 1c3c4c36..5e45edd8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ db/development.sqlite3.save db/development_structure.sql db/schema.rb config/initializers/google_parameters.rb +config/*.pem cache test/tmp nbproject diff --git a/app/controllers/admin/friends_controller.rb b/app/controllers/admin/friends_controller.rb new file mode 100644 index 00000000..fdae1538 --- /dev/null +++ b/app/controllers/admin/friends_controller.rb @@ -0,0 +1,48 @@ +module Admin + class FriendsController < ApplicationController + layout 'admin' + before_filter :admin_required + before_filter :load_public_key, :only => [:index] + before_filter :find_friend, :only => [:edit, :update, :destroy] + + def index + @friends = Friend.for_list + end + + def new + @friend = Friend.new + end + + def create + @friend = Friend.new(params[:friend]) + + redirect_to admin_friends_path if @friend.save + end + + def edit + end + + def update + redirect_to admin_friends_path if @friend.update_attributes(params[:friend]) + end + + def destroy + @friend.destroy + + redirect_to admin_friends_path + end + + private + + def load_public_key + public_key_file = File.join(Rails.root, "config/friendlist_public.pem") + + @public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file)) if FileTest.exists? public_key_file + end + + def find_friend + @friend = Friend.find(params[:id]) + end + + end +end diff --git a/app/controllers/friends_controller.rb b/app/controllers/friends_controller.rb new file mode 100644 index 00000000..20af5fd7 --- /dev/null +++ b/app/controllers/friends_controller.rb @@ -0,0 +1,41 @@ +class FriendsController < ApplicationController + before_filter :load_private_key + protect_from_forgery :except => [:status, :user_data] + + def status + unless @private_key + head :precondition_failed + else + hostname = @private_key.private_decrypt([params[:message]].pack("H*")) + @friend = Friend.first(:conditions => {:hostname => hostname}, :select => 'id, hostname, public_key') + puts @friend.inspect + + respond_to do |format| + format.json { render :json => @friend } + end + end + end + + def user_data + public_key = OpenSSL::PKey::RSA.new(Friend.find_by_hostname(params[:hostname]).public_key) + login = @private_key.private_decrypt([params[:message]].pack("H*")) + + if @private_key && public_key && public_key.verify(OpenSSL::Digest::SHA1.new, [params[:sign]].pack("H*"), login) + @user = User.first(:conditions => {:login => login}, + :select => ('id, login, email, first_name, last_name, country, city, occupation')) + + respond_to do |format| + format.json { render :json => @user } + end + else + head :precondition_failed + end + end + + private + + def load_private_key + private_key_file = File.join(Rails.root, "config/friendlist_private.pem") + @private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file)) if FileTest.exists? private_key_file + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b7f5bff6..799d1099 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -11,7 +11,7 @@ def create current_user.remember_me unless current_user.remember_token? cookies[:auth_token] = { :value => self.current_user.remember_token, :expires => self.current_user.remember_token_expires_at } end - redirect_back_or_default(user_path(:id => current_user.id)) + redirect_back_or_default('/') flash[:notice] = t('message.session.logged', :user_name => h(params[:login])) else flash[:error] = t('message.session.failed') diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 098b8917..de44d55f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,45 +1,28 @@ # Controller for work with users: create(signup), update, delete, activate class UsersController < ApplicationController - include ActiveScaffold - - before_filter :login_required, :only => [:current] - before_filter :scaffold_action, :set_common_columns_info, :only => [:edit, :update, :new, :create] - before_filter(:current_user_only, :unless => :admin?, - :except => [:restore, :activate, :current,:new, :create]) - - - USER_EDITABLE_COLUMNS = [:password, :password_confirmation, :email, :first_name, :last_name, :country, :city, - :occupation, :projects, :subscribed, :subscribed_talks] - ONLY_CREATE_COLUMNS = [:login] - COLUMNS = ONLY_CREATE_COLUMNS + USER_EDITABLE_COLUMNS - PRIORITY_COUNTRIES = ['Belarus', 'Ukraine', 'Russia'] - - LOCALIZATION_LABEL_PREFIX = "label.user." - LOCALIZATION_DESCRIPTION_PREFIX = "description.user." - - active_scaffold :users do - cls = UsersController - self.actions = [:create, :update] - self.columns = cls::COLUMNS - self.create.columns = cls::COLUMNS - self.update.columns = cls::USER_EDITABLE_COLUMNS - - self.columns[:subscribed].form_ui = :checkbox - self.columns[:subscribed_talks].form_ui = :checkbox - self.columns[:password].form_ui = :password - self.columns[:password_confirmation].form_ui = :password - self.columns[:country].form_ui = :country - self.columns[:country].options[:priority] = cls::PRIORITY_COUNTRIES - User::REQUIRED_FIELDS.each{|i| self.columns[i].required = true } + before_filter :login_required, :only => [:show, :index, :edit, :update, :current] + + def signup end - def list - redirect_to user_path(:id => current_user.id) + # render new.rhtml + def new + @user_friends = Friend.check_by_login params[:login] if params[:login] + @user = User.new @user_friends.values.first if @user_friends.values.length > 0 end - def index - redirect_to user_path(:id => current_user.id) + def create + cookies.delete :auth_token + @user = User.new(params[:user]) + if @user.save + UserMailer.deliver_signup_notification(@user) + self.current_user = @user + flash[:notice] = t('message.user.registred') + redirect_to user_path(:id => current_user.id, :lang => params[:lang]) + else + render :action => 'new' + end end def current @@ -140,4 +123,26 @@ def random_pronouncable_password(size = 4) end r end + + def edit + @user = User.find params[:id] + unless @user.editable_by? current_user + return render(:text =>t('message.common.access_denied'), :status=> 403) + end + end + + def update + @user = User.find params[:id] + + unless @user.editable_by?(current_user) + return render(:text =>t('message.common.access_denied'), :status=> 403) + end + + flash[:notice] = t('message.user.login_change') if params[:user].delete(:login) + if(@user.update_attributes(params[:user])) + redirect_to user_path(:id=>@user) + else + render :action => "users/edit" + end + end end diff --git a/app/helpers/admin/friends_helper.rb b/app/helpers/admin/friends_helper.rb new file mode 100644 index 00000000..9fc432b6 --- /dev/null +++ b/app/helpers/admin/friends_helper.rb @@ -0,0 +1,23 @@ +module Admin + module FriendsHelper + + def status code + case code + when :bad_public_key + t ".status.bad_public_key" + when 201 + t ".status.ok" + when 412 + t ".status.precondition_failed" + when 404 + when 0 + when nil + t ".status.not_responding" + else + code + end + end + + end +end + diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 188d3c05..2312c6fd 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -1,20 +1,7 @@ module UsersHelper - PRIORITY_COUNTRIES = ['Belarus', 'Ukraine', 'Russia'] - def describe_user(user) - translate('message.user.describe', :full_name => user.full_name, + translate('message.user.describe', :full_name => user.full_name, :country => user.country, :city => user.city) end - - def active_scaffold_input_country(column, options) - priority = PRIORITY_COUNTRIES - select_options = {:prompt => as_(:_select_)} - select_options.merge!(options) - country_select(:record, column.name, column.options[:priority] || priority, select_options, column.options) - end - - def as_(param, opts={}) - t("label.user.#{param}", :default => t("label.common.#{param}")) - end end diff --git a/app/models/friend.rb b/app/models/friend.rb new file mode 100644 index 00000000..f455eaa4 --- /dev/null +++ b/app/models/friend.rb @@ -0,0 +1,90 @@ +class Friend < ActiveRecord::Base + + def self.check_by_login login + friends = Friend.all + friend_hostnames = friends.inject({}) do |res, friend| + res[friend.hostname] = friend.id + + res + end + + private_key_file = File.join(Rails.root, "config/friendlist_private.pem") + private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file)) rescue nil + + if private_key + checks = friends.inject([]) do |res, friend| + public_key = OpenSSL::PKey::RSA.new(friend.public_key) rescue nil + + if public_key + message = public_key.public_encrypt(login).unpack("H*")[0] + sign = private_key.sign(OpenSSL::Digest::SHA1.new, login).unpack("H*")[0] + + res.push({ :url => friend.hostname + 'friends/user_data.json', + :post_fields => { 'hostname' => friend.hostname, + 'message' => message, + 'sign' => sign } }) + end + + res + end + + friend_statuses = {} + require 'curb' + #Curl::Multi.post(checks, {:follow_location => true}, {:pipeline => true}) do |easy| + # friend_statuses[friend_hostnames[easy.url.chomp "friends/user_data.json"]] = easy.response_code + #end + checks.each do |check| + c = Curl::Easy.http_post(check[:url], + Curl::PostField.content('message', check[:post_fields]['message']), + Curl::PostField.content('sign', check[:post_fields]['sign']), + Curl::PostField.content('hostname', check[:post_fields]['hostname'])) + + friend_statuses[friend_hostnames[check[:url].chomp "friends/user_data.json"]] = JSON.parse c.body_str rescue nil + end + + friend_statuses + end + end + + def self.for_list + friends = Friend.all + + friend_hostnames = friends.inject({}) do |res, friend| + res[friend.hostname] = friend.id + + res + end + + friend_statuses = {} + checks = friends.inject([]) do |res, friend| + public_key = OpenSSL::PKey::RSA.new(friend.public_key) rescue nil + + unless public_key + friend_statuses[friend.id] = :bad_public_key + else + message = public_key.public_encrypt('http://localhost:3030/').unpack("H*")[0] + res.push({ :url => friend.hostname + 'friends/status.json', :post_fields => { 'message' => message, 'id' => friend.id } }) + end + + res + end + + require 'curb' + #Curl::Multi.post(checks, {:follow_location => true}, {:pipeline => true}) do |easy| + # friend_statuses[friend_hostnames[easy.url.chomp "friends/status.json"]] = easy.response_code + #end + checks.each do |check| + c = Curl::Easy.http_post(check[:url], + Curl::PostField.content('message', check[:post_fields]['message']), + Curl::PostField.content('id', check[:post_fields]['id'])) + + + friend_statuses[friend_hostnames[check[:url].chomp "friends/status.json"]] = c.response_code + end + + friends.collect do |friend| + { :id => friend.id, :hostname => friend.hostname, :status => friend_statuses[friend.id] } + end + end + +end diff --git a/app/views/admin/friends/_form.html.erb b/app/views/admin/friends/_form.html.erb new file mode 100644 index 00000000..c4f3baa8 --- /dev/null +++ b/app/views/admin/friends/_form.html.erb @@ -0,0 +1,11 @@ +<%= f.error_messages %> + +
+ <%= f.label :hostname, t('.hostname') %> + <%= f.text_field :hostname %> +
+ +
+ <%= f.label :public_key, t('.public_key') %>
+ <%= f.text_area :public_key, :cols => 80 %> +
diff --git a/app/views/admin/friends/_friend.html.erb b/app/views/admin/friends/_friend.html.erb new file mode 100644 index 00000000..d65512f0 --- /dev/null +++ b/app/views/admin/friends/_friend.html.erb @@ -0,0 +1,8 @@ + + <%= friend[:hostname] %> + <%= status friend[:status] %> + + <%= link_to t('.edit'), edit_admin_friend_path(:id => friend[:id], :lang => params[:lang]) %> + <%= link_to t('.delete'), admin_friend_path(:id => friend[:id], :lang => params[:lang]), :method => :delete %> + + diff --git a/app/views/admin/friends/_public_key.html.erb b/app/views/admin/friends/_public_key.html.erb new file mode 100644 index 00000000..0e353fc1 --- /dev/null +++ b/app/views/admin/friends/_public_key.html.erb @@ -0,0 +1,5 @@ +<% if key %> +
<%= key %>
+<% else %> + <%= t('.generate_key_pair') %> +<% end %> diff --git a/app/views/admin/friends/edit.html.erb b/app/views/admin/friends/edit.html.erb new file mode 100644 index 00000000..4680c0be --- /dev/null +++ b/app/views/admin/friends/edit.html.erb @@ -0,0 +1,5 @@ +<%= form_for(@friend, :url => admin_friend_path(:id => @friend.id, :lang => params[:lang]), :method => :put) do |f| %> + <%= render :partial => 'form', :locals => { :f => f } %> + + <%= f.submit t('label.common.update') %> +<% end %> diff --git a/app/views/admin/friends/index.html.erb b/app/views/admin/friends/index.html.erb new file mode 100644 index 00000000..a346b53e --- /dev/null +++ b/app/views/admin/friends/index.html.erb @@ -0,0 +1,20 @@ +

<%= t('.friendlist') %>

+ +<%= link_to t('.create'), new_admin_friend_path %> + + + + + + + + + + + + <%= render :partial => 'friend', :collection => @friends %> + +
<%= t('.hostname') %><%= t('.status') %> 
+ +<%= render :partial => 'public_key', :locals => { :key => @public_key } %> + diff --git a/app/views/admin/friends/new.html.erb b/app/views/admin/friends/new.html.erb new file mode 100644 index 00000000..8c06b645 --- /dev/null +++ b/app/views/admin/friends/new.html.erb @@ -0,0 +1,5 @@ +<%= form_for(@friend, :url => admin_friends_path(:lang => params[:lang])) do |f| %> + <%= render :partial => 'form', :locals => { :f => f } %> + + <%= f.submit t('label.common.create') %> +<% end %> diff --git a/app/views/layouts/partials/_top.html.erb b/app/views/layouts/partials/_top.html.erb index fe94f0f3..de29a835 100644 --- a/app/views/layouts/partials/_top.html.erb +++ b/app/views/layouts/partials/_top.html.erb @@ -10,7 +10,7 @@ <% else %>
  • <%= link_to t('label.session.loginButton'), new_session_path %>
  • |
  • -
  • <%= link_to t('label.user.register'), new_user_path %>
  • +
  • <%= link_to t('label.user.register'), :controller => :users, :action => :signup %>
  • <% end %> diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb new file mode 100644 index 00000000..83f03b3b --- /dev/null +++ b/app/views/users/_form.html.erb @@ -0,0 +1,37 @@ +

    <%= t('message.user.accuracy_note')%>

    + +

    *
    + <%= f.password_field :password %>

    + +

    *
    + <%= f.password_field :password_confirmation %>

    + +

    *
    + <%= f.text_field :email %>

    + +

    *
    + <%= f.text_field :first_name %>

    + +

    *
    + <%= f.text_field :last_name %>

    + +

    *
    + <%= f.country_select :country, ['Belarus', 'Ukraine', 'Russia'] %>

    + +

    *
    + <%= f.text_field :city %>

    + +

    *
    + <%= f.text_field :occupation %>

    + +


    + <%= f.text_area :projects, :style => 'width: 100%', :rows => 5 %>

    + +


    + <%= f.check_box :subscribed %>

    +

    + <%= file_column_field("user", "avator") %>

    + +

    <%= t('message.user.required_fields', :mark => '*') %>

    + +

    <%= t("message.user.privacy", :link => article_link(t('message.user.privacy_link'), 'users', 'privacy'))%>

    diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 00000000..6ee28871 --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,11 @@ +<%= error_messages_for :user %> + +

    <%= t('label.user.title', :full_name => @user.full_name, :login =>@user.login) %>

    +<% form_for(@user, :url => user_path(:id => @user), :html =>{:multipart => true}) do |f| %> +

    *
    + <%= f.text_field :login %>

    + + <%= render :partial =>"form", :locals => {:f => f}%> + +

    <%= submit_tag t('label.common.save') %>

    +<% end %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 00000000..b5838e2b --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,13 @@ +<%= flashes_if_any %> + +<%= error_messages_for :user %> + +<% form_for(:user, :url => users_path, :html => {:multipart => true}) do |f| -%> +

    *
    + <%= f.text_field :login %>

    + + <%= render :partial =>"form", :locals => {:f => f } %> + +

    <%= submit_tag t('label.user.create') %>

    + +<% end -%> diff --git a/app/views/users/signup.html.erb b/app/views/users/signup.html.erb new file mode 100644 index 00000000..538e9795 --- /dev/null +++ b/app/views/users/signup.html.erb @@ -0,0 +1,6 @@ +<% form_tag :controller => :users, :action => :new do %> +

    *
    + <%= text_field_tag :login %>

    + +

    <%= submit_tag t('label.user.create') %>

    +<% end -%> diff --git a/config/initializers/menu.rb b/config/initializers/menu.rb index 6743b64b..52d762ea 100644 --- a/config/initializers/menu.rb +++ b/config/initializers/menu.rb @@ -54,5 +54,6 @@ ['menu.admin.conference_registrations', 'admin/conference_registrations'], ['menu.admin.sponsors', 'admin/sponsors'], ['menu.admin.info_mailer', 'admin/info_mailer'], + ['menu.admin.friendlist', 'admin/friends'] ]] ] diff --git a/config/locales/en.yml b/config/locales/en.yml index 0b612ac9..6b853060 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -368,6 +368,26 @@ en: activation_restore: "Account activation for LVEE (repeat)" password_restore: "Password restore for LVEE" title: "Hello, {{full_name}}" + admin: + friends: + form: + hostname: "Hostname" + public_key: "Public key" + index: + create: "New" + friendlist: "Friendlist" + hostname: "Hostname" + status: "Status" + friend: + edit: "Edit" + delete: "Delete" + status: + bad_public_key: "Bad public key" + precondition_failed: "Hostname does not configured" + not_responding: "Hostname does not responded" + ok: "Ok" + public_key: + generate_key_pair: "Run rake task friendlist:generate_keys first" menu: admin: conference_registrations: "Conference registrations admin" @@ -377,6 +397,7 @@ en: statuses: "Statuses admin" title: Admin users: "Users admin" + friendlist: "Friends" conference: about: About attribution: Attribution diff --git a/config/routes.rb b/config/routes.rb index 59797573..9f75b73b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,8 @@ map.connect 'sitemap.xml', :controller => 'main', :action => 'sitemap' map.connect 'sitemap-news.xml', :controller => 'main', :action => 'sitemap_news' map.connect 'tracker', :controller => 'admin/tracker', :action => 'tracker' + map.connect 'friends/status.:format', :controller => 'friends', :action => 'status' + map.connect 'friends/user_data.:format', :controller => 'friends', :action => 'user_data' map.namespace :admin, :namespace => "", :path_prefix =>":lang", :name_prefix => "" do |admin| admin.resources :users @@ -15,6 +17,7 @@ admin.resources :conference_registrations, :active_scaffold => true, :collection => {:show_statistics => :get} admin.resources :statuses, :active_scaffold => true admin.resources :sponsors, :active_scaffold => true + admin.resources :friends admin.mail_user 'users/:to_list/mail', :controller => "info_mailer", :action => "index" end @@ -72,6 +75,7 @@ :controller => 'conference_registrations', :action => 'user_list') ns.connect "users/list", :controller => "users", :action => "list" + ns.connect "users/signup", :controller => "users", :action => "signup" ns.resources :users, :member => { :activate => :get }, :collection => {:current => :get, :restore => :any} do |m| m.connect('conference_registrations/new/:conference_id', diff --git a/db/migrate/20110320184326_create_friends.rb b/db/migrate/20110320184326_create_friends.rb new file mode 100644 index 00000000..e93a82e3 --- /dev/null +++ b/db/migrate/20110320184326_create_friends.rb @@ -0,0 +1,14 @@ +class CreateFriends < ActiveRecord::Migration + def self.up + create_table :friends do |t| + t.string :hostname, :nil => false + t.text :public_key, :default => '', :nil => false + + t.timestamps + end + end + + def self.down + drop_table :friends + end +end diff --git a/lib/tasks/friend_list_key_generator.rake b/lib/tasks/friend_list_key_generator.rake new file mode 100644 index 00000000..4ddcecd8 --- /dev/null +++ b/lib/tasks/friend_list_key_generator.rake @@ -0,0 +1,18 @@ +require 'fileutils' +require 'openssl' + +namespace :friendlist do + desc "Generate RSA key pair" + task :generate_keys do + key = OpenSSL::PKey::RSA.generate(2048) + + output_public = File.new(File.join(Rails.root, "config/friendlist_public.pem"), "w") + output_public.puts key.public_key + output_public.close + + output_private = File.new(File.join(Rails.root, "config/friendlist_private.pem"), "w") + output_private.puts key.to_pem + output_private.close + end +end + diff --git a/vendor/plugins/country_select/MIT-LICENSE b/vendor/plugins/country_select/MIT-LICENSE new file mode 100644 index 00000000..77a51dab --- /dev/null +++ b/vendor/plugins/country_select/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 Michael Koziarski + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/plugins/country_select/README b/vendor/plugins/country_select/README new file mode 100644 index 00000000..15408fb4 --- /dev/null +++ b/vendor/plugins/country_select/README @@ -0,0 +1,14 @@ +CountrySelect +============= + +Provides a simple helper to get an HTML select list of countries. The list of countries comes from the ISO 3166 standard. While it is a relatively neutral source of country names, it will still offend some users. + +Users are strongly advised to evaluate the suitability of this list given their user base. + +Example +======= + +country_select("user", "country_name") + + +Copyright (c) 2008 Michael Koziarski, released under the MIT license diff --git a/vendor/plugins/country_select/init.rb b/vendor/plugins/country_select/init.rb new file mode 100644 index 00000000..4568f7bc --- /dev/null +++ b/vendor/plugins/country_select/init.rb @@ -0,0 +1 @@ +require 'country_select' \ No newline at end of file diff --git a/vendor/plugins/country_select/install.rb b/vendor/plugins/country_select/install.rb new file mode 100644 index 00000000..dd99bf4d --- /dev/null +++ b/vendor/plugins/country_select/install.rb @@ -0,0 +1,2 @@ +# Install hook code here +puts "The list of countries provided by this plugin may offend some users. Please review it carefully before you use it" \ No newline at end of file diff --git a/vendor/plugins/country_select/lib/country_select.rb b/vendor/plugins/country_select/lib/country_select.rb new file mode 100644 index 00000000..1b021c05 --- /dev/null +++ b/vendor/plugins/country_select/lib/country_select.rb @@ -0,0 +1,88 @@ +# CountrySelect +module ActionView + module Helpers + module FormOptionsHelper + # Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags. + def country_select(object, method, priority_countries = nil, options = {}, html_options = {}) + InstanceTag.new(object, method, self, options.delete(:object)).to_country_select_tag(priority_countries, options, html_options) + end + # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to + # have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so + # that they will be listed above the rest of the (long) list. + # + # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. + def country_options_for_select(selected = nil, priority_countries = nil) + country_options = "" + + if priority_countries + country_options += options_for_select(priority_countries, selected) + country_options += "\n" + # prevents selected from being included twice in the HTML which causes + # some browsers to select the second selected option (not priority) + # which makes it harder to select an alternative priority country + selected=nil if priority_countries.include?(selected) + end + + return country_options + options_for_select(COUNTRIES, selected) + end + # All the countries included in the country_options output. + COUNTRIES = ["Afghanistan", "Aland Islands", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", + "Anguilla", "Antarctica", "Antigua And Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", + "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", + "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina", "Botswana", "Bouvet Island", "Brazil", + "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", + "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", + "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", + "Congo, the Democratic Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", + "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", + "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Malvinas)", + "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia", + "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea", + "Guinea-Bissau", "Guyana", "Haiti", "Heard and McDonald Islands", "Holy See (Vatican City State)", + "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran, Islamic Republic of", "Iraq", + "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", + "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", "Kyrgyzstan", + "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", + "Liechtenstein", "Lithuania", "Luxembourg", "Macao", "Macedonia, The Former Yugoslav Republic Of", + "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique", + "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Moldova, Republic of", + "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", + "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", + "Nigeria", "Niue", "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", + "Palestinian Territory, Occupied", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", + "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation", + "Rwanda", "Saint Barthelemy", "Saint Helena", "Saint Kitts and Nevis", "Saint Lucia", + "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", + "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", + "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", + "South Georgia and the South Sandwich Islands", "Spain", "Sri Lanka", "Sudan", "Suriname", + "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic", + "Taiwan, Province of China", "Tajikistan", "Tanzania, United Republic of", "Thailand", "Timor-Leste", + "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", + "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", + "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", + "Viet Nam", "Virgin Islands, British", "Virgin Islands, U.S.", "Wallis and Futuna", "Western Sahara", + "Yemen", "Zambia", "Zimbabwe"] unless const_defined?("COUNTRIES") + end + + class InstanceTag + def to_country_select_tag(priority_countries, options, html_options) + html_options = html_options.stringify_keys + add_default_name_and_id(html_options) + value = value(object) + content_tag("select", + add_options( + country_options_for_select(value, priority_countries), + options, value + ), html_options + ) + end + end + + class FormBuilder + def country_select(method, priority_countries = nil, options = {}, html_options = {}) + @template.country_select(@object_name, method, priority_countries, options.merge(:object => @object), html_options) + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/country_select/uninstall.rb b/vendor/plugins/country_select/uninstall.rb new file mode 100644 index 00000000..97383334 --- /dev/null +++ b/vendor/plugins/country_select/uninstall.rb @@ -0,0 +1 @@ +# Uninstall hook code here