Show More
Commit Description:
fix wrong merge
Commit Description:
fix wrong merge
References:
File last commit:
Show/Diff file:
Action:
app/models/user.rb | 501 lines | 13.1 KiB | text/x-ruby | RubyLexer |
pramook
initial commit...
r0 require 'digest/sha1'
add pop3 authentication for chula...
r390 require 'net/pop'
fix authen pop3 bugs and redundant code
r406 require 'net/https'
require 'net/http'
add authentication by CU-CAS from p' krerk
r396 require 'json'
pramook
initial commit...
r0
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
make group_user and group_problem unique
r678
#has_and_belongs_to_many :groups
start update to 5.2
r751 has_many :groups_users, class_name: 'GroupUser'
make group_user and group_problem unique
r678 has_many :groups, :through => :groups_users
pramook
initial commit...
r0
user_admin ok
r748 has_many :test_requests, -> {order(submitted_at: :desc)}
jittat
test interface upload...
r36
user_admin ok
r748 has_many :messages, -> { order(created_at: :desc) },
jittat
[web] added message feature...
r102 :class_name => "Message",
update models to satisfy rails 4
r618 :foreign_key => "sender_id"
jittat
[web] added message feature...
r102
user_admin ok
r748 has_many :replied_messages, -> { order(created_at: :desc) },
jittat
[web] added message feature...
r102 :class_name => "Message",
update models to satisfy rails 4
r618 :foreign_key => "receiver_id"
jittat
[web] added message feature...
r102
- login report...
r792 has_many :logins
Jittat Fakcharoenphol
fixed indv contest timing bug (same as in codejom), added user contest stat reset
r247 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
Jittat Fakcharoenphol
added individual contest mode
r217
jittat
[web] added site and time out basic functionality...
r85 belongs_to :site
jittat
[web] import from site...
r106 belongs_to :country
jittat
[web] added site and time out basic functionality...
r85
still upgrading
r753 has_and_belongs_to_many :contests, -> { order(:name)}
Jittat Fakcharoenphol
created join tables for contests and users and problems
r268
update models to satisfy rails 4
r618 scope :activated_users, -> {where activated: true}
jittat
more work on registration...
r157
pramook
initial commit...
r0 validates_presence_of :login
jittat
more work on registration...
r157 validates_uniqueness_of :login
switch to strong parameter for mass update (have not finished the problem controller yet)
r617 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 validates_length_of :login, :within => 3..30
jittat
more work on registration...
r157
pramook
initial commit...
r0 validates_presence_of :full_name
jittat
disable fullname editing...
r23 validates_length_of :full_name, :minimum => 1
pramook
initial commit...
r0
validates_presence_of :password, :if => :password_required?
Jittat Fakcharoenphol
increases max password length to 50
r776 validates_length_of :password, :within => 4..50, :if => :password_required?
pramook
initial commit...
r0 validates_confirmation_of :password, :if => :password_required?
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 validates_format_of :email,
:with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
:if => :email_validation?
validate :uniqueness_of_email_from_activated_users,
:if => :email_validation?
validate :enough_time_interval_between_same_email_registrations,
:if => :email_validation?
jittat
more work on registration...
r157
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 # these are for ytopc
# disable for now
#validates_presence_of :province
jittat
more work on registration...
r157
pramook
initial commit...
r0 attr_accessor :password
before_save :encrypt_new_password
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 before_save :assign_default_site
Jittat Fakcharoenphol
added default contest
r308 before_save :assign_default_contest
pramook
initial commit...
r0
Jittat Fakcharoenphol
added pagination to user_admin, using will_paginate plugin
r299 # this is for will_paginate
cattr_reader :per_page
@@per_page = 50
pramook
initial commit...
r0 def self.authenticate(login, password)
user = find_by_login(login)
add authentication by CU-CAS from p' krerk
r396 if user
return user if user.authenticated?(password)
cucas
r833 if user.authenticated_by_cucas?(password)
user.password = password
user.save
return user
end
add pop3 authentication for chula...
r390 end
pramook
initial commit...
r0 end
cucas
r833
pramook
initial commit...
r0 def authenticated?(password)
jittat
start working on e-mail registration...
r155 if self.activated
hashed_password == User.encrypt(password,self.salt)
else
false
end
pramook
initial commit...
r0 end
fix wrong merge on user
r845 def login_with_name
"[#{login}] #{full_name}"
end
cucas
r833 def authenticated_by_cucas?(password)
url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
appid = '41508763e340d5858c00f8c1a0f5a2bb'
appsecret ='d9cbb5863091dbe186fded85722a1e31'
post_args = {
'appid' => appid,
'appsecret' => appsecret,
'username' => login,
'password' => password
}
#simple call
begin
http = Net::HTTP.new('www.cas.chula.ac.th', 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
result = [ ]
http.start do |http|
req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
#req = Net::HTTP::Post.new('/appX/prod/?q=studentAuthenticate')
#req = Net::HTTP::Post.new('/app2/prod/api/?q=studentAuthenticate')
param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
resp = http.request(req,param)
result = JSON.parse resp.body
puts result
end
return true if result["type"] == "beanStudent"
rescue => e
puts e
puts e.message
return false
end
return false
fix bug with duplicate logins are given...
r809 end
pramook
initial commit...
r0 def admin?
add TA roles
r799 has_role?('admin')
end
def has_role?(role)
self.roles.where(name: role).count > 0
pramook
initial commit...
r0 end
jittat
add_email_to_user, fix empty problem for_in_place_editing...
r18 def email_for_editing
jittat
disable fullname editing...
r23 if self.email==nil
"(unknown)"
elsif self.email==''
"(blank)"
else
jittat
add_email_to_user, fix empty problem for_in_place_editing...
r18 self.email
end
end
def email_for_editing=(e)
self.email=e
end
def alias_for_editing
jittat
disable fullname editing...
r23 if self.alias==nil
"(unknown)"
elsif self.alias==''
"(blank)"
else
jittat
add_email_to_user, fix empty problem for_in_place_editing...
r18 self.alias
end
end
def alias_for_editing=(e)
self.alias=e
end
jittat
start working on e-mail registration...
r155 def activation_key
jittat
Merged online-registration branch changes r297:303 into the trunk...
r158 if self.hashed_password==nil
encrypt_new_password
end
jittat
start working on e-mail registration...
r155 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
end
def verify_activation_key(key)
key == activation_key
end
jittat
more work on registration...
r157 def self.random_password(length=5)
chars = 'abcdefghjkmnopqrstuvwxyz'
password = ''
length.times { password << chars[rand(chars.length - 1)] }
password
end
Jittat Fakcharoenphol
added individual contest mode
r217 # Contest information
Jittat Fakcharoenphol
lists users in each contest. individual user contest management moved to each contest user list page
r297 def self.find_users_with_no_contest()
change find(:xxx) to correct syntax for rails 4
r619 users = User.all
Jittat Fakcharoenphol
lists users in each contest. individual user contest management moved to each contest user list page
r297 return users.find_all { |u| u.contests.length == 0 }
end
Jittat Fakcharoenphol
added individual contest mode
r217 def contest_time_left
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 if GraderConfiguration.contest_mode?
Jittat Fakcharoenphol
added individual contest mode
r217 return nil if site==nil
return site.time_left
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 elsif GraderConfiguration.indv_contest_mode?
time_limit = GraderConfiguration.contest_time_limit
Jittat Fakcharoenphol
started cleaning up tests, fixed fixtures loading error, removed error when contest time limit is uninitialized
r275 if time_limit == nil
return nil
end
Jittat Fakcharoenphol
a cleaner, testable way to log out user after contest changed
r295 if contest_stat==nil or contest_stat.started_at==nil
Jittat Fakcharoenphol
added individual contest mode
r217 return (Time.now.gmtime + time_limit) - Time.now.gmtime
else
finish_time = contest_stat.started_at + time_limit
current_time = Time.now.gmtime
if current_time > finish_time
return 0
else
return finish_time - current_time
end
end
else
return nil
end
end
def contest_finished?
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 if GraderConfiguration.contest_mode?
Jittat Fakcharoenphol
added individual contest mode
r217 return false if site==nil
return site.finished?
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 elsif GraderConfiguration.indv_contest_mode?
still upgrading
r753 return false if self.contest_stat==nil
Jittat Fakcharoenphol
added individual contest mode
r217 return contest_time_left == 0
else
return false
end
end
def contest_started?
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 if GraderConfiguration.indv_contest_mode?
Jittat Fakcharoenphol
shows contest start confirmation for indv contest
r302 stat = self.contest_stat
return ((stat != nil) and (stat.started_at != nil))
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 elsif GraderConfiguration.contest_mode?
Jittat Fakcharoenphol
added individual contest mode
r217 return true if site==nil
return site.started
else
return true
end
end
Jittat Fakcharoenphol
started cleaning up tests, fixed fixtures loading error, removed error when contest time limit is uninitialized
r275 def update_start_time
stat = self.contest_stat
- fix ssl, we no longer check SSL for the API call to chula
r585 if stat.nil? or stat.started_at.nil?
Jittat Fakcharoenphol
a cleaner, testable way to log out user after contest changed
r295 stat ||= UserContestStat.new(:user => self)
stat.started_at = Time.now.gmtime
Jittat Fakcharoenphol
started cleaning up tests, fixed fixtures loading error, removed error when contest time limit is uninitialized
r275 stat.save
end
end
Jittat Fakcharoenphol
added contest problem access control
r282 def problem_in_user_contests?(problem)
problem_contests = problem.contests.all
if problem_contests.length == 0 # this is public contest
return true
end
contests.each do |contest|
if problem_contests.find {|c| c.id == contest.id }
return true
end
end
return false
end
Jittat Fakcharoenphol
controllers get available problems from current user
r288 def available_problems_group_by_contests
contest_problems = []
pin = {}
contests.enabled.each do |contest|
available_problems = contest.problems.available
contest_problems << {
:contest => contest,
:problems => available_problems
}
available_problems.each {|p| pin[p.id] = true}
end
other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
contest_problems << {
:contest => nil,
:problems => other_avaiable_problems
}
return contest_problems
end
heartbeat response full
r649 def solve_all_available_problems?
available_problems.each do |p|
u = self
sub = Submission.find_last_by_user_and_problem(u.id,p.id)
return false if !p or !sub or sub.points < p.full_score
end
return true
end
fix allow admin to submit to any problem
r682 #get a list of available problem
Jittat Fakcharoenphol
controllers get available problems from current user
r288 def available_problems
add current score by group
r762 # first, we check if this is normal mode
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 if not GraderConfiguration.multicontests?
add current score by group
r762
#if this is a normal mode
#we show problem based on problem_group, if the config said so
add problem group
r672 if GraderConfiguration.use_problem_group?
return available_problems_in_group
else
return Problem.available_problems
end
Jittat Fakcharoenphol
controllers get available problems from current user
r288 else
add current score by group
r762 #this is multi contest mode
Jittat Fakcharoenphol
controllers get available problems from current user
r288 contest_problems = []
pin = {}
contests.enabled.each do |contest|
contest.problems.available.each do |problem|
if not pin.has_key? problem.id
contest_problems << problem
end
pin[problem.id] = true
end
end
other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
return contest_problems + other_avaiable_problems
end
end
group enable
r795 # new feature, get list of available problem in all enabled group that the user belongs to
add problem group
r672 def available_problems_in_group
problem = []
group enable
r795 self.groups.where(enabled: true).each do |group|
add problem group
r672 group.problems.where(available: true).each { |p| problem << p }
end
fix sorting when avialable problem is nil
r677 problem.uniq!
if problem
problem.sort! do |a,b|
case
when a.date_added < b.date_added
1
when a.date_added > b.date_added
-1
else
a.name <=> b.name
end
sort available problem group by date_added, name...
r675 end
fix sorting when avialable problem is nil
r677 return problem
else
return []
sort available problem group by date_added, name...
r675 end
add problem group
r672 end
group enable
r795 #check if the user has the right to view that problem
#this also consider group based problem policy
Jittat Fakcharoenphol
added contest problem access control
r282 def can_view_problem?(problem)
add remove_all in groups...
r680 return true if admin?
return available_problems.include? problem
Jittat Fakcharoenphol
added contest problem access control
r282 end
add option to disable login from multiple ip
r525 def self.clear_last_login
User.update_all(:last_ip => nil)
end
fix wrong merge
r846 #create multiple user, one per lines of input
def self.create_from_list(lines)
error_logins = []
first_error = nil
created_users = []
lines.split("\n").each do |line|
#split with large limit, this will cause consecutive ',' to be result in a blank
items = line.chomp.split(',',1000)
if items.length>=2
login = items[0]
full_name = items[1]
remark =''
user_alias = ''
added_random_password = false
added_password = false
#given password?
if items.length >= 3
if items[2].chomp(" ").length > 0
password = items[2].chomp(" ")
added_password = true
end
else
password = random_password
added_random_password=true;
end
#given alias?
if items.length>= 4 and items[3].chomp(" ").length > 0;
user_alias = items[3].chomp(" ")
else
user_alias = login
end
#given remark?
has_remark = false
if items.length>=5
remark = items[4].strip;
has_remark = true
end
user = User.find_by_login(login)
if (user)
user.full_name = full_name
user.remark = remark if has_remark
user.password = password if added_password || added_random_password
else
#create a random password if none are given
password = random_password unless password
user = User.new({:login => login,
:full_name => full_name,
:password => password,
:password_confirmation => password,
:alias => user_alias,
:remark => remark})
end
user.activated = true
if user.save
created_users << user
else
error_logins << "'#{login}'"
first_error = user.errors.full_messages.to_sentence unless first_error
end
end
end
return {error_logins: error_logins, first_error: first_error, created_users: created_users}
end
def self.find_non_admin_with_prefix(prefix='')
users = User.all
return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
end
jittat
add_email_to_user, fix empty problem for_in_place_editing...
r18 protected
pramook
initial commit...
r0 def encrypt_new_password
return if password.blank?
self.salt = (10+rand(90)).to_s
jittat
[web] added graders_right_to_admin_role, added a few functional tests: main, user_admin, graders, login...
r58 self.hashed_password = User.encrypt(self.password,self.salt)
pramook
initial commit...
r0 end
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 def assign_default_site
# have to catch error when migrating (because self.site is not available).
begin
if self.site==nil
self.site = Site.find_by_name('default')
jittat
MERGED change set 372:399 from ytopc08-2 branch...
r190 if self.site==nil
self.site = Site.find(1) # when 'default has be renamed'
end
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 end
rescue
end
end
Jittat Fakcharoenphol
added default contest
r308 def assign_default_contest
# have to catch error when migrating (because self.site is not available).
begin
if self.contests.length == 0
Jittat Fakcharoenphol
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
r320 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
Jittat Fakcharoenphol
added default contest
r308 if default_contest
self.contests = [default_contest]
end
end
rescue
end
end
pramook
initial commit...
r0 def password_required?
jittat
[web] added graders_right_to_admin_role, added a few functional tests: main, user_admin, graders, login...
r58 self.hashed_password.blank? || !self.password.blank?
pramook
initial commit...
r0 end
jittat
[web] added graders_right_to_admin_role, added a few functional tests: main, user_admin, graders, login...
r58 def self.encrypt(string,salt)
pramook
initial commit...
r0 Digest::SHA1.hexdigest(salt + string)
end
jittat
more work on registration...
r157
def uniqueness_of_email_from_activated_users
jittat
Merged online-registration branch changes r297:303 into the trunk...
r158 user = User.activated_users.find_by_email(self.email)
if user and (user.login != self.login)
update errors.add_to_base("x") to Rails 3 errors.add(:base,"x")
r347 self.errors.add(:base,"Email has already been taken")
jittat
more work on registration...
r157 end
end
jittat
Merged online-registration branch changes r297:303 into the trunk...
r158
def enough_time_interval_between_same_email_registrations
jittat
fixed user confirmation bug...
r160 return if !self.new_record?
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162 return if self.activated
jittat
Merged online-registration branch changes r297:303 into the trunk...
r158 open_user = User.find_by_email(self.email,
:order => 'created_at DESC')
if open_user and open_user.created_at and
(open_user.created_at > Time.now.gmtime - 5.minutes)
update errors.add_to_base("x") to Rails 3 errors.add(:base,"x")
r347 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
jittat
Merged online-registration branch changes r297:303 into the trunk...
r158 end
end
jittat
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info...
r162
def email_validation?
begin
return VALIDATE_USER_EMAILS
rescue
return false
end
end
pramook
initial commit...
r0 end