summaryrefslogtreecommitdiff
path: root/app/models/user.rb
blob: 55a7da0d1de31c15cf52a759ff71399f8728c740 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
class User < ActiveRecord::Base

before_save { self.email = email.downcase }
before_save { self.user_name = user_name.downcase }

=begin

Rails looks for the create_remember_token and runs the method
before anything else.

This method cannot be called by a user since it is denoted
as private.

=end

before_create :create_remember_token

=begin

VAILD_EMAIL is the regex used to valid a user given email.

A break down of the regex is listed below.

/ -------------> Start of the regex
\A ------------> match start of a string
[\w+\-.]+ -----> at least one owrd character, plus, hyphen, or 
			           dot
@ -------------> literal ampersand
[a-z\d\-.]+ ---> at least one letter, digit, hyphen, or dot
(?:\.[a-z]+) --> ensures that the error of example@foo..com
							   does not occur
\z ------------> match end of a string
/ -------------> end of the regex
i -------------> case sensative

=end
		
	VALID_EMAIL_REG = /\A[\w+\-.]+@[a-z\d\-.]+(?:\.[a-z]+)\z/i

=begin

VALID_USER_NAME checks to make sure a user's user_name
is in the proper format.

=end

	VALID_USER_NAME_REG = /[a-zA-Z0-9\-]/

=begin

The following lines put a user accout through a series of
validations in order to make sure all of their information
is in the proper format.

validates :symbol_to_be_valided

presence: determines whether or not a symbol is filled or not
length: ensures there is a length limit on the symbol
format: checks the format of given information to ensure 
        validity

=end

	validates :name, presence: true, length: { maximum: 50 }
	validates :email, presence: true, format: {with: 
                                       VALID_EMAIL_REG},
                      uniqueness: { case_sensitive: false }
  validates :user_name, presence: true, length:{maximum: 50},
                        format: {with: VALID_USER_NAME_REG },
                        uniqueness: {case_sensitive: false }

=begin

Instead of adding password and password_confirmation
attributes, requiring the presence of a password, 
requirin that pw and pw_com match, and add an authenticate
method to compare an encrypted password to the
password_digest to authenticate users, I can just add
has_secure_password which does all of this for me.

=end

	has_secure_password

	validates :password, length: { minimum: 6 }

=begin

	Create a random remember token for the user. This will be
  changed every time the user creates a new session.

	By changing the cookie every new session, any hijacked sessions
	(where the attacker steals a cookie to sign in as a certain 
	user) will expire the next time the user signs back in.
 
  The random string is of length 16 composed of A-Z, a-z, 0-9
	This is the browser's cookie value.

=end
 
  def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

=begin

	Encrypt the remember token.
	This is the encrypted version of the cookie stored on
  the database.

	The reasoning for storing a hashed token is so that even if
	the database is compromised, the atacker won't be able to use
	the remember tokens to sign in.

=end

  def User.hash(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

=begin

SHA-1 (Secure Hash Algorithm) is a US engineered hash
function that produces a 20 byte hash value which typically
forms a hexadecimal number 40 digits long. 
The reason I am not using the Bcrypt algorithm is because
SHA-1 is much faster and I will be calling this on
every page a user accesses.

https://en.wikipedia.org/wiki/SHA-1

=end

	# Everything under private is hidden so you cannot call.
	private

=begin		

  Create_remember_token in order to ensure a user always has
  a remember token.

=end
		  def create_remember_token
		    self.remember_token = User.hash(User.new_remember_token)
		  end

=begin

In order to ensure that someone did not accidently submit
two accounts rapidly (which would throw off the validates 
for user_name and email), I added an index to the Users 
email and user_name in the database to ensure uniqueness
This also gives and index to the user_name and email
so finding a user SHOULD be easier for the database.

=end

end