added email verification methods to user

This commit is contained in:
albert
2010-03-09 16:14:29 -05:00
parent 65561a0779
commit 12afa9b491
4 changed files with 105 additions and 3 deletions

View File

@@ -1,6 +1,8 @@
require 'digest/sha1' require 'digest/sha1'
class User < ActiveRecord::Base class User < ActiveRecord::Base
class Error < Exception ; end
attr_accessor :password attr_accessor :password
attr_accessible :password_hash, :email, :last_logged_in_at, :last_forum_read_at, :has_mail, :receive_email_notifications, :comment_threshold, :always_resize_images, :favorite_tags, :blacklisted_tags attr_accessible :password_hash, :email, :last_logged_in_at, :last_forum_read_at, :has_mail, :receive_email_notifications, :comment_threshold, :always_resize_images, :favorite_tags, :blacklisted_tags
validates_length_of :name, :within => 2..20, :on => :create validates_length_of :name, :within => 2..20, :on => :create
@@ -14,6 +16,7 @@ class User < ActiveRecord::Base
after_save :update_cache after_save :update_cache
before_create :normalize_level before_create :normalize_level
has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy
belongs_to :inviter, :class_name => "User"
scope :named, lambda {|name| where(["lower(name) = ?", name])} scope :named, lambda {|name| where(["lower(name) = ?", name])}
module NameMethods module NameMethods
@@ -116,11 +119,30 @@ class User < ActiveRecord::Base
end end
end end
module EmailVerificationMethods
def is_verified?
email_verification_key.blank?
end
def generate_email_verification_key
self.email_verification_key = Digest::SHA1.hexdigest("#{Time.now.to_f}--#{name}--#{rand(1_000_000)}--")
end
def verify!(key)
if email_verification_key == key
self.update_attribute(:email_verification_key, nil)
else
raise User::Error.new("Verification key does not match")
end
end
end
include NameMethods include NameMethods
include PasswordMethods include PasswordMethods
extend AuthenticationMethods extend AuthenticationMethods
include FavoriteMethods include FavoriteMethods
include LevelMethods include LevelMethods
include EmailVerificationMethods
def can_update?(object, foreign_key = :user_id) def can_update?(object, foreign_key = :user_id)
is_moderator? || is_admin? || object.__send__(foreign_key) == id is_moderator? || is_admin? || object.__send__(foreign_key) == id

View File

