Description:
start working on e-mail registration git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@294 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r155:f1e975d4e9fc - - 14 files changed: 144 inserted, 8 deleted

@@ -0,0 +1,23
1 + class AddMoreOptionsToConfigurations < ActiveRecord::Migration
2 + def self.up
3 + # If the server is in contest mode and
4 + # Configuration['contest.multisites'] is true
5 + # the menu for site administrator is shown.
6 +
7 + Configuration.create(:key => 'contest.multisites',
8 + :value_type => 'boolean',
9 + :value => 'false')
10 +
11 + # If Configuration['system.online_registration'] is true,
12 + # the registration menu would appear
13 +
14 + Configuration.create(:key => 'system.online_registration',
15 + :value_type => 'boolean',
16 + :value => 'false')
17 + end
18 +
19 + def self.down
20 + Configuration.find_by_key('contest.multisites').destroy
21 + Configuration.find_by_key('system.online_registration').destroy
22 + end
23 + end
@@ -0,0 +1,15
1 + class AddActivatedToUsers < ActiveRecord::Migration
2 + def self.up
3 + add_column :users, :activated, :boolean, :default => 0
4 +
5 + User.find(:all).each do |user|
6 + user.activated = true
7 + user.save
8 + end
9 + end
10 +
11 +
12 + def self.down
13 + remove_column :users, :activated
14 + end
15 + end
@@ -0,0 +1,3
1 + #!/usr/bin/env ruby
2 + require File.dirname(__FILE__) + '/../config/boot'
3 + require 'commands/dbconsole'
@@ -0,0 +1,3
1 + #!/usr/bin/env ruby
2 + require File.dirname(__FILE__) + '/../../config/boot'
3 + require 'commands/performance/request'
@@ -0,0 +1,53
1 +
2 + require File.dirname(__FILE__) + '/../spec_helper'
3 +
4 + describe User do
5 +
6 + before(:each) do
7 + @password = "hello"
8 + @salt = "123"
9 + @john = stub_model(User, :salt => @salt,
10 + :hashed_password => User.encrypt(@password,@salt))
11 + end
12 +
13 + it "should authenticate activated user" do
14 + @john.should_receive(:activated).and_return(true)
15 + @john.authenticated?(@password).should == true
16 + end
17 +
18 + it "should not authenticate inactivated user" do
19 + @john.should_receive(:activated).and_return(false)
20 + @john.authenticated?(@password).should == false
21 + end
22 +
23 + it "should not authenticate user with incorrect password" do
24 + @john.should_receive(:activated).and_return(true)
25 + @john.should_receive(:hashed_password).and_return("byebye")
26 + @john.authenticated?(@password).should == false
27 + end
28 +
29 + end
30 +
31 + describe User, "during registration" do
32 +
33 + class User
34 + public :encrypt_new_password
35 + end
36 +
37 + before(:each) do
38 + @john = User.new(:login => 'john', :password => 'hello')
39 + @john.encrypt_new_password
40 + end
41 +
42 + it "should produce and accept activation key" do
43 + activation_key = @john.activation_key
44 +
45 + @john.verify_activation_key(activation_key).should == true
46 + end
47 +
48 + it "should not accept invalid activation key" do
49 + @john.verify_activation_key("12345").should == false
50 + end
51 +
52 +
53 + end
@@ -16,43 +16,45
16 end
16 end
17
17
18 def show
18 def show
19 @user = User.find(params[:id])
19 @user = User.find(params[:id])
20 end
20 end
21
21
22 def new
22 def new
23 @user = User.new
23 @user = User.new
24 end
24 end
25
25
26 def create
26 def create
27 @user = User.new(params[:user])
27 @user = User.new(params[:user])
28 + @user.activated = true
28 if @user.save
29 if @user.save
29 flash[:notice] = 'User was successfully created.'
30 flash[:notice] = 'User was successfully created.'
30 redirect_to :action => 'list'
31 redirect_to :action => 'list'
31 else
32 else
32 render :action => 'new'
33 render :action => 'new'
33 end
34 end
34 end
35 end
35
36
36 def create_from_list
37 def create_from_list
37 lines = params[:user_list]
38 lines = params[:user_list]
38 lines.split("\n").each do |line|
39 lines.split("\n").each do |line|
39 items = line.chomp.split(',')
40 items = line.chomp.split(',')
40 if items.length==4
41 if items.length==4
41 user = User.new
42 user = User.new
42 user.login = items[0]
43 user.login = items[0]
43 user.full_name = items[1]
44 user.full_name = items[1]
44 user.alias = items[2]
45 user.alias = items[2]
45 user.password = items[3]
46 user.password = items[3]
46 user.password_confirmation = items[3]
47 user.password_confirmation = items[3]
48 + user.activated = true
47 user.save
49 user.save
48 end
50 end
49 end
51 end
50 redirect_to :action => 'list'
52 redirect_to :action => 'list'
51 end
53 end
52
54
53 def edit
55 def edit
54 @user = User.find(params[:id])
56 @user = User.find(params[:id])
55 end
57 end
56
58
57 def update
59 def update
58 @user = User.find(params[:id])
60 @user = User.find(params[:id])
@@ -94,22 +94,26
94
94
95 def self.read_config
95 def self.read_config
96 @@configurations = {}
96 @@configurations = {}
97 Configuration.find(:all).each do |conf|
97 Configuration.find(:all).each do |conf|
98 key = conf.key
98 key = conf.key
99 val = conf.value
99 val = conf.value
100 @@configurations[key] = Configuration.convert_type(val,conf.value_type)
100 @@configurations[key] = Configuration.convert_type(val,conf.value_type)
101 end
101 end
102 end
102 end
103
103
104 def self.read_one_key(key)
104 def self.read_one_key(key)
105 conf = Configuration.find_by_key(key)
105 conf = Configuration.find_by_key(key)
106 - return Configuration.convert_type(conf.value,conf.value_type)
106 + if conf
107 + return Configuration.convert_type(conf.value,conf.value_type)
108 + else
109 + return nil
110 + end
107 end
111 end
108
112
109 def self.read_grading_info
113 def self.read_grading_info
110 f = File.open(TASK_GRADING_INFO_FILENAME)
114 f = File.open(TASK_GRADING_INFO_FILENAME)
111 @@task_grading_info = YAML.load(f)
115 @@task_grading_info = YAML.load(f)
112 f.close
116 f.close
113 end
117 end
114
118
115 end
119 end
@@ -28,25 +28,29
28 validates_confirmation_of :password, :if => :password_required?
28 validates_confirmation_of :password, :if => :password_required?
29
29
30 attr_accessor :password
30 attr_accessor :password
31
31
32 before_save :encrypt_new_password
32 before_save :encrypt_new_password
33
33
34 def self.authenticate(login, password)
34 def self.authenticate(login, password)
35 user = find_by_login(login)
35 user = find_by_login(login)
36 return user if user && user.authenticated?(password)
36 return user if user && user.authenticated?(password)
37 end
37 end
38
38
39 def authenticated?(password)
39 def authenticated?(password)
40 - hashed_password == User.encrypt(password,self.salt)
40 + if self.activated
41 + hashed_password == User.encrypt(password,self.salt)
42 + else
43 + false
44 + end
41 end
45 end
42
46
43 def admin?
47 def admin?
44 self.roles.detect {|r| r.name == 'admin' }
48 self.roles.detect {|r| r.name == 'admin' }
45 end
49 end
46
50
47 def email_for_editing
51 def email_for_editing
48 if self.email==nil
52 if self.email==nil
49 "(unknown)"
53 "(unknown)"
50 elsif self.email==''
54 elsif self.email==''
51 "(blank)"
55 "(blank)"
52 else
56 else
@@ -63,24 +67,32
63 "(unknown)"
67 "(unknown)"
64 elsif self.alias==''
68 elsif self.alias==''
65 "(blank)"
69 "(blank)"
66 else
70 else
67 self.alias
71 self.alias
68 end
72 end
69 end
73 end
70
74
71 def alias_for_editing=(e)
75 def alias_for_editing=(e)
72 self.alias=e
76 self.alias=e
73 end
77 end
74
78
79 + def activation_key
80 + Digest::SHA1.hexdigest(self.hashed_password)[0..7]
81 + end
82 +
83 + def verify_activation_key(key)
84 + key == activation_key
85 + end
86 +
75 protected
87 protected
76 def encrypt_new_password
88 def encrypt_new_password
77 return if password.blank?
89 return if password.blank?
78 self.salt = (10+rand(90)).to_s
90 self.salt = (10+rand(90)).to_s
79 self.hashed_password = User.encrypt(self.password,self.salt)
91 self.hashed_password = User.encrypt(self.password,self.salt)
80 end
92 end
81
93
82 def password_required?
94 def password_required?
83 self.hashed_password.blank? || !self.password.blank?
95 self.hashed_password.blank? || !self.password.blank?
84 end
96 end
85
97
86 def self.encrypt(string,salt)
98 def self.encrypt(string,salt)
@@ -21,25 +21,32
21 - form_tag :controller => 'login', :action => 'login' do
21 - form_tag :controller => 'login', :action => 'login' do
22 %table
22 %table
23 %tr
23 %tr
24 %td{:align => "right"} Login:
24 %td{:align => "right"} Login:
25 %td= text_field_tag 'login'
25 %td= text_field_tag 'login'
26 %tr
26 %tr
27 %td{:align => "right"} Password:
27 %td{:align => "right"} Password:
28 %td= password_field_tag
28 %td= password_field_tag
29 = submit_tag 'Login'
29 = submit_tag 'Login'
30
30
31 %br/
31 %br/
32
32
33 - - if Configuration['system.mode']=='contest'
33 + -# if Configuration['system.online_registration']
34 + Want to participate?
35 + %b
36 + Please
37 + = link_to 'register.', :controller => :users, :action => :new
38 + %br/
39 +
40 + - if (Configuration['system.mode']=='contest') and (Configuration['contest.multisites'])
34 %script{:type => 'text/javascript'}
41 %script{:type => 'text/javascript'}
35 var siteList = new Array();
42 var siteList = new Array();
36 - @countries.each do |country|
43 - @countries.each do |country|
37 = "siteList[#{country.id}] = new Array();"
44 = "siteList[#{country.id}] = new Array();"
38 - country.sites.each do |site|
45 - country.sites.each do |site|
39 = "siteList[#{country.id}][#{site.id}] = \"#{site.name}\";"
46 = "siteList[#{country.id}][#{site.id}] = \"#{site.name}\";"
40
47
41 var allSiteList = new Array();
48 var allSiteList = new Array();
42 - @site_select.each do |sel|
49 - @site_select.each do |sel|
43 = "allSiteList[#{sel[1]}]=\"#{sel[0]}\";"
50 = "allSiteList[#{sel[1]}]=\"#{sel[0]}\";"
44
51
45 %script{:type => 'text/javascript', :src => '/javascripts/site_update.js'}
52 %script{:type => 'text/javascript', :src => '/javascripts/site_update.js'}
@@ -73,32 +73,32
73 def gem_version
73 def gem_version
74 if defined? RAILS_GEM_VERSION
74 if defined? RAILS_GEM_VERSION
75 RAILS_GEM_VERSION
75 RAILS_GEM_VERSION
76 elsif ENV.include?('RAILS_GEM_VERSION')
76 elsif ENV.include?('RAILS_GEM_VERSION')
77 ENV['RAILS_GEM_VERSION']
77 ENV['RAILS_GEM_VERSION']
78 else
78 else
79 parse_gem_version(read_environment_rb)
79 parse_gem_version(read_environment_rb)
80 end
80 end
81 end
81 end
82
82
83 def load_rubygems
83 def load_rubygems
84 require 'rubygems'
84 require 'rubygems'
85 -
85 + min_version = '1.1.1'
86 - unless rubygems_version >= '0.9.4'
86 + unless rubygems_version >= min_version
87 - $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
87 + $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
88 exit 1
88 exit 1
89 end
89 end
90
90
91 rescue LoadError
91 rescue LoadError
92 - $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
92 + $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93 exit 1
93 exit 1
94 end
94 end
95
95
96 def parse_gem_version(text)
96 def parse_gem_version(text)
97 $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
97 $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
98 end
98 end
99
99
100 private
100 private
101 def read_environment_rb
101 def read_environment_rb
102 File.read("#{RAILS_ROOT}/config/environment.rb")
102 File.read("#{RAILS_ROOT}/config/environment.rb")
103 end
103 end
104 end
104 end
@@ -34,26 +34,33
34 # This is necessary if your schema can't be completely dumped by the schema dumper,
34 # This is necessary if your schema can't be completely dumped by the schema dumper,
35 # like if you have constraints or database-specific column types
35 # like if you have constraints or database-specific column types
36 # config.active_record.schema_format = :sql
36 # config.active_record.schema_format = :sql
37
37
38 # Activate observers that should always be running
38 # Activate observers that should always be running
39 # config.active_record.observers = :cacher, :garbage_collector
39 # config.active_record.observers = :cacher, :garbage_collector
40
40
41 # Make Active Record use UTC-base instead of local time
41 # Make Active Record use UTC-base instead of local time
42 config.active_record.default_timezone = :utc
42 config.active_record.default_timezone = :utc
43
43
44 # See Rails::Configuration for more options
44 # See Rails::Configuration for more options
45
45
46 + # -------------
47 + # Required gems
48 + # -------------
49 +
46 # This is for rspec
50 # This is for rspec
47 config.gem "rspec-rails", :lib => "spec"
51 config.gem "rspec-rails", :lib => "spec"
52 + config.gem "haml"
53 + config.gem "pony"
54 + #config.gem "BlueCloth", :lig => "bluecloth"
48 end
55 end
49
56
50 # Add new inflection rules using the following format
57 # Add new inflection rules using the following format
51 # (all these examples are active by default):
58 # (all these examples are active by default):
52 # Inflector.inflections do |inflect|
59 # Inflector.inflections do |inflect|
53 # inflect.plural /^(ox)$/i, '\1en'
60 # inflect.plural /^(ox)$/i, '\1en'
54 # inflect.singular /^(ox)en/i, '\1'
61 # inflect.singular /^(ox)en/i, '\1'
55 # inflect.irregular 'person', 'people'
62 # inflect.irregular 'person', 'people'
56 # inflect.uncountable %w( fish sheep )
63 # inflect.uncountable %w( fish sheep )
57 # end
64 # end
58
65
59 # Add new mime types for use in respond_to blocks:
66 # Add new mime types for use in respond_to blocks:
@@ -1,24 +1,24
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 20081107145815) do
12 + ActiveRecord::Schema.define(:version => 20081204122651) do
13
13
14 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 t.boolean "frontpage", :default => false
20 t.boolean "frontpage", :default => false
21 end
21 end
22
22
23 create_table "configurations", :force => true do |t|
23 create_table "configurations", :force => true do |t|
24 t.string "key"
24 t.string "key"
@@ -173,17 +173,18
173
173
174 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
174 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
175
175
176 create_table "users", :force => true do |t|
176 create_table "users", :force => true do |t|
177 t.string "login", :limit => 10
177 t.string "login", :limit => 10
178 t.string "full_name"
178 t.string "full_name"
179 t.string "hashed_password"
179 t.string "hashed_password"
180 t.string "salt", :limit => 5
180 t.string "salt", :limit => 5
181 t.string "alias"
181 t.string "alias"
182 t.string "email"
182 t.string "email"
183 t.integer "site_id"
183 t.integer "site_id"
184 t.integer "country_id"
184 t.integer "country_id"
185 + t.boolean "activated", :default => false
185 end
186 end
186
187
187 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
188 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
188
189
189 end
190 end
@@ -1,17 +1,22
1
1
2 require File.dirname(__FILE__) + '/../spec_helper'
2 require File.dirname(__FILE__) + '/../spec_helper'
3
3
4 describe Configuration do
4 describe Configuration do
5
5
6 + # only work with cached configuration
7 + class Configuration
8 + @@cache = true
9 + end
10 +
6 before(:each) do
11 before(:each) do
7 @int_config = mock(Configuration,
12 @int_config = mock(Configuration,
8 :id => 1,
13 :id => 1,
9 :key => 'mode',
14 :key => 'mode',
10 :value_type => 'integer',
15 :value_type => 'integer',
11 :value => '30')
16 :value => '30')
12
17
13 @string_config = mock(Configuration,
18 @string_config = mock(Configuration,
14 :id => 2,
19 :id => 2,
15 :key => 'title',
20 :key => 'title',
16 :value_type => 'string',
21 :value_type => 'string',
17 :value => 'Hello')
22 :value => 'Hello')
@@ -1,7 +1,8
1 begin
1 begin
2 require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here
2 require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here
3 rescue LoadError
3 rescue LoadError
4 require 'haml' # From gem
4 require 'haml' # From gem
5 end
5 end
6
6
7 + # Load Haml and Sass
7 Haml.init_rails(binding)
8 Haml.init_rails(binding)
You need to be logged in to leave comments. Login now