From 85c0d8b8275adf65a7f2e0b383d0f17aaaba9605 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 3 Feb 2012 18:32:04 +0400 Subject: [PATCH 01/17] Change git branch for mass rebuild --- app/models/project.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 15c546f25..ecbf136ee 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -61,14 +61,14 @@ class Project < ActiveRecord::Base end end - def build_for(platform, user) + def build_for(platform, user) build_lists.create do |bl| bl.pl = platform bl.bpl = platform bl.update_type = 'recommended' bl.arch = Arch.find_by_name('x86_64') # Return i586 after mass rebuild # FIXME: Need to set "latest_#{platform.name}" - bl.project_version = "latest_mandriva2011" + bl.project_version = "latest_import_mandriva2011" bl.build_requires = false # already set as db default bl.user = user bl.auto_publish = true # already set as db default From 4e3d6b4056de8359634cc938bcff39f7ef8a8183 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 6 Feb 2012 19:07:08 +0400 Subject: [PATCH 02/17] Show xml-rpc error code in error message --- app/models/repository.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 29cb61fff..379d3deac 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -57,7 +57,7 @@ class Repository < ActiveRecord::Base if result == BuildServer::SUCCESS return true else - raise "Failed to delete repository #{name} inside platform #{platform.name}." + raise "Failed to delete repository #{name} inside platform #{platform.name} with code #{result}." end end From 36f609ec7ddbc2580312c949fc2a3a1e5528ea72 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 7 Feb 2012 01:47:39 +0600 Subject: [PATCH 03/17] [refs #143] fix destroy --- app/models/group.rb | 4 ++-- db/migrate/20120206194328_remove_orphan_platforms.rb | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20120206194328_remove_orphan_platforms.rb diff --git a/app/models/group.rb b/app/models/group.rb index a720995ef..bc89373d4 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -4,14 +4,14 @@ class Group < ActiveRecord::Base has_many :own_projects, :as => :owner, :class_name => 'Project' - has_many :relations, :as => :object, :dependent => :destroy has_many :objects, :as => :target, :class_name => 'Relation' has_many :targets, :as => :object, :class_name => 'Relation' has_many :members, :through => :objects, :source => :object, :source_type => 'User', :autosave => true has_many :projects, :through => :targets, :source => :target, :source_type => 'Project', :autosave => true - has_many :platforms, :through => :targets, :source => :target, :source_type => 'Platform', :autosave => true + has_many :platforms, :through => :targets, :source => :target, :source_type => 'Platform', :autosave => true, :dependent => :destroy has_many :repositories, :through => :targets, :source => :target, :source_type => 'Repository', :autosave => true + has_many :relations, :as => :object, :dependent => :destroy validates :name, :owner, :presence => true validates :uname, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /^[a-z0-9_]+$/ } diff --git a/db/migrate/20120206194328_remove_orphan_platforms.rb b/db/migrate/20120206194328_remove_orphan_platforms.rb new file mode 100644 index 000000000..aa922710a --- /dev/null +++ b/db/migrate/20120206194328_remove_orphan_platforms.rb @@ -0,0 +1,8 @@ +class RemoveOrphanPlatforms < ActiveRecord::Migration + def self.up + Platform.all.each {|x| x.destroy unless x.owner.present?} + end + + def self.down + end +end From 86704bc39d4eaf390c19fb59e761f40241ceac1c Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 7 Feb 2012 15:31:07 +0600 Subject: [PATCH 04/17] [refs #155] fix render event logs --- app/views/event_logs/_description.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/event_logs/_description.html.haml b/app/views/event_logs/_description.html.haml index 3d4606c91..eb6f9d25f 100644 --- a/app/views/event_logs/_description.html.haml +++ b/app/views/event_logs/_description.html.haml @@ -1,8 +1,8 @@ = surround '[', ']' do - = I18n.t "event_log.controllers.#{el.controller.underscore}", :default => lambda{el.controller} + = I18n.t "event_log.controllers.#{el.controller.underscore}", :default => el.controller = I18n.t "event_log.actions.#{el.controller.underscore}.#{el.action}", :default => :"event_log.actions.#{el.action}" - if el.object_id.present? and el.object_type.present? = I18n.t "activerecord.models.#{el.object_type.underscore}" = el.object_name = "(id##{el.object_id})" # link_to "id##{el.object_id}", el.object -= el.message \ No newline at end of file += el.message From 325667dde03cc1c30c26263652422c2b63a1d811 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 7 Feb 2012 17:31:00 +0600 Subject: [PATCH 05/17] [refs #168] removed wrong ability --- app/models/ability.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 735aaed2a..812098179 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -67,7 +67,6 @@ class Ability can :autocomplete_user_uname, Platform # TODO delegate to platform? - can :read, Repository, :visibility => 'open' can :read, Repository, :owner_type => 'User', :owner_id => user.id can :read, Repository, :owner_type => 'Group', :owner_id => user.group_ids can(:read, Repository, read_relations_for('repositories')) {|repository| local_reader? repository} From c47db562707c29231a7d5f7f10979b6265e5292a Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 7 Feb 2012 19:55:45 +0600 Subject: [PATCH 06/17] [refs #168] can read repos in the open platform --- app/models/ability.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/ability.rb b/app/models/ability.rb index 812098179..0ca631e51 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -67,6 +67,7 @@ class Ability can :autocomplete_user_uname, Platform # TODO delegate to platform? + can :read, Repository, :platform => {:visibility => 'open'} can :read, Repository, :owner_type => 'User', :owner_id => user.id can :read, Repository, :owner_type => 'Group', :owner_id => user.group_ids can(:read, Repository, read_relations_for('repositories')) {|repository| local_reader? repository} From 02217752af5e3c1b9f8d955e5b1d0d7ee0229755 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Wed, 8 Feb 2012 17:07:16 +0600 Subject: [PATCH 07/17] [refs #169] fix creating build list on empty repository --- app/controllers/build_lists_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 0104bee2d..9bed99bbf 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -49,7 +49,7 @@ class BuildListsController < ApplicationController Arch.where(:id => params[:arches]).each do |arch| Platform.main.where(:id => params[:bpls]).each do |bpl| @build_list = @project.build_lists.build(params[:build_list]) - @build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last || @build_list.project_version).first.id + @build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last || @build_list.project_version).first.id if @build_list.project_version @build_list.bpl = bpl; @build_list.arch = arch; @build_list.user = current_user flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :bpl => bpl.name, :pl => @build_list.pl} if @build_list.save From ce39cdd04f4527400e51893192b5fec1b386f1a6 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 9 Feb 2012 21:46:23 +0400 Subject: [PATCH 08/17] [issue #174] A half of work to create invitations system --- .../register_requests_controller.rb | 32 +++++++++++++++++++ app/models/ability.rb | 3 ++ app/models/register_request.rb | 18 +++++++++++ app/models/user.rb | 2 +- app/views/devise/registrations/new.html.haml | 7 ++++ app/views/devise/shared/_links.haml | 5 +-- app/views/register_requests/index.html.haml | 27 ++++++++++++++++ app/views/register_requests/new.html.haml | 24 ++++++++++++++ app/views/users/index.html.haml | 1 + config/routes.rb | 10 +++++- ...20120209135822_create_register_requests.rb | 21 ++++++++++++ db/schema.rb | 29 +++++++++++------ spec/factories/register_requests.rb | 10 ++++++ spec/models/cancan_spec.rb | 25 +++++++++++++++ spec/models/register_request_spec.rb | 5 +++ 15 files changed, 206 insertions(+), 13 deletions(-) create mode 100644 app/controllers/register_requests_controller.rb create mode 100644 app/models/register_request.rb create mode 100644 app/views/register_requests/index.html.haml create mode 100644 app/views/register_requests/new.html.haml create mode 100644 db/migrate/20120209135822_create_register_requests.rb create mode 100644 spec/factories/register_requests.rb create mode 100644 spec/models/register_request_spec.rb diff --git a/app/controllers/register_requests_controller.rb b/app/controllers/register_requests_controller.rb new file mode 100644 index 000000000..78bd523cc --- /dev/null +++ b/app/controllers/register_requests_controller.rb @@ -0,0 +1,32 @@ +# -*- encoding : utf-8 -*- +class RegisterRequestsController < ApplicationController + load_and_authorize_resource + + def index + @register_requests = @register_requests.unprocessed.paginate(:page => params[:page]) + end + + def new + render :layout => 'sessions' + end + + def show_message + end + + def create + if @register_request = RegisterRequest.create(params[:register_request]) + redirect_to show_message_register_requests_path + else + redirect_to :action => :new + end + end + + def approve + @register_request.update_attributes(:approved => true, :rejected => false) + end + + def reject + @register_request.update_attributes(:approved => false, :rejected => true) + end +end + diff --git a/app/models/ability.rb b/app/models/ability.rb index 0ca631e51..741909db3 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -16,6 +16,7 @@ class Ability can :manage, :all cannot :destroy, Subscribe cannot :create, Subscribe + cannot :create, RegisterRequest else # Shared rights between guests and registered users can :forbidden, Platform @@ -26,6 +27,7 @@ class Ability if user.guest? # Guest rights can :create, User + can :create, RegisterRequest else # Registered user rights can [:show, :autocomplete_user_uname], User @@ -97,6 +99,7 @@ class Ability can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)} #cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues cannot(:manage, Comment) {|comment| comment.commentable_type == 'Issue' && !comment.commentable.project.has_issues} # switch off issues + cannot :manage, RegisterRequest end end diff --git a/app/models/register_request.rb b/app/models/register_request.rb new file mode 100644 index 000000000..216e0702c --- /dev/null +++ b/app/models/register_request.rb @@ -0,0 +1,18 @@ +class RegisterRequest < ActiveRecord::Base + default_scope order('created_at ASC') + + scope :rejected, where(:rejected => true) + scope :approved, where(:approved => true) + scope :unprocessed, where(:approved => false, :rejected => false) + + before_create :generate_token + + validate :name, :presence => true + validate :email, :presence => true, :uniqueness => {:case_sensitive => false} + + protected + + def generate_token + token = Digest::SHA1.hexdigest(name + email + Time.now.to_s + rand.to_s) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 314816ac0..69dac7a6a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,7 +4,7 @@ class User < ActiveRecord::Base LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']] LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last) - devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable + devise :database_authenticatable, :registerable, #:omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable has_one :notifier, :class_name => 'Settings::Notifier' #:notifier diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 5c9d0de5d..8438dc9ec 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -24,6 +24,13 @@ .right = f.text_field :name, :class => "text_field" + .group.wat-cf + .left + = f.label 'Token', :class => "label" + .right + = text_field_tag :token, '', :class => "text_field", :style => 'width: 70%' + = link_to t('get_token'), new_register_request_path, :style => 'display: inline-block; float: right' + - if resource.authentications.blank? .group.wat-cf .left diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index 958f5ec3c..3ae0900da 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -1,13 +1,14 @@ - if controller_name != 'sessions' = link_to t("layout.devise.shared_links.sign_in"), new_session_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.registerable? && controller_name != 'registrations' - = link_to t("layout.devise.shared_links.sign_up"), new_registration_path(resource_name), :class => "text_button_padding link_button" + =# link_to t("layout.devise.shared_links.sign_up"), new_registration_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.sign_up"), new_register_request_path, :class => "text_button_padding link_button" # to prereg form - if devise_mapping.recoverable? && controller_name != 'passwords' = link_to t("layout.devise.shared_links.forgot_password"), new_password_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.confirmable? && controller_name != 'confirmations' = link_to t("layout.devise.shared_links.confirm_again"), new_confirmation_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' = link_to t("layout.devise.shared_links.unlock"), new_unlock_path(resource_name), :class => "text_button_padding link_button" -- if devise_mapping.omniauthable? +-# if devise_mapping.omniauthable? - resource_class.omniauth_providers.each do |provider| = link_to t("layout.devise.shared_links.sign_in_through", :provider => provider.to_s.classify), omniauth_authorize_path(resource_name, provider), :class => "text_button_padding link_button" diff --git a/app/views/register_requests/index.html.haml b/app/views/register_requests/index.html.haml new file mode 100644 index 000000000..88eb17602 --- /dev/null +++ b/app/views/register_requests/index.html.haml @@ -0,0 +1,27 @@ +.block + .secondary-navigation + %ul.wat-cf + %li.first= link_to t("layout.users.list"), users_path + %li= link_to t("layout.users.new"), new_user_path + %li.active= link_to t("layout.users.register_requests"), register_requests_path + .content + %h2.title + = t("layout.register_request.list_header") + .inner + %table.table + %tr + %th= t("activerecord.attributes.register_request.name") + %th= t("activerecord.attributes.register_request.email") + %th= t("activerecord.attributes.register_request.created_at") + %th.last   + - @register_requests.each do |request| + %tr{:class => cycle("odd", "even")} + %td= request.name + %td= request.email + %td + = link_to t("layout.approve"), register_request_approve_path(request) if can? :approve, request + | + = link_to t("layout.reject"), register_request_reject_path(request) if can? :reject, request + .actions-bar.wat-cf + .actions + = will_paginate @register_requests diff --git a/app/views/register_requests/new.html.haml b/app/views/register_requests/new.html.haml new file mode 100644 index 000000000..5ff201c35 --- /dev/null +++ b/app/views/register_requests/new.html.haml @@ -0,0 +1,24 @@ +#block-login.block + %h2= title t("layout.register_request.get_token_header") + .content.login + - if flash.present? + .flash + - flash.each do |key, value| + .message{ :title => key.to_s.humanize, :class => (key == :alert ? "error" : key) } + %p= value + - form_for(@register_request, :html => { :class => "form login" }) do |f| + .group.wat-cf + .left + = f.label :name, :class => "label right" + .right + = f.text_field :name, :class => "text_field" + .group.wat-cf + .left + = f.label :email, :class => "label right" + .right + = f.text_field :email, :class => "text_field" + .group.navform.wat-cf + .right + %button.button{ :type => "submit" } + = t("layout.register_request.get_token_button") + %span.text_button_padding diff --git a/app/views/users/index.html.haml b/app/views/users/index.html.haml index 92ce0aef8..f48d594f0 100644 --- a/app/views/users/index.html.haml +++ b/app/views/users/index.html.haml @@ -3,6 +3,7 @@ %ul.wat-cf %li.first.active= link_to t("layout.users.list"), users_path %li= link_to t("layout.users.new"), new_user_path + %li= link_to t("layout.users.register_requests"), register_requests_path if can? :read, RegisterRequest .content %h2.title = t("layout.users.list_header") diff --git a/config/routes.rb b/config/routes.rb index c26020d1e..b4922adc2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,7 +9,15 @@ Rosa::Application.routes.draw do resources :users do resources :groups, :only => [:new, :create, :index] - get :autocomplete_user_uname, :on => :collection + collection do + resources :register_requests, :only => [:index, :new, :create, :show_message, :approve, :reject] do + get :show_message, :on => :collection + get :approve + get :reject + end + get :autocomplete_user_uname + end + namespace :settings do resource :notifier, :only => [:show, :update] end diff --git a/db/migrate/20120209135822_create_register_requests.rb b/db/migrate/20120209135822_create_register_requests.rb new file mode 100644 index 000000000..6ae743fa7 --- /dev/null +++ b/db/migrate/20120209135822_create_register_requests.rb @@ -0,0 +1,21 @@ +class CreateRegisterRequests < ActiveRecord::Migration + def self.up + create_table :register_requests do |t| + t.string :name + t.string :email + t.string :token + t.boolean :approved, :default => false + t.boolean :rejected, :default => false + + t.timestamps + end + add_index :register_requests, [:email], :unique => true, :case_sensitive => false + add_index :register_requests, [:token], :unique => true, :case_sensitive => false + end + + def self.down + remove_index :register_requests, [:email] + remove_index :register_requests, [:token] + drop_table :register_requests + end +end diff --git a/db/schema.rb b/db/schema.rb index ad2ca6d65..33856c334 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120131124517) do +ActiveRecord::Schema.define(:version => 20120209135822) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -253,15 +253,27 @@ ActiveRecord::Schema.define(:version => 20120131124517) do t.text "description" t.string "ancestry" t.boolean "has_issues", :default => true + t.boolean "has_wiki", :default => false t.string "srpm_file_name" t.string "srpm_content_type" t.integer "srpm_file_size" t.datetime "srpm_updated_at" - t.boolean "has_wiki", :default => false end add_index "projects", ["category_id"], :name => "index_projects_on_category_id" - add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false + add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true + + create_table "register_requests", :force => true do |t| + t.string "name" + t.string "email" + t.string "token" + t.boolean "approved", :default => false + t.boolean "rejected", :default => false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "register_requests", ["email"], :name => "index_register_requests_on_email", :unique => true, :case_sensitive => false create_table "relations", :force => true do |t| t.integer "object_id" @@ -320,19 +332,18 @@ ActiveRecord::Schema.define(:version => 20120131124517) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false - t.string "password_salt", :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" - t.string "remember_token" + t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" t.text "ssh_key" t.string "uname" t.string "role" - t.string "language", :default => "en" - t.integer "own_projects_count", :default => 0, :null => false + t.string "language", :default => "en" + t.integer "own_projects_count", :default => 0, :null => false end add_index "users", ["email"], :name => "index_users_on_email", :unique => true diff --git a/spec/factories/register_requests.rb b/spec/factories/register_requests.rb new file mode 100644 index 000000000..7fd9c1446 --- /dev/null +++ b/spec/factories/register_requests.rb @@ -0,0 +1,10 @@ +# Read about factories at http://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :register_request do + name "MyString" + email "MyString" + token "MyString" + approved false + end +end diff --git a/spec/models/cancan_spec.rb b/spec/models/cancan_spec.rb index 8b48e44f6..597d5dd38 100644 --- a/spec/models/cancan_spec.rb +++ b/spec/models/cancan_spec.rb @@ -22,6 +22,7 @@ describe CanCan do let(:personal_repository) { Factory(:personal_repository) } let(:open_platform) { Factory(:platform, :visibility => 'open') } let(:hidden_platform) { Factory(:platform, :visibility => 'hidden') } + let(:register_request) { Factory(:register_request) } before(:each) do stub_rsync_methods @@ -44,6 +45,10 @@ describe CanCan do it 'should not be able to destroy personal repositories' do @ability.should_not be_able_to(:destroy, personal_repository) end + + it 'should not be able to create new register requests' do + @ability.should_not be_able_to(:create, RegisterRequest) + end end context 'Site guest' do @@ -69,6 +74,22 @@ describe CanCan do end end + it 'should be able to create register request' do + @ability.should be_able_to(:create, RegisterRequest) + end + + it 'should not be able to update register request' do + @ability.should_not be_able_to(:update, register_request) + end + + it 'should not be able to list register requests' do + @ability.should_not be_able_to(:read, register_request) + end + + it 'should not be able to destroy register requests' do + @ability.should_not be_able_to(:destroy, register_request) + end + it 'should be able to register new user' do @ability.should be_able_to(:create, User) end @@ -105,6 +126,10 @@ describe CanCan do @ability.should be_able_to(:create, Project) end + it "should not be able to manage register requests" do + @ability.should_not be_able_to(:manage, RegisterRequest) + end + context "private users relations" do before(:each) do @private_user = Factory(:private_user) diff --git a/spec/models/register_request_spec.rb b/spec/models/register_request_spec.rb new file mode 100644 index 000000000..eea8bb192 --- /dev/null +++ b/spec/models/register_request_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe RegisterRequest do + pending "add some examples to (or delete) #{__FILE__}" +end From edef21068d5a59b95764e6fa4768e5e00ac48d28 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 10 Feb 2012 01:44:47 +0400 Subject: [PATCH 09/17] [issue #174] Fixed bug with RegisterRequest --- Gemfile | 2 +- app/models/register_request.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index dd9ed33ea..248704ebd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,6 @@ source 'http://rubygems.org' gem 'rails', '3.0.11' #, :git => 'git://github.com/rails/rails.git' -gem 'shotgun' gem 'pg', '~> 0.11.0' gem 'silent-postgres', '~> 0.1.1' @@ -61,6 +60,7 @@ group :development do gem 'ruby_parser' gem 'hirb' + gem 'shotgun' # deploy gem 'capistrano', :require => false diff --git a/app/models/register_request.rb b/app/models/register_request.rb index 216e0702c..d59416607 100644 --- a/app/models/register_request.rb +++ b/app/models/register_request.rb @@ -13,6 +13,6 @@ class RegisterRequest < ActiveRecord::Base protected def generate_token - token = Digest::SHA1.hexdigest(name + email + Time.now.to_s + rand.to_s) + self.token = Digest::SHA1.hexdigest(name + email + Time.now.to_s + rand.to_s) end end From f9e7f3fb06f00d230c25e3a2c45798245b5f8fda Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 10 Feb 2012 01:45:26 +0400 Subject: [PATCH 10/17] [issue #174] Devise hacks --- app/views/devise/registrations/new.html.haml | 10 +--- lib/preregistration/devise/preregistration.rb | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 lib/preregistration/devise/preregistration.rb diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 8438dc9ec..5b6ba193c 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -2,6 +2,7 @@ %h2= title t("devise.registrations.sign_up_header") .content = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :class => "form" }) do |f| + = hidden_field_tag :invitation_token, @invitation_token - if resource.errors.present? .flash .message.error= resource.errors.full_messages.map { |msg| content_tag(:p, msg) }.join.html_safe @@ -16,7 +17,7 @@ .left = f.label :email, :class => "label" .right - = f.text_field :email, :class => "text_field" + = f.text_field :email, :class => "text_field", :readonly => 'readonly' .group.wat-cf .left @@ -24,13 +25,6 @@ .right = f.text_field :name, :class => "text_field" - .group.wat-cf - .left - = f.label 'Token', :class => "label" - .right - = text_field_tag :token, '', :class => "text_field", :style => 'width: 70%' - = link_to t('get_token'), new_register_request_path, :style => 'display: inline-block; float: right' - - if resource.authentications.blank? .group.wat-cf .left diff --git a/lib/preregistration/devise/preregistration.rb b/lib/preregistration/devise/preregistration.rb new file mode 100644 index 000000000..da2635184 --- /dev/null +++ b/lib/preregistration/devise/preregistration.rb @@ -0,0 +1,59 @@ +# -*- encoding : utf-8 -*- +module Preregistration + module Devise + module RegistrationsController + extend ActiveSupport::Concern + + included do + alias_method_chain :create, :token + alias_method_chain :new, :token + end + + def new_with_token + if params['invitation_token'] + req = RegisterRequest.approved.where(:token => params['invitation_token'].strip).first + redirect_to new_register_request_path and return unless req + + resource = build_resource({}) + resource.name = req.name if resource.respond_to? :name + resource.email = req.email if resource.respond_to? :email + @invitation_token = req.token + + respond_with_navigational(resource){ render_with_scope :new } + else + redirect_to new_register_request_path + end + end + + def create_with_token + redirect_to new_register_request_path and return unless params['invitation_token'] + req = RegisterRequest.approved.where(:token => params['invitation_token'].strip).first + + build_resource + + redirect_to new_register_request_path and return unless req and resource.email == req.email + + @invitation_token = req.token + if resource.save + if resource.active_for_authentication? + set_flash_message :notice, :signed_up if is_navigational_format? + sign_in(resource_name, resource) + respond_with resource, :location => after_sign_up_path_for(resource) + else + set_flash_message :notice, :inactive_signed_up, :reason => inactive_reason(resource) if is_navigational_format? + expire_session_data_after_sign_in! + respond_with resource, :location => after_inactive_sign_up_path_for(resource) + end + else + clean_up_passwords(resource) + respond_with_navigational(resource) { render_with_scope :new } + end + end + + end #RegistrationsController + end #Devise +end #Preregistration + +Rails.application.config.to_prepare do + ::Devise::RegistrationsController.send :include, Preregistration::Devise::RegistrationsController +end From d0fe7f55d5121c4599c1a85f9b6b45a37c375312 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 10 Feb 2012 02:55:28 +0400 Subject: [PATCH 11/17] [issue #174] added static pages and some changes --- .../register_requests_controller.rb | 18 +- app/models/ability.rb | 2 +- app/models/register_request.rb | 2 +- app/views/register_requests/index.html.haml | 48 ++-- config/routes.rb | 1 + public/invite.html | 94 +++++++ public/pics/bg-signup.png | Bin 0 -> 2923 bytes public/pics/bg.png | Bin 0 -> 1433 bytes public/pics/button-green-disabled.png | Bin 0 -> 2852 bytes public/pics/button-green-hover.png | Bin 0 -> 2865 bytes public/pics/button-green-normal.png | Bin 0 -> 2853 bytes public/pics/button-green-press.png | Bin 0 -> 2830 bytes public/pics/flag.png | Bin 0 -> 3016 bytes public/pics/logo.png | Bin 0 -> 5695 bytes public/pics/square.png | Bin 0 -> 2815 bytes public/styles/prereg.css | 233 ++++++++++++++++++ public/thanks.html | 61 +++++ 17 files changed, 438 insertions(+), 21 deletions(-) create mode 100644 public/invite.html create mode 100644 public/pics/bg-signup.png create mode 100644 public/pics/bg.png create mode 100644 public/pics/button-green-disabled.png create mode 100644 public/pics/button-green-hover.png create mode 100644 public/pics/button-green-normal.png create mode 100644 public/pics/button-green-press.png create mode 100644 public/pics/flag.png create mode 100644 public/pics/logo.png create mode 100644 public/pics/square.png create mode 100644 public/styles/prereg.css create mode 100644 public/thanks.html diff --git a/app/controllers/register_requests_controller.rb b/app/controllers/register_requests_controller.rb index 78bd523cc..1c2c9ef35 100644 --- a/app/controllers/register_requests_controller.rb +++ b/app/controllers/register_requests_controller.rb @@ -7,26 +7,34 @@ class RegisterRequestsController < ApplicationController end def new - render :layout => 'sessions' +# render :layout => 'sessions' + redirect_to '/invite.html' end def show_message end def create - if @register_request = RegisterRequest.create(params[:register_request]) - redirect_to show_message_register_requests_path - else - redirect_to :action => :new + RegisterRequest.create(params[:register_request]) + redirect_to '/thanks.html' #show_message_register_requests_path + end + + def update + case params[:update_type] + when 'approve' # see approve method + when 'reject' # see reject method end + redirect_to :action => :index end def approve @register_request.update_attributes(:approved => true, :rejected => false) + redirect_to :action => :index end def reject @register_request.update_attributes(:approved => false, :rejected => true) + redirect_to :action => :index end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 741909db3..113b50dd1 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -27,7 +27,7 @@ class Ability if user.guest? # Guest rights can :create, User - can :create, RegisterRequest + can [:create, :show_message], RegisterRequest else # Registered user rights can [:show, :autocomplete_user_uname], User diff --git a/app/models/register_request.rb b/app/models/register_request.rb index d59416607..ba4fb2295 100644 --- a/app/models/register_request.rb +++ b/app/models/register_request.rb @@ -8,7 +8,7 @@ class RegisterRequest < ActiveRecord::Base before_create :generate_token validate :name, :presence => true - validate :email, :presence => true, :uniqueness => {:case_sensitive => false} + validate :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } protected diff --git a/app/views/register_requests/index.html.haml b/app/views/register_requests/index.html.haml index 88eb17602..a5fcb474d 100644 --- a/app/views/register_requests/index.html.haml +++ b/app/views/register_requests/index.html.haml @@ -8,20 +8,40 @@ %h2.title = t("layout.register_request.list_header") .inner - %table.table - %tr - %th= t("activerecord.attributes.register_request.name") - %th= t("activerecord.attributes.register_request.email") - %th= t("activerecord.attributes.register_request.created_at") - %th.last   - - @register_requests.each do |request| - %tr{:class => cycle("odd", "even")} - %td= request.name - %td= request.email - %td - = link_to t("layout.approve"), register_request_approve_path(request) if can? :approve, request - | - = link_to t("layout.reject"), register_request_reject_path(request) if can? :reject, request + = form_tag register_requests_path, :method => :put, :class => 'update_form' do + = hidden_field_tag 'update_type' + %table.table + %tr + %th   + %th= t("activerecord.attributes.register_request.name") + %th= t("activerecord.attributes.register_request.email") + %th= t("activerecord.attributes.register_request.created_at") + %th.last   + - @register_requests.each do |request| + %tr{:class => cycle("odd", "even")} + %td= check_box_tag 'request_ids[]', request.id + %td= request.name + %td= request.email + %td + = link_to t("layout.approve"), register_request_approve_path(request) if can? :approve, request + | + = link_to t("layout.reject"), register_request_reject_path(request) if can? :reject, request .actions-bar.wat-cf .actions + = submit_tag t("layout.register_request.approve_selected"), :class => 'approve_registration' + = submit_tag t("layout.register_request.reject_selected"), :class => 'reject_registration' + .pagination = will_paginate @register_requests +:javascript + $(function() { + var form = $('form.update_form') + var change_update_type = function (type) { + $('input#update_type').val(type); + }; + $('.approve_registration').live('click', function(e) { + //set update_type to 'approve' + }); + $('.approve_registration').live('click', function(e) { + //set update_type to 'reject' + }); + }); diff --git a/config/routes.rb b/config/routes.rb index b4922adc2..0ec6e9dcd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,6 +12,7 @@ Rosa::Application.routes.draw do collection do resources :register_requests, :only => [:index, :new, :create, :show_message, :approve, :reject] do get :show_message, :on => :collection + put :update, :on => :collection get :approve get :reject end diff --git a/public/invite.html b/public/invite.html new file mode 100644 index 000000000..32ac74325 --- /dev/null +++ b/public/invite.html @@ -0,0 +1,94 @@ + + + + + Сборочная среда + + + + +
+ +
+ + +
+ Платформа разработки и управления жизненным циклом дистрибутивов: от исходного кода до ISO-образов +
+ +
+
+
+ + +
+
+