@@ -1181,6 +1181,41 @@ CREATE SEQUENCE tag_implications_id_seq
ALTER SEQUENCE tag_implications_id_seq OWNED BY tag_implications.id; ALTER SEQUENCE tag_implications_id_seq OWNED BY tag_implications.id;
--
-- Name: tag_subscriptions; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE tag_subscriptions (
id integer NOT NULL,
owner_id integer NOT NULL,
name character varying(255) NOT NULL,
tag_query character varying(255) NOT NULL,
post_ids text NOT NULL,
is_visible_on_profile boolean DEFAULT true NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
--
-- Name: tag_subscriptions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE tag_subscriptions_id_seq
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
--
-- Name: tag_subscriptions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE tag_subscriptions_id_seq OWNED BY tag_subscriptions.id;
-- --
-- Name: tags; Type: TABLE; Schema: public; Owner: -; Tablespace: -- Name: tags; Type: TABLE; Schema: public; Owner: -; Tablespace:
-- --
@@ -1335,7 +1370,8 @@ CREATE TABLE users (
name character varying(255) NOT NULL, name character varying(255) NOT NULL,
password_hash character varying(255) NOT NULL, password_hash character varying(255) NOT NULL,
email character varying(255), email character varying(255),
invited_by integer, email_verification_key character varying(255),
inviter_id integer,
is_banned boolean DEFAULT false NOT NULL, is_banned boolean DEFAULT false NOT NULL,
is_privileged boolean DEFAULT false NOT NULL, is_privileged boolean DEFAULT false NOT NULL,
is_contributor boolean DEFAULT false NOT NULL, is_contributor boolean DEFAULT false NOT NULL,
@@ -1668,6 +1704,13 @@ ALTER TABLE tag_aliases ALTER COLUMN id SET DEFAULT nextval('tag_aliases_id_seq'
ALTER TABLE tag_implications ALTER COLUMN id SET DEFAULT nextval('tag_implications_id_seq'::regclass); ALTER TABLE tag_implications ALTER COLUMN id SET DEFAULT nextval('tag_implications_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE tag_subscriptions ALTER COLUMN id SET DEFAULT nextval('tag_subscriptions_id_seq'::regclass);
-- --
-- Name: id; Type: DEFAULT; Schema: public; Owner: - -- Name: id; Type: DEFAULT; Schema: public; Owner: -
-- --
@@ -1973,6 +2016,14 @@ ALTER TABLE ONLY tag_implications
ADD CONSTRAINT tag_implications_pkey PRIMARY KEY (id); ADD CONSTRAINT tag_implications_pkey PRIMARY KEY (id);
--
-- Name: tag_subscriptions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY tag_subscriptions
ADD CONSTRAINT tag_subscriptions_pkey PRIMARY KEY (id);
-- --
-- Name: tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- Name: tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
-- --
@@ -2533,6 +2584,20 @@ CREATE INDEX index_tag_implications_on_antecedent_name ON tag_implications USING
CREATE INDEX index_tag_implications_on_consequent_name ON tag_implications USING btree (consequent_name); CREATE INDEX index_tag_implications_on_consequent_name ON tag_implications USING btree (consequent_name);
--
-- Name: index_tag_subscriptions_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_tag_subscriptions_on_name ON tag_subscriptions USING btree (name);
--
-- Name: index_tag_subscriptions_on_owner_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_tag_subscriptions_on_owner_id ON tag_subscriptions USING btree (owner_id);
-- --
-- Name: index_tags_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- Name: index_tags_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace:
-- --
@@ -2736,4 +2801,6 @@ INSERT INTO schema_migrations (version) VALUES ('20100223001012');
INSERT INTO schema_migrations (version) VALUES ('20100224171915'); INSERT INTO schema_migrations (version) VALUES ('20100224171915');
INSERT INTO schema_migrations (version) VALUES ('20100224172146'); INSERT INTO schema_migrations (version) VALUES ('20100224172146');
INSERT INTO schema_migrations (version) VALUES ('20100307073438');

View File

@@ -6,7 +6,8 @@ class CreateUsers < ActiveRecord::Migration
t.column :name, :string, :null => false t.column :name, :string, :null => false
t.column :password_hash, :string, :null => false t.column :password_hash, :string, :null => false
t.column :email, :string t.column :email, :string
t.column :invited_by, :integer t.column :email_verification_key, :string
t.column :inviter_id, :integer
t.column :is_banned, :boolean, :null => false, :default => false t.column :is_banned, :boolean, :null => false, :default => false
t.column :is_privileged, :boolean, :null => false, :default => false t.column :is_privileged, :boolean, :null => false, :default => false
t.column :is_contributor, :boolean, :null => false, :default => false t.column :is_contributor, :boolean, :null => false, :default => false

View File

@@ -6,6 +6,18 @@ class UserTest < ActiveSupport::TestCase
MEMCACHE.flush_all MEMCACHE.flush_all
end end
should "verify" do
user = Factory.create(:user)
assert(user.is_verified?)
user = Factory.create(:user)
user.generate_email_verification_key
user.save
assert(!user.is_verified?)
assert_raise(User::Error) {user.verify!("bbb")}
assert_nothing_raised {user.verify!(user.email_verification_key)}
assert(user.is_verified?)
end
should "authenticate" do should "authenticate" do
@user = Factory.create(:user) @user = Factory.create(:user)
assert(User.authenticate(@user.name, "password"), "Authentication should have succeeded") assert(User.authenticate(@user.name, "password"), "Authentication should have succeeded")