LOTS of stuff
This commit is contained in:
@@ -13,4 +13,12 @@ class Forum < ActiveRecord::Base
|
||||
def group
|
||||
forumgroup
|
||||
end
|
||||
end
|
||||
|
||||
def can_read?(user)
|
||||
group.can_read?(user) && (role_read.nil? || (!user.nil? && user.role >= role_read))
|
||||
end
|
||||
|
||||
def can_write?(user)
|
||||
group.can_read?(user) && can_read?(user) && (role_write.nil? || (!user.nil? && user.role >= role_write))
|
||||
end
|
||||
end
|
||||
@@ -12,4 +12,12 @@ class Forumgroup < ActiveRecord::Base
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def can_read?(user)
|
||||
role_read.nil? || (!user.nil? && user.role >= role_read)
|
||||
end
|
||||
|
||||
def can_write?(user)
|
||||
!user.nil? && can_read?(user) && user.confirmed? && (role_write.nil? || user.role >= role_write)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,11 +2,15 @@ class Forumthread < ActiveRecord::Base
|
||||
belongs_to :forum
|
||||
belongs_to :user_author, class_name: "User", foreign_key: "user_author_id"
|
||||
belongs_to :user_editor, class_name: "User", foreign_key: "user_editor_id"
|
||||
has_many :threadreplies
|
||||
|
||||
attr_accessible :title, :content, :sticky, :locked, :user_author, :user_editor, :forum
|
||||
|
||||
validates_presence_of :title
|
||||
validates_presence_of :title, :author, :forum
|
||||
validates_presence_of :content
|
||||
validates_length_of :content, in: 5..10000
|
||||
|
||||
accepts_nested_attributes_for :threadreplies
|
||||
|
||||
def to_s
|
||||
title
|
||||
@@ -23,4 +27,16 @@ class Forumthread < ActiveRecord::Base
|
||||
def editor
|
||||
@editor ||= user_editor
|
||||
end
|
||||
|
||||
def replies
|
||||
threadreplies
|
||||
end
|
||||
|
||||
def can_read?(user)
|
||||
forum.can_read?(user)
|
||||
end
|
||||
|
||||
def can_write?(user)
|
||||
forum.can_write?(user) && (!locked? || mod?)
|
||||
end
|
||||
end
|
||||
2
app/models/register_token.rb
Normal file
2
app/models/register_token.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
class RegisterToken < ActiveRecord::Base
|
||||
end
|
||||
@@ -25,20 +25,24 @@ class Role < ActiveRecord::Base
|
||||
elsif role.is_a?(Symbol)
|
||||
self <=> Role.find_by_name(role)
|
||||
else
|
||||
raise "Cannot compare Role with #{role.class}"
|
||||
self.to_i <=> role
|
||||
end
|
||||
end
|
||||
|
||||
def self.all_until (role)
|
||||
Role.all.select do |r|
|
||||
def self.all_to (role)
|
||||
Role.order(:value).select do |r|
|
||||
r <= role
|
||||
end
|
||||
end
|
||||
|
||||
def self.all_from(role)
|
||||
Role.all.select do |r|
|
||||
Role.order(:value).select do |r|
|
||||
r >= role
|
||||
end
|
||||
end
|
||||
|
||||
def self.all_from_to(from, to)
|
||||
Role.order(:value).select {|r| r >= from}.select {|r| r <= to}
|
||||
end
|
||||
|
||||
end
|
||||
22
app/models/threadreply.rb
Normal file
22
app/models/threadreply.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
class Threadreply < ActiveRecord::Base
|
||||
belongs_to :forumthread
|
||||
belongs_to :user_author, class_name: "User", foreign_key: "user_author_id"
|
||||
belongs_to :user_editor, class_name: "User", foreign_key: "user_editor_id"
|
||||
|
||||
attr_accessible :title, :content, :sticky, :locked, :user_author, :user_editor, :forumthread
|
||||
|
||||
validates_presence_of :content
|
||||
validates_length_of :content, in: 2..10000
|
||||
|
||||
def author
|
||||
@author ||= if self.user_author.present?
|
||||
user_author
|
||||
else
|
||||
User.first
|
||||
end
|
||||
end
|
||||
|
||||
def editor
|
||||
@editor ||= user_editor
|
||||
end
|
||||
end
|
||||
@@ -1,34 +1,43 @@
|
||||
class User < ActiveRecord::Base
|
||||
include UsersHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
belongs_to :role
|
||||
attr_accessible :name, :password, :password_confirmation, :ign, :email, :confirm_code, :about, :last_ip, :skype, :skype_public, :youtube, :youtube_channelname, :twitter, :last_login, :role, :role_id
|
||||
attr_accessible :uuid, :confirmed, :name, :password, :password_confirmation, :ign, :email, :email_token, :about, :last_ip, :skype, :skype_public, :youtube, :youtube_channelname, :twitter, :last_seen, :role, :role_id
|
||||
|
||||
has_secure_password
|
||||
|
||||
before_validation :strip_whitespaces
|
||||
before_validation :strip_whitespaces, :set_uuid, :set_name, :set_role, :set_email_token
|
||||
|
||||
validates_presence_of :password, :password_confirmation, :confirm_code, :on => :create
|
||||
validates_presence_of :password, :password_confirmation, :email_token, :on => :create
|
||||
validates_presence_of :name, :email, :ign
|
||||
|
||||
validates_length_of :password, in: 8..256, :on => :create
|
||||
validates_length_of :name, in: 3..20
|
||||
validates_length_of :name, in: 2..30
|
||||
validates_length_of :about, maximum: 5000
|
||||
validates_length_of :ign, minimum: 2, maximum: 100
|
||||
validates_length_of :ign, minimum: 2, maximum: 16
|
||||
|
||||
validates :email, uniqueness: {case_sensitive: false}, format: {with: /^\S+@\S+\.[a-z]{2,}$/i, message: "That doesn't look like an email adress."}
|
||||
validates :name, uniqueness: {case_sensitive: false}, format: {with: /^[a-z\d\-_ ]+$/i, message: "Allowed characters: a-z0-9, dashes, underscores and spaces"}
|
||||
validates :email, uniqueness: {case_sensitive: false}, format: {with: /^.+@.+\..{2,}$/i, message: "That doesn't look like an email adress."}
|
||||
validates :ign, uniqueness: {case_sensitive: false}, format: {with: /^[a-z\d_]+$/i, message: "That is probably not your username."}
|
||||
|
||||
validate :ign_is_not_skull, :ign_has_paid, :ign_has_correct_case
|
||||
validate :ign_is_not_mojang, on: :create
|
||||
validate :ign_has_paid
|
||||
|
||||
has_many :blogposts
|
||||
has_many :comments
|
||||
|
||||
# foo.bar.is?(current_user)
|
||||
def is? (user)
|
||||
self == user
|
||||
end
|
||||
|
||||
def donor?
|
||||
!!self.donor
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
!!self.confirmed
|
||||
end
|
||||
|
||||
#roles
|
||||
def disabled?
|
||||
!!(self.role == :disabled)
|
||||
@@ -38,20 +47,8 @@ class User < ActiveRecord::Base
|
||||
!!(self.role == :banned)
|
||||
end
|
||||
|
||||
def unconfirmed?
|
||||
!!(self.role == :unconfirmed)
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
!!(self.role > :unconfirmed)
|
||||
end
|
||||
|
||||
def default?
|
||||
!!(self.role >= :default)
|
||||
end
|
||||
|
||||
def donor?
|
||||
!!(self.role >= :donor)
|
||||
def normal?
|
||||
!!(self.role >= :normal)
|
||||
end
|
||||
|
||||
def mod?
|
||||
@@ -66,26 +63,124 @@ class User < ActiveRecord::Base
|
||||
!!(self.role >= :superadmin)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ign_is_not_skull
|
||||
errors.add(:ign, "Good one...") if ["MHF_Blaze", "MHF_CaveSpider", "MHF_Chicken", "MHF_Cow", "MHF_Enderman", "MHF_Ghast", "MHF_Golem", "MHF_Herobrine", "MHF_LavaSlime", "MHF_MushroomCow", "MHF_Ocelot", "MHF_Pig", "MHF_PigZombie", "MHF_Sheep", "MHF_Slime", "MHF_Spider", "MHF_Squid", "MHF_Villager", "MHF_Cactus", "MHF_Cake", "MHF_Chest", "MHF_Melon", "MHF_OakLog", "MHF_Pumpkin", "MHF_TNT", "MHF_TNT2", "MHF_ArrowUp", "MHF_ArrowDown", "MHF_ArrowLeft", "MHF_ArrowRight", "MHF_Exclamation", "MHF_Question"].include?(self.ign)
|
||||
def avatar_url(size)
|
||||
return "https://minotar.net/helm/#{CGI.escape(self.ign)}/#{CGI.escape(size.to_s)}"
|
||||
end
|
||||
|
||||
def ign_is_not_mojang
|
||||
if self.ign.start_with?("mojang_secret_ign_")
|
||||
self.ign = self.ign[18..-1]
|
||||
else
|
||||
errors.add(:ign, "If that's really you, contact <a href='/users?role=staff'>us</a> in-game.") if ["mollstam", "carlmanneh", "MinecraftChick", "Notch", "jeb_", "xlson", "jonkagstrom", "KrisJelbring", "marc", "Marc_IRL", "MidnightEnforcer", "YoloSwag4Lyfe", "EvilSeph", "Grumm", "Dinnerbone", "geuder", "eldrone", "JahKob", "BomBoy", "MansOlson", "pgeuder", "91maan90", "vubui", "PoiPoiChen", "mamirm", "eldrone", "_tomcc"].include?(self.ign)
|
||||
|
||||
|
||||
#check if this user is an idiot and uses their mc password.
|
||||
def uses_mc_password?(password)
|
||||
uri = URI.parse("https://authserver.mojang.com/authenticate")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.open_timeout = 5
|
||||
http.read_timeout = 20
|
||||
http.use_ssl = true
|
||||
|
||||
payload = { agent: { name: "Minecraft", version: 1 }, username: self.email, password: password }
|
||||
begin
|
||||
response = http.post(uri.request_uri, payload.to_json, "Content-Type" => "application/json").code
|
||||
if response.code == "200"
|
||||
return true
|
||||
else
|
||||
payload[:username] = self.ign
|
||||
return http.post(uri.request_uri, payload.to_json, "Content-Type" => "application/json").code == "200"
|
||||
end
|
||||
rescue => e
|
||||
puts "---"
|
||||
puts "ERROR: failed to check mc password for '#{self.uuid}'. Login servers down?"
|
||||
puts e.message
|
||||
puts "---"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def ign_has_paid
|
||||
errors.add(:ign, "'#{self.ign}' is not a valid account!") unless haspaid?(self.ign)
|
||||
def haspaid?
|
||||
begin
|
||||
response = open("https://sessionserver.mojang.com/session/minecraft/profile/#{CGI.escape(self.uuid)}", read_timeout: 0.5)
|
||||
if response.status[0] == "200"
|
||||
session_profile = JSON.load(response.read)
|
||||
if session_profile["legacy"] == true
|
||||
return open("https://minecraft.net/haspaid.jsp?#{{user: self.ign}.to_query}", read_timeout: 0.5).read == "true"
|
||||
else
|
||||
return true
|
||||
end
|
||||
elsif response.status[0] == "204"
|
||||
return false
|
||||
else
|
||||
puts "---"
|
||||
puts "ERROR: unexpected response code while checking '#{self.uuid}' for premium account"
|
||||
puts "code: #{reponse.status}, body: '#{reponse.read}'"
|
||||
puts "---"
|
||||
end
|
||||
rescue => e
|
||||
puts "---"
|
||||
puts "ERROR: failed to check for premium account for '#{self.uuid}'. Minecraft servers down?"
|
||||
puts e.message
|
||||
puts "---"
|
||||
end
|
||||
# mojang servers have trouble
|
||||
return true
|
||||
end
|
||||
|
||||
def ign_has_correct_case
|
||||
errors.add(:ign, "The IGN is case-sensitive. Please correct '#{self.ign}'.") unless correct_case?(self.ign)
|
||||
# def correct_case?(ign)
|
||||
# begin
|
||||
# http = Net::HTTP.start("skins.minecraft.net")
|
||||
# skin = http.get("/MinecraftSkins/#{CGI.escape(ign)}.png")
|
||||
# http.finish
|
||||
# rescue
|
||||
# puts "---"
|
||||
# puts "ERROR: failed to get skin status code for '#{ign}'. Skin servers down?"
|
||||
# puts "---"
|
||||
# end
|
||||
# skin.code != "404"
|
||||
# end
|
||||
|
||||
def get_profile
|
||||
uri = URI.parse("https://api.mojang.com/profiles")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.open_timeout = 5
|
||||
http.read_timeout = 20
|
||||
http.use_ssl = true
|
||||
|
||||
payload = { agent: "Minecraft", name: self.ign }
|
||||
begin
|
||||
response = http.post(uri.request_uri, payload.to_json, "Content-Type" => "application/json")
|
||||
if response.code == "200"
|
||||
return JSON.load(response.body)["profiles"][0]
|
||||
end
|
||||
rescue => e
|
||||
puts "----"
|
||||
puts "Failed to get mojang profile for #{self.ign}"
|
||||
puts e.message
|
||||
puts "----"
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private
|
||||
|
||||
def set_uuid
|
||||
if !self.uuid.present?
|
||||
# idk
|
||||
end
|
||||
end
|
||||
|
||||
def set_name
|
||||
self.name ||= self.ign
|
||||
end
|
||||
|
||||
def set_role
|
||||
self.role ||= Role.get(:normal)
|
||||
end
|
||||
|
||||
def ign_has_paid
|
||||
errors.add(:ign, "'#{self.ign}' is not a valid account!") unless self.haspaid?
|
||||
end
|
||||
|
||||
def strip_whitespaces
|
||||
@@ -97,4 +192,20 @@ class User < ActiveRecord::Base
|
||||
self.youtube.strip! if self.youtube
|
||||
self.twitter.strip! if self.twitter
|
||||
end
|
||||
|
||||
def set_email_token
|
||||
self.email_token = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
# def ign_is_not_skull
|
||||
# errors.add(:ign, "Good one...") if ["MHF_Blaze", "MHF_CaveSpider", "MHF_Chicken", "MHF_Cow", "MHF_Enderman", "MHF_Ghast", "MHF_Golem", "MHF_Herobrine", "MHF_LavaSlime", "MHF_MushroomCow", "MHF_Ocelot", "MHF_Pig", "MHF_PigZombie", "MHF_Sheep", "MHF_Slime", "MHF_Spider", "MHF_Squid", "MHF_Villager", "MHF_Cactus", "MHF_Cake", "MHF_Chest", "MHF_Melon", "MHF_OakLog", "MHF_Pumpkin", "MHF_TNT", "MHF_TNT2", "MHF_ArrowUp", "MHF_ArrowDown", "MHF_ArrowLeft", "MHF_ArrowRight", "MHF_Exclamation", "MHF_Question"].include?(self.ign)
|
||||
# end
|
||||
|
||||
# def ign_is_not_mojang
|
||||
# if self.ign.start_with?("mojang_secret_ign_")
|
||||
# self.ign = self.ign[18..-1]
|
||||
# else
|
||||
# errors.add(:ign, "If that's really you, contact <a href='/users?role=staff'>us</a> in-game.") if ["mollstam", "carlmanneh", "MinecraftChick", "Notch", "jeb_", "xlson", "jonkagstrom", "KrisJelbring", "marc", "Marc_IRL", "MidnightEnforcer", "YoloSwag4Lyfe", "EvilSeph", "Grumm", "Dinnerbone", "geuder", "eldrone", "JahKob", "BomBoy", "MansOlson", "pgeuder", "91maan90", "vubui", "PoiPoiChen", "mamirm", "eldrone", "_tomcc"].include?(self.ign)
|
||||
# end
|
||||
# end
|
||||
end
|
||||
Reference in New Issue
Block a user