Здравствуйте, вы попали на страницу нашего нового сервиса ABF, который сейчас проходит тестирование.

+ Это проект универсального build-сервера ABF, цель которого — автоматизировать согласование зависимостей при пересборке пакетов, облегчить работу билд-менеджеров, гарантировать, что все пакеты в образе собраны без конфликтов друг с другом.

+ FAQ + Документация + Обсуждение +

+ +
+
+ + +
+
+
+

+ В настоящее время сервис работает в закрытом режиме.


+ Оставьте оставьте свои контактные данные в форме ниже, если хотите поучаствовать в тестировании. +

+ + +
+
+ + +
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + + + diff --git a/public/pics/bg-signup.png b/public/pics/bg-signup.png new file mode 100644 index 0000000000000000000000000000000000000000..79676f1614ab0dc45d49e5d4c94789890057ff2a GIT binary patch literal 2923 zcmV-x3zYPUP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0001%Nkl*KI!lU_oD3(7@Zy zAcuI*K?hQDVnG9okS%vv-abi!NdgbD1Z<2I_IS!tvjV6bmxPB|WsU0;OIS)BsPmz? z@~%nyS)}wnFvY7wqW&eEteM~O;~fFj{7hQZ)j-l)ZkkLi?`-MA#rKIAB(q4ba{%cu V1R^3gA6@_e002ovPDHLkV1gr$Y>)r| literal 0 HcmV?d00001 diff --git a/public/pics/bg.png b/public/pics/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..62e74e049553094021ff0203220b8b0fef1ec9d3 GIT binary patch literal 1433 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 literal 0 HcmV?d00001 diff --git a/public/pics/flag.png b/public/pics/flag.png new file mode 100644 index 0000000000000000000000000000000000000000..85b84ce4fb597341b055fbdd3068f01b071b3f08 GIT binary patch literal 3016 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 + + + + Сборочная среда + + + + +
+ +
+ + +
+ Платформа разработки и управления жизненным циклом дистрибутивов: от исходного кода до ISO-образов +
+ +
+
+
+ + +
+
+

Спасибо!

+ Благодарим за интерес к нашему сервису ABF!
+ Приглашение будет выслано вам по указанной электронной почте.

+ Ваши замечания-комментарии-пожелания ждем по адресу: _____

+ Подробнее с ABF можно ознакомиться по ссылкам:

+ FAQ + Документация + Обсуждение +

+
+ +
+
+
+ +
+ + + + \ No newline at end of file From e535ca2b641cd147cd498c53d89493843d83e8e5 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Fri, 10 Feb 2012 01:33:06 +0200 Subject: [PATCH 12/17] Fix validations. Refs #174 --- app/models/register_request.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/register_request.rb b/app/models/register_request.rb index ba4fb2295..50203ba0c 100644 --- a/app/models/register_request.rb +++ b/app/models/register_request.rb @@ -7,8 +7,8 @@ class RegisterRequest < ActiveRecord::Base before_create :generate_token - validate :name, :presence => true - validate :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } + validates :name, :presence => true + validates :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } protected From a17f5481689b6009e2ac4fa3f4501f5a0642c5c0 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 10 Feb 2012 14:04:15 +0400 Subject: [PATCH 13/17] [issue #174] Fixed bugs --- app/controllers/register_requests_controller.rb | 9 ++++++++- app/views/register_requests/index.html.haml | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/register_requests_controller.rb b/app/controllers/register_requests_controller.rb index 1c2c9ef35..7204458ed 100644 --- a/app/controllers/register_requests_controller.rb +++ b/app/controllers/register_requests_controller.rb @@ -2,6 +2,8 @@ class RegisterRequestsController < ApplicationController load_and_authorize_resource + before_filter :find_register_request, :only => [:approve, :reject] + def index @register_requests = @register_requests.unprocessed.paginate(:page => params[:page]) end @@ -36,5 +38,10 @@ class RegisterRequestsController < ApplicationController @register_request.update_attributes(:approved => false, :rejected => true) redirect_to :action => :index end -end + protected + + def find_register_request + @register_request = RegisterRequest.find(params[:register_request_id]) + end +end diff --git a/app/views/register_requests/index.html.haml b/app/views/register_requests/index.html.haml index a5fcb474d..2c50e6a0c 100644 --- a/app/views/register_requests/index.html.haml +++ b/app/views/register_requests/index.html.haml @@ -22,6 +22,7 @@ %td= check_box_tag 'request_ids[]', request.id %td= request.name %td= request.email + %td= request.created_at %td = link_to t("layout.approve"), register_request_approve_path(request) if can? :approve, request | From 8417e8c16f6077ea9d9b8fa6d38131fafe77da2f Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 10 Feb 2012 15:18:40 +0400 Subject: [PATCH 14/17] [issue #174] multiupdate in admin view. --- app/controllers/register_requests_controller.rb | 11 ++++++++--- app/views/register_requests/index.html.haml | 16 +++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/controllers/register_requests_controller.rb b/app/controllers/register_requests_controller.rb index 7204458ed..74ddd6627 100644 --- a/app/controllers/register_requests_controller.rb +++ b/app/controllers/register_requests_controller.rb @@ -22,9 +22,14 @@ class RegisterRequestsController < ApplicationController end def update - case params[:update_type] - when 'approve' # see approve method - when 'reject' # see reject method + if params[:update_type].present? and params[:request_ids].present? + updates = RegisterRequest.where(:id => params[:request_ids]) + case params[:update_type] + when 'approve' # see approve method + updates.each {|req| req.update_attributes(:approved => true, :rejected => false)} + when 'reject' # see reject method + updates.each {|req| req.update_attributes(:approved => false, :rejected => true)} + end end redirect_to :action => :index end diff --git a/app/views/register_requests/index.html.haml b/app/views/register_requests/index.html.haml index 2c50e6a0c..4720b8c83 100644 --- a/app/views/register_requests/index.html.haml +++ b/app/views/register_requests/index.html.haml @@ -29,20 +29,26 @@ = link_to t("layout.reject"), register_request_reject_path(request) if can? :reject, request .actions-bar.wat-cf .actions - = submit_tag t("layout.register_request.approve_selected"), :class => 'approve_registration' - = submit_tag t("layout.register_request.reject_selected"), :class => 'reject_registration' + + + =# button_tag t("layout.register_request.approve_selected"), :class => 'approve_registration' + =# button_tag t("layout.register_request.reject_selected"), :class => 'reject_registration' .pagination = will_paginate @register_requests :javascript $(function() { - var form = $('form.update_form') + var $form = $('form.update_form') var change_update_type = function (type) { $('input#update_type').val(type); }; - $('.approve_registration').live('click', function(e) { + $('#approve_registration').live('click', function(e) { //set update_type to 'approve' + change_update_type('approve'); + $form.submit(); }); - $('.approve_registration').live('click', function(e) { + $('#reject_registration').live('click', function(e) { //set update_type to 'reject' + change_update_type('reject'); + $form.submit(); }); }); From 704c544cbc7a757e317c6f21329bea2a375cf930 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Fri, 10 Feb 2012 18:33:16 +0200 Subject: [PATCH 15/17] Add more register_requests fields, change design. Apply invitation mail sending. Refactor. Refs #174 --- Gemfile | 2 +- Gemfile.lock | 22 ++++++++++ app/mailers/user_mailer.rb | 5 +++ app/models/register_request.rb | 15 +++++-- app/views/register_requests/index.html.haml | 6 ++- .../invite_approve_notification.html.haml | 7 +++ config/environments/development.rb | 2 + config/locales/en.yml | 1 + config/locales/ru.yml | 1 + ...53_add_more_fields_to_register_requests.rb | 11 +++++ db/schema.rb | 14 +++--- public/invite.html | 43 +++++++++++++------ public/styles/prereg.css | 20 ++++++--- public/thanks.html | 16 +++---- 14 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 app/views/user_mailer/invite_approve_notification.html.haml create mode 100644 db/migrate/20120210141153_add_more_fields_to_register_requests.rb diff --git a/Gemfile b/Gemfile index 248704ebd..048bda1da 100644 --- a/Gemfile +++ b/Gemfile @@ -53,7 +53,7 @@ end gem 'newrelic_rpm' group :development do - # gem 'letter_opener' + gem 'mailcatcher' # 'letter_opener' gem 'rails3-generators' gem 'web-app-theme' gem 'hpricot' diff --git a/Gemfile.lock b/Gemfile.lock index d71c4ed97..1c497b240 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,6 +85,7 @@ GEM diff-lcs (1.1.3) erubis (2.6.6) abstract (>= 1.0.0) + eventmachine (0.12.10) expression_parser (0.9.0) factory_girl (2.3.2) activesupport @@ -121,6 +122,16 @@ GEM i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + mailcatcher (0.2.4) + eventmachine + haml + i18n + json + mail + sinatra + skinny (>= 0.1.2) + sqlite3-ruby + thin meta-tags (1.2.4) actionpack mime-types (1.17.2) @@ -212,7 +223,17 @@ GEM sinatra (1.2.8) rack (~> 1.1) tilt (>= 1.2.2, < 2.0) + skinny (0.2.0) + eventmachine (~> 0.12) + thin (~> 1.2) + sqlite3 (1.3.5) + sqlite3-ruby (1.3.3) + sqlite3 (>= 1.3.3) state_machine (1.1.2) + thin (1.3.1) + daemons (>= 1.0.9) + eventmachine (>= 0.12.6) + rack (>= 1.0.0) thor (0.14.6) tilt (1.3.3) treetop (1.4.10) @@ -260,6 +281,7 @@ DEPENDENCIES hirb hpricot jammit + mailcatcher meta-tags (~> 1.2.4) newrelic_rpm omniauth (~> 1.0.1) diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 4fcc5488b..6609ac427 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -33,4 +33,9 @@ class UserMailer < ActionMailer::Base format.html end end + + def invite_approve_notification(register_request) + @register_request = register_request + mail :to => register_request.email, :subject => I18n.t("notifications.subjects.invite_approve_notification") + end end diff --git a/app/models/register_request.rb b/app/models/register_request.rb index 50203ba0c..a0299556f 100644 --- a/app/models/register_request.rb +++ b/app/models/register_request.rb @@ -5,14 +5,21 @@ class RegisterRequest < ActiveRecord::Base scope :approved, where(:approved => true) scope :unprocessed, where(:approved => false, :rejected => false) - before_create :generate_token + # before_create :generate_token + before_update :invite_approve_notification - validates :name, :presence => true validates :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } protected - def generate_token - self.token = Digest::SHA1.hexdigest(name + email + Time.now.to_s + rand.to_s) + def generate_token + self.token = Digest::SHA1.hexdigest(name + email + Time.now.to_s + rand.to_s) + end + + def invite_approve_notification + if approved_changed? and approved == true + generate_token + UserMailer.invite_approve_notification(self).deliver end + end end diff --git a/app/views/register_requests/index.html.haml b/app/views/register_requests/index.html.haml index 4720b8c83..a860887aa 100644 --- a/app/views/register_requests/index.html.haml +++ b/app/views/register_requests/index.html.haml @@ -15,13 +15,17 @@ %th   %th= t("activerecord.attributes.register_request.name") %th= t("activerecord.attributes.register_request.email") + %th= t("activerecord.attributes.register_request.interest") + %th= t("activerecord.attributes.register_request.more") %th= t("activerecord.attributes.register_request.created_at") - %th.last   + %th - @register_requests.each do |request| %tr{:class => cycle("odd", "even")} %td= check_box_tag 'request_ids[]', request.id %td= request.name %td= request.email + %td= request.interest + %td= request.more %td= request.created_at %td = link_to t("layout.approve"), register_request_approve_path(request) if can? :approve, request diff --git a/app/views/user_mailer/invite_approve_notification.html.haml b/app/views/user_mailer/invite_approve_notification.html.haml new file mode 100644 index 000000000..d669eb178 --- /dev/null +++ b/app/views/user_mailer/invite_approve_notification.html.haml @@ -0,0 +1,7 @@ +%p== Здравствуйте, #{@register_request.name}. + +%p + Вы приглашены в проект ABF. Чтобы зарегистрироваться перейдите по + = link_to 'ссылке', new_user_registration_url(:invitation_token => @register_request.token) + +%p== Команда поддержки «ROSA Build System» diff --git a/config/environments/development.rb b/config/environments/development.rb index 3e4c691ae..38b0372c3 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -16,6 +16,8 @@ Rosa::Application.configure do # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false + config.action_mailer.delivery_method = :smtp # :letter_opener + config.action_mailer.smtp_settings = { :host => "localhost", :port => 1025 } config.action_mailer.default_url_options = { :host => 'localhost:3000' } # Print deprecation notices to the Rails logger diff --git a/config/locales/en.yml b/config/locales/en.yml index d864d5797..18777b03d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -946,6 +946,7 @@ en: new_user_notification: Registered on project «%{ project_name }» issue_assign_notification: New task assigned new_commit_comment_notification: New comment to commit + invite_approve_notification: Invitation to ABF project: category_id: Category diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c165f173a..e156c522f 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -793,3 +793,4 @@ ru: new_user_notification: Регистрация на проекте «%{ project_name }» issue_assign_notification: Вам назначили задачу new_commit_comment_notification: Новый комментарий к коммиту + invite_approve_notification: Приглашение в ABF diff --git a/db/migrate/20120210141153_add_more_fields_to_register_requests.rb b/db/migrate/20120210141153_add_more_fields_to_register_requests.rb new file mode 100644 index 000000000..cbe0dc71a --- /dev/null +++ b/db/migrate/20120210141153_add_more_fields_to_register_requests.rb @@ -0,0 +1,11 @@ +class AddMoreFieldsToRegisterRequests < ActiveRecord::Migration + def self.up + add_column :register_requests, :interest, :string + add_column :register_requests, :more, :text + end + + def self.down + remove_column :register_requests, :interest + remove_column :register_requests, :more + end +end diff --git a/db/schema.rb b/db/schema.rb index 33856c334..9e4ecacb8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120209135822) do +ActiveRecord::Schema.define(:version => 20120210141153) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -90,12 +90,12 @@ ActiveRecord::Schema.define(:version => 20120209135822) do end create_table "comments", :force => true do |t| - t.string "commentable_id" t.string "commentable_type" t.integer "user_id" t.text "body" t.datetime "created_at" t.datetime "updated_at" + t.decimal "commentable_id", :precision => 50, :scale => 0 end create_table "containers", :force => true do |t| @@ -117,6 +117,7 @@ ActiveRecord::Schema.define(:version => 20120209135822) do t.string "locked_by" t.datetime "created_at" t.datetime "updated_at" + t.string "queue" end add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" @@ -253,15 +254,15 @@ ActiveRecord::Schema.define(:version => 20120209135822) do t.text "description" t.string "ancestry" t.boolean "has_issues", :default => true - t.boolean "has_wiki", :default => false t.string "srpm_file_name" t.string "srpm_content_type" t.integer "srpm_file_size" t.datetime "srpm_updated_at" + t.boolean "has_wiki", :default => false end add_index "projects", ["category_id"], :name => "index_projects_on_category_id" - add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true + add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false create_table "register_requests", :force => true do |t| t.string "name" @@ -271,9 +272,12 @@ ActiveRecord::Schema.define(:version => 20120209135822) do t.boolean "rejected", :default => false t.datetime "created_at" t.datetime "updated_at" + t.string "interest" + t.text "more" end add_index "register_requests", ["email"], :name => "index_register_requests_on_email", :unique => true, :case_sensitive => false + add_index "register_requests", ["token"], :name => "index_register_requests_on_token", :unique => true, :case_sensitive => false create_table "relations", :force => true do |t| t.integer "object_id" @@ -335,7 +339,6 @@ ActiveRecord::Schema.define(:version => 20120209135822) do t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" - t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" @@ -343,6 +346,7 @@ ActiveRecord::Schema.define(:version => 20120209135822) do t.string "uname" t.string "role" t.string "language", :default => "en" + t.datetime "reset_password_sent_at" t.integer "own_projects_count", :default => 0, :null => false end diff --git a/public/invite.html b/public/invite.html index 32ac74325..32141fb72 100644 --- a/public/invite.html +++ b/public/invite.html @@ -3,7 +3,7 @@ Сборочная среда - + @@ -24,11 +24,12 @@
-

Здравствуйте, вы попали на страницу нашего нового сервиса ABF, который сейчас проходит тестирование.

- Это проект универсального build-сервера ABF, цель которого — автоматизировать согласование зависимостей при пересборке пакетов, облегчить работу билд-менеджеров, гарантировать, что все пакеты в образе собраны без конфликтов друг с другом.

- FAQ - Документация - Обсуждение +

+ Приветствуем Вас!

+ Вы находитесь на странице размещения заявок на участие в бета-тестировании сборочного сервиса ABF компании РОСА.

+ В первую очередь одобряются заявки от потенциальных майнтейнеров и представителей дистрибутивных команд.

+ Ознакомиться с документацией можно здесь.

+ Мы будем рады ответить на Ваши вопросы на форуме проекта.

@@ -37,13 +38,11 @@
+

Хочу стать бета-тестером ABF!

+
-

- В настоящее время сервис работает в закрытом режиме.


- Оставьте оставьте свои контактные данные в форме ниже, если хотите поучаствовать в тестировании. -

- + + +
+
+ + +
+
+
diff --git a/public/styles/prereg.css b/public/styles/prereg.css index 6950dddb4..b958cc409 100644 --- a/public/styles/prereg.css +++ b/public/styles/prereg.css @@ -104,7 +104,7 @@ article div.right { article div.left a { color: #FFF; - padding-right: 29px; +/* padding-right: 29px;*/ } article div.left a.last { @@ -117,7 +117,7 @@ article div.right p { article div.all a { color: #FFF; - padding-right: 29px; +/* padding-right: 29px;*/ } article div.all p { @@ -147,17 +147,27 @@ article div.signup-right { article div.signup-right input { height: 21px; - width: 170px; + width: 185px; border: 1px solid #8199a9; border-radius: 2px; - color: #cfcfcf; font-family: Tahoma; font-size: 12px; - padding-left: 10px; +/* padding-left: 10px;*/ margin-top: 6px; margin-top: 14px; margin-right: 15px; } +article div.signup-right textarea, article div.signup-right select { + width: 185px; + border: 1px solid #8199a9; + border-radius: 2px; + font-family: Tahoma; + font-size: 12px; + margin-top: 6px; + margin-top: 14px; + margin-right: 15px; +} +article div.signup-right select { width: 190px; } article div.button { float: right; diff --git a/public/thanks.html b/public/thanks.html index cf88c9a86..0979c0751 100644 --- a/public/thanks.html +++ b/public/thanks.html @@ -3,7 +3,7 @@ Сборочная среда - + @@ -24,14 +24,12 @@
-

Спасибо!

- Благодарим за интерес к нашему сервису ABF!
- Приглашение будет выслано вам по указанной электронной почте.

- Ваши замечания-комментарии-пожелания ждем по адресу: _____

- Подробнее с ABF можно ознакомиться по ссылкам:

- FAQ - Документация - Обсуждение +

+ Спасибо!

+ Благодарим за интерес к нашему сервису ABF!

+ Приглашение будет выслано вам по указанной электронной почте.

+ Приглашаем Вас на форум проекта, где мы будем рады ответить на Ваши вопросы и получить Ваши пожелания.

+ Ознакомиться с документацией можно здесь.

From 47399a957f582405354e47a372794b6f54ebb9df Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Sat, 11 Feb 2012 00:36:45 +0400 Subject: [PATCH 16/17] Update doc link --- public/invite.html | 2 +- public/thanks.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/invite.html b/public/invite.html index 32141fb72..f7b2a5416 100644 --- a/public/invite.html +++ b/public/invite.html @@ -28,7 +28,7 @@ Приветствуем Вас!

Вы находитесь на странице размещения заявок на участие в бета-тестировании сборочного сервиса ABF компании РОСА.

В первую очередь одобряются заявки от потенциальных майнтейнеров и представителей дистрибутивных команд.

- Ознакомиться с документацией можно здесь.

+ Ознакомиться с документацией можно здесь.

Мы будем рады ответить на Ваши вопросы на форуме проекта.

diff --git a/public/thanks.html b/public/thanks.html index 0979c0751..41aaabe92 100644 --- a/public/thanks.html +++ b/public/thanks.html @@ -29,7 +29,7 @@ Благодарим за интерес к нашему сервису ABF!

Приглашение будет выслано вам по указанной электронной почте.

Приглашаем Вас на форум проекта, где мы будем рады ответить на Ваши вопросы и получить Ваши пожелания.

- Ознакомиться с документацией можно здесь. + Ознакомиться с документацией можно здесь.

From 1356ffa43752be7a89cc43e11fb0449974991ef0 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 13 Feb 2012 14:23:20 +0400 Subject: [PATCH 17/17] [refs #178] Fix project create error with group owner --- app/models/group.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/group.rb b/app/models/group.rb index bc89373d4..c68147305 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -20,6 +20,7 @@ class Group < ActiveRecord::Base attr_readonly :uname, :own_projects_count delegate :ssh_key, :to => :owner + delegate :email, :to => :owner after_create :add_owner_to_members after_initialize lambda {|r| r.name ||= r.uname } # default