usman 0.1.5 → 0.1.6dev2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -16
- data/app/controllers/usman/admin/base_controller.rb +22 -0
- data/app/controllers/usman/admin/dashboard_controller.rb +1 -1
- data/app/controllers/usman/admin/features_controller.rb +4 -1
- data/app/controllers/usman/admin/permissions_controller.rb +9 -15
- data/app/controllers/usman/admin/resource_controller.rb +3 -1
- data/app/controllers/usman/admin/roles_controller.rb +4 -2
- data/app/controllers/usman/admin/user_roles_controller.rb +142 -0
- data/app/controllers/usman/admin/users_controller.rb +5 -2
- data/app/controllers/usman/application_controller.rb +0 -4
- data/app/controllers/usman/sessions_controller.rb +5 -2
- data/app/helpers/usman/authentication_helper.rb +35 -25
- data/app/models/feature.rb +50 -46
- data/app/models/image/feature_image.rb +1 -1
- data/app/models/image/profile_picture.rb +1 -1
- data/app/models/permission.rb +3 -8
- data/app/models/role.rb +4 -7
- data/app/models/user.rb +81 -103
- data/app/models/usman/application_record.rb +3 -0
- data/app/services/usman/authentication_service.rb +4 -3
- data/app/uploaders/profile_picture_uploader.rb +2 -1
- data/app/views/layouts/kuppayam/_header.html.erb +1 -1
- data/app/views/layouts/kuppayam/_navbar.html.erb +1 -1
- data/app/views/layouts/kuppayam/_sidebar.html.erb +8 -7
- data/app/views/usman/admin/dashboard/index.html.erb +0 -1
- data/app/views/usman/admin/features/_form.html.erb +5 -2
- data/app/views/usman/admin/features/_index.html.erb +4 -1
- data/app/views/usman/admin/features/index.html.erb +20 -3
- data/app/views/usman/admin/permissions/_show.html.erb +2 -10
- data/app/views/usman/admin/permissions/index.html.erb +20 -3
- data/app/views/usman/admin/roles/_form.html.erb +1 -1
- data/app/views/usman/admin/roles/_index.html.erb +3 -3
- data/app/views/usman/admin/roles/_row.html.erb +2 -2
- data/app/views/usman/admin/roles/_show.html.erb +41 -7
- data/app/views/usman/admin/roles/index.html.erb +22 -3
- data/app/views/usman/admin/user_roles/_form.html.erb +24 -0
- data/app/views/usman/admin/user_roles/_index.html.erb +59 -0
- data/app/views/usman/admin/user_roles/_row.html.erb +34 -0
- data/app/views/usman/admin/users/_index.html.erb +22 -16
- data/app/views/usman/admin/users/_row.html.erb +4 -4
- data/app/views/usman/admin/users/_show.html.erb +1 -1
- data/app/views/usman/admin/users/index.html.erb +4 -2
- data/app/views/usman/sessions/_form.html.erb +19 -7
- data/app/views/usman/sessions/sign_in.html.erb +1 -1
- data/config/initializers/overide_kuppayam_controllers.rb +74 -0
- data/config/locales/kuppayam/authentication.en.yml +4 -1
- data/config/routes.rb +3 -1
- data/db/import_data/dummy/features.csv +7 -0
- data/db/import_data/dummy/permissions.csv +18 -1
- data/db/import_data/dummy/roles.csv +5 -0
- data/db/import_data/dummy/users.csv +7 -3
- data/db/import_data/features.csv +7 -0
- data/db/import_data/permissions.csv +1 -30
- data/db/import_data/roles.csv +5 -0
- data/db/migrate/20170000000100_create_users.rb +1 -1
- data/db/migrate/20170000000101_create_features.rb +1 -1
- data/db/migrate/20170000000102_create_roles.rb +1 -1
- data/db/migrate/20170728095744_create_otp_registrations.rb +17 -0
- data/lib/tasks/usman/all.rake +34 -10
- data/lib/{tasks/usman → temp}/features.rake +3 -6
- data/lib/{tasks/usman → temp}/permissions.rake +3 -5
- data/lib/temp/roles.rake +24 -0
- data/lib/{tasks/usman → temp}/users.rake +3 -5
- data/lib/usman/engine.rb +2 -3
- data/lib/usman/version.rb +1 -1
- metadata +27 -45
- data/app/views/usman/admin/features/_action_buttons.html.erb +0 -0
- data/app/views/usman/admin/features/temp/create.js.erb +0 -29
- data/app/views/usman/admin/features/temp/destroy.js.erb +0 -16
- data/app/views/usman/admin/features/temp/edit.js.erb +0 -7
- data/app/views/usman/admin/features/temp/index.js.erb +0 -8
- data/app/views/usman/admin/features/temp/new.js.erb +0 -7
- data/app/views/usman/admin/features/temp/row.js.erb +0 -10
- data/app/views/usman/admin/features/temp/show.js.erb +0 -8
- data/app/views/usman/admin/features/temp/update.js.erb +0 -16
- data/app/views/usman/admin/permissions/temp/create.js.erb +0 -29
- data/app/views/usman/admin/permissions/temp/destroy.js.erb +0 -22
- data/app/views/usman/admin/permissions/temp/edit.js.erb +0 -4
- data/app/views/usman/admin/permissions/temp/index.js.erb +0 -14
- data/app/views/usman/admin/permissions/temp/new.js.erb +0 -4
- data/app/views/usman/admin/permissions/temp/row.js.erb +0 -24
- data/app/views/usman/admin/permissions/temp/show.js.erb +0 -13
- data/app/views/usman/admin/permissions/temp/update.js.erb +0 -29
- data/db/import_data/dummy/images/users/guna.neweast.png +0 -0
- data/db/import_data/dummy/images/users/junaid.ramzan.jpg +0 -0
- data/db/import_data/dummy/images/users/kpvarma.png +0 -0
- data/db/import_data/dummy/images/users/stephen.price.png +0 -0
- data/db/import_data/dummy/images/users/vinodh.jpg +0 -0
- data/db/import_data/images/users/junaid.ramzan.jpg +0 -0
- data/db/import_data/images/users/kpvarma.png +0 -0
- data/db/import_data/images/users/vinodh.jpg +0 -0
- data/lib/usman/extras/import_error_handler.rb +0 -79
data/app/models/feature.rb
CHANGED
@@ -1,22 +1,19 @@
|
|
1
1
|
class Feature < Usman::ApplicationRecord
|
2
2
|
|
3
|
-
require 'import_error_handler.rb'
|
4
|
-
extend Usman::ImportErrorHandler
|
5
|
-
|
6
3
|
# Constants
|
7
|
-
UNPUBLISHED = "unpublished"
|
8
4
|
PUBLISHED = "published"
|
5
|
+
UNPUBLISHED = "unpublished"
|
9
6
|
DISABLED = "disabled"
|
10
7
|
|
11
8
|
STATUS = {
|
12
|
-
UNPUBLISHED => "Un-Published",
|
13
9
|
PUBLISHED => "Published",
|
10
|
+
UNPUBLISHED => "Un-Published",
|
14
11
|
DISABLED => "Disabled"
|
15
12
|
}
|
16
13
|
|
17
14
|
STATUS_REVERSE = {
|
18
|
-
"
|
19
|
-
"Published" =>
|
15
|
+
"Published" => PUBLISHED,
|
16
|
+
"Un-Published" => UNPUBLISHED,
|
20
17
|
"Disabled" => DISABLED
|
21
18
|
}
|
22
19
|
|
@@ -26,7 +23,7 @@ class Feature < Usman::ApplicationRecord
|
|
26
23
|
has_one :feature_image, :as => :imageable, :dependent => :destroy, :class_name => "Image::FeatureImage"
|
27
24
|
|
28
25
|
# Validations
|
29
|
-
validates :name, presence: true
|
26
|
+
validates :name, presence: true, length: {minimum: 3, maximum: 250}
|
30
27
|
validates :status, :presence => true, :inclusion => {:in => STATUS.keys, :presence_of => :status, :message => "%{value} is not a valid status" }
|
31
28
|
|
32
29
|
# ------------------
|
@@ -47,9 +44,7 @@ class Feature < Usman::ApplicationRecord
|
|
47
44
|
scope :published, -> { where(status: PUBLISHED) }
|
48
45
|
scope :disabled, -> { where(status: DISABLED) }
|
49
46
|
|
50
|
-
def self.save_row_data(row
|
51
|
-
|
52
|
-
image_base_path = base_path + "images/"
|
47
|
+
def self.save_row_data(row)
|
53
48
|
|
54
49
|
row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
|
55
50
|
|
@@ -60,45 +55,24 @@ class Feature < Usman::ApplicationRecord
|
|
60
55
|
feature.status = Feature::UNPUBLISHED
|
61
56
|
|
62
57
|
# Initializing error hash for displaying all errors altogether
|
63
|
-
error_object =
|
64
|
-
|
65
|
-
|
66
|
-
begin
|
67
|
-
image_path = image_base_path + "features/#{feature.name.parameterize}.png"
|
68
|
-
image_path = image_base_path + "features/#{feature.name.parameterize}}.jpg" unless File.exists?(image_path)
|
69
|
-
if File.exists?(image_path)
|
70
|
-
feature.build_feature_image
|
71
|
-
feature.feature_image.image = File.open(image_path)
|
72
|
-
else
|
73
|
-
summary = "Feature Image not found for feature: #{feature.name}"
|
74
|
-
details = "#{image_path}/png doesn't exists"
|
75
|
-
error_object.warnings << { summary: summary, details: details }
|
76
|
-
end
|
77
|
-
rescue => e
|
78
|
-
summary = "Error during processing: #{$!}"
|
79
|
-
details = "Feature: #{feature.name}, Image Path: #{image_path}"
|
80
|
-
stack_trace = "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
|
81
|
-
error_object.errors << { summary: summary, details: details, stack_trace: stack_trace }
|
82
|
-
end if feature.feature_image.blank?
|
83
|
-
|
84
|
-
if feature.valid? && (feature.feature_image.blank? || feature.feature_image.valid?)
|
58
|
+
error_object = Kuppayam::Importer::ErrorHash.new
|
59
|
+
|
60
|
+
if feature.valid?
|
85
61
|
feature.save!
|
86
62
|
else
|
87
63
|
summary = "Error while saving feature: #{feature.name}"
|
88
64
|
details = "Error! #{feature.errors.full_messages.to_sentence}"
|
89
|
-
details << ", #{feature.feature_image.errors.full_messages.to_sentence}" if feature.feature_image
|
90
65
|
error_object.errors << { summary: summary, details: details }
|
91
66
|
end
|
92
67
|
return error_object
|
93
68
|
end
|
94
69
|
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
70
|
+
# ------------------
|
71
|
+
# Instance Methods
|
72
|
+
# ------------------
|
73
|
+
|
74
|
+
# Status Methods
|
75
|
+
# --------------
|
102
76
|
|
103
77
|
# * Return true if the user is not published, else false.
|
104
78
|
# == Examples
|
@@ -145,14 +119,44 @@ class Feature < Usman::ApplicationRecord
|
|
145
119
|
# change the status to :suspended
|
146
120
|
# Return the status
|
147
121
|
# == Examples
|
148
|
-
# >>> feature.
|
149
|
-
# => "
|
150
|
-
def
|
122
|
+
# >>> feature.disable!
|
123
|
+
# => "disabled"
|
124
|
+
def disable!
|
151
125
|
self.update_attribute(:status, DISABLED)
|
152
126
|
end
|
153
127
|
|
154
|
-
|
155
|
-
|
128
|
+
# Permission Methods
|
129
|
+
# ------------------
|
130
|
+
|
131
|
+
def can_be_edited?
|
132
|
+
published? or unpublished?
|
133
|
+
end
|
134
|
+
|
135
|
+
def can_be_deleted?
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
139
|
+
def can_be_published?
|
140
|
+
unpublished? or disabled?
|
141
|
+
end
|
142
|
+
|
143
|
+
def can_be_unpublished?
|
144
|
+
published? or disabled?
|
145
|
+
end
|
146
|
+
|
147
|
+
def can_be_disabled?
|
148
|
+
published? or unpublished?
|
149
|
+
end
|
150
|
+
|
151
|
+
# Other Methods
|
152
|
+
# -------------
|
153
|
+
|
154
|
+
# * Return full name
|
155
|
+
# == Examples
|
156
|
+
# >>> feature.display_name
|
157
|
+
# => "Products"
|
158
|
+
def display_name
|
159
|
+
"#{name}"
|
156
160
|
end
|
157
161
|
|
158
162
|
end
|
data/app/models/permission.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
class Permission < Usman::ApplicationRecord
|
2
2
|
|
3
|
-
|
4
|
-
extend Usman::ImportErrorHandler
|
5
|
-
|
6
|
-
# Associations
|
3
|
+
# Associations
|
7
4
|
belongs_to :user
|
8
5
|
belongs_to :feature
|
9
6
|
|
@@ -30,16 +27,14 @@ class Permission < Usman::ApplicationRecord
|
|
30
27
|
LOWER(f.name) LIKE LOWER('%#{query}%')")}
|
31
28
|
|
32
29
|
|
33
|
-
def self.save_row_data(row
|
34
|
-
|
35
|
-
image_base_path = base_path + "images/"
|
30
|
+
def self.save_row_data(row)
|
36
31
|
|
37
32
|
row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
|
38
33
|
|
39
34
|
return if row[:user].blank? || row[:feature].blank?
|
40
35
|
|
41
36
|
# Initializing error hash for displaying all errors altogether
|
42
|
-
error_object =
|
37
|
+
error_object = Kuppayam::Importer::ErrorHash.new
|
43
38
|
|
44
39
|
user = User.find_by_username(row[:user])
|
45
40
|
unless user
|
data/app/models/role.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
class Role < Usman::ApplicationRecord
|
2
2
|
|
3
|
-
require 'import_error_handler.rb'
|
4
|
-
extend Usman::ImportErrorHandler
|
5
|
-
|
6
3
|
# Associations
|
7
4
|
has_and_belongs_to_many :users
|
8
5
|
|
9
6
|
# Validations
|
10
|
-
validates :name, presence: true
|
7
|
+
validates :name, presence: true, length: {minimum: 3, maximum: 250}
|
11
8
|
|
12
9
|
# ------------------
|
13
10
|
# Class Methods
|
@@ -18,10 +15,10 @@ class Role < Usman::ApplicationRecord
|
|
18
15
|
# == Examples
|
19
16
|
# >>> role.search(query)
|
20
17
|
# => ActiveRecord::Relation object
|
21
|
-
scope :search, lambda {|query| where("LOWER(name) LIKE LOWER('%#{query}%')")
|
18
|
+
scope :search, lambda {|query| where("LOWER(roles.name) LIKE LOWER('%#{query}%')")
|
22
19
|
}
|
23
20
|
|
24
|
-
def self.save_row_data(row
|
21
|
+
def self.save_row_data(row)
|
25
22
|
|
26
23
|
row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
|
27
24
|
|
@@ -31,7 +28,7 @@ class Role < Usman::ApplicationRecord
|
|
31
28
|
role.name = row[:name]
|
32
29
|
|
33
30
|
# Initializing error hash for displaying all errors altogether
|
34
|
-
error_object =
|
31
|
+
error_object = Kuppayam::Importer::ErrorHash.new
|
35
32
|
|
36
33
|
if role.valid?
|
37
34
|
role.save!
|
data/app/models/user.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
class User < Usman::ApplicationRecord
|
2
2
|
|
3
|
-
require 'import_error_handler.rb'
|
4
|
-
extend Usman::ImportErrorHandler
|
5
|
-
extend KuppayamValidators
|
6
|
-
|
7
3
|
# including Password Methods
|
8
4
|
has_secure_password
|
9
5
|
|
@@ -26,10 +22,10 @@ class User < Usman::ApplicationRecord
|
|
26
22
|
|
27
23
|
EXCLUDED_JSON_ATTRIBUTES = [:confirmation_token, :password_digest, :reset_password_token, :unlock_token, :status, :reset_password_sent_at, :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip, :confirmed_at, :confirmation_sent_at, :unconfirmed_email, :failed_attempts, :locked_at, :created_at, :updated_at]
|
28
24
|
DEFAULT_PASSWORD = "Password@1"
|
29
|
-
SESSION_TIME_OUT =
|
25
|
+
SESSION_TIME_OUT = 120.minutes
|
30
26
|
|
31
27
|
# Validations
|
32
|
-
validates :name, presence: true
|
28
|
+
validates :name, presence: true, length: {minimum: 3, maximum: 250}
|
33
29
|
validate_username :username
|
34
30
|
validate_email :email
|
35
31
|
validate_password :password, condition_method: :should_validate_password?
|
@@ -43,26 +39,24 @@ class User < Usman::ApplicationRecord
|
|
43
39
|
has_one :profile_picture, :as => :imageable, :dependent => :destroy, :class_name => "Image::ProfilePicture"
|
44
40
|
has_many :permissions
|
45
41
|
has_many :features, through: :permissions
|
46
|
-
has_and_belongs_to_many :
|
42
|
+
has_and_belongs_to_many :roles
|
47
43
|
|
48
44
|
|
49
45
|
# ------------------
|
50
46
|
# Class Methods
|
51
47
|
# ------------------
|
52
48
|
|
53
|
-
|
54
|
-
self.where("LOWER(email) = LOWER('#{query}') OR LOWER(username) = LOWER('#{query}')").first
|
55
|
-
end
|
49
|
+
# Scopes Methods
|
56
50
|
|
57
51
|
# return an active record relation object with the search query in its where clause
|
58
52
|
# Return the ActiveRecord::Relation object
|
59
53
|
# == Examples
|
60
54
|
# >>> user.search(query)
|
61
55
|
# => ActiveRecord::Relation object
|
62
|
-
scope :search, lambda {|query| where("LOWER(name) LIKE LOWER('%#{query}%') OR\
|
63
|
-
LOWER(username) LIKE LOWER('%#{query}%') OR\
|
64
|
-
LOWER(email) LIKE LOWER('%#{query}%') OR\
|
65
|
-
LOWER(designation) LIKE LOWER('%#{query}%')")
|
56
|
+
scope :search, lambda {|query| where("LOWER(users.name) LIKE LOWER('%#{query}%') OR\
|
57
|
+
LOWER(users.username) LIKE LOWER('%#{query}%') OR\
|
58
|
+
LOWER(users.email) LIKE LOWER('%#{query}%') OR\
|
59
|
+
LOWER(users.designation) LIKE LOWER('%#{query}%')")
|
66
60
|
}
|
67
61
|
|
68
62
|
scope :status, lambda { |status| where("LOWER(status)='#{status}'") }
|
@@ -70,10 +64,13 @@ class User < Usman::ApplicationRecord
|
|
70
64
|
scope :pending, -> { where(status: PENDING) }
|
71
65
|
scope :approved, -> { where(status: APPROVED) }
|
72
66
|
scope :suspended, -> { where(status: SUSPENDED) }
|
67
|
+
|
68
|
+
scope :super_admins, -> { where(super_admin: TRUE) }
|
69
|
+
scope :normal_users, -> { where(super_admin: FALSE) }
|
73
70
|
|
74
|
-
|
71
|
+
# Import Methods
|
75
72
|
|
76
|
-
|
73
|
+
def self.save_row_data(row)
|
77
74
|
|
78
75
|
row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
|
79
76
|
|
@@ -92,7 +89,7 @@ class User < Usman::ApplicationRecord
|
|
92
89
|
user.assign_default_password
|
93
90
|
|
94
91
|
# Initializing error hash for displaying all errors altogether
|
95
|
-
error_object =
|
92
|
+
error_object = Kuppayam::Importer::ErrorHash.new
|
96
93
|
|
97
94
|
if user.valid?
|
98
95
|
user.save!
|
@@ -102,47 +99,15 @@ class User < Usman::ApplicationRecord
|
|
102
99
|
error_object.errors << { summary: summary, details: details }
|
103
100
|
end
|
104
101
|
|
105
|
-
## Adding a profile picture
|
106
|
-
begin
|
107
|
-
image_path = image_base_path + "users/#{user.username}.png"
|
108
|
-
image_path = image_base_path + "users/#{user.username}.jpg" unless File.exists?(image_path)
|
109
|
-
if File.exists?(image_path)
|
110
|
-
user.build_profile_picture
|
111
|
-
user.profile_picture.image = File.open(image_path)
|
112
|
-
if user.profile_picture.valid?
|
113
|
-
user.profile_picture.save
|
114
|
-
else
|
115
|
-
summary = "Error while saving user: #{user.name}"
|
116
|
-
details = "Error! #{user.errors.full_messages.to_sentence}"
|
117
|
-
details << ", #{user.profile_picture.errors.full_messages.to_sentence}" if user.profile_picture
|
118
|
-
error_object.errors << { summary: summary, details: details }
|
119
|
-
end
|
120
|
-
else
|
121
|
-
summary = "Profile Picture not found for user: #{user.name}"
|
122
|
-
details = "#{image_path}/png doesn't exists"
|
123
|
-
error_object.warnings << { summary: summary, details: details }
|
124
|
-
end
|
125
|
-
rescue => e
|
126
|
-
summary = "Error during processing: #{$!}"
|
127
|
-
details = "User: #{user.name}, Image Path: #{image_path}"
|
128
|
-
stack_trace = "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
|
129
|
-
error_object.errors << { summary: summary, details: details, stack_trace: stack_trace }
|
130
|
-
end if user.profile_picture.blank?
|
131
|
-
|
132
102
|
return error_object
|
133
103
|
end
|
134
104
|
|
135
105
|
# ------------------
|
136
|
-
# Instance
|
106
|
+
# Instance Methods
|
137
107
|
# ------------------
|
138
|
-
|
139
|
-
#
|
140
|
-
#
|
141
|
-
# >>> user.display_name
|
142
|
-
# => "Joe Black"
|
143
|
-
def display_name
|
144
|
-
"#{name}"
|
145
|
-
end
|
108
|
+
|
109
|
+
# Status Methods
|
110
|
+
# --------------
|
146
111
|
|
147
112
|
# * Return true if the user is not approved, else false.
|
148
113
|
# == Examples
|
@@ -195,36 +160,26 @@ class User < Usman::ApplicationRecord
|
|
195
160
|
self.update_attribute(:status, SUSPENDED)
|
196
161
|
end
|
197
162
|
|
198
|
-
|
199
|
-
|
200
|
-
|
163
|
+
# Authentication Methods
|
164
|
+
# ----------------------
|
165
|
+
|
166
|
+
def start_session(remote_ip)
|
167
|
+
self.current_sign_in_at = Time.now
|
168
|
+
self.current_sign_in_ip = remote_ip
|
201
169
|
|
202
|
-
def start_session
|
203
|
-
# FIX ME - specs are not written to ensure that all these data are saved
|
204
|
-
self.token_created_at = Time.now
|
205
170
|
self.sign_in_count = self.sign_in_count ? self.sign_in_count + 1 : 1
|
206
|
-
self.last_sign_in_at = self.current_sign_in_at
|
207
|
-
self.last_sign_in_ip = self.current_sign_in_ip
|
208
|
-
self.current_sign_in_at = self.token_created_at
|
209
171
|
|
210
|
-
# FIX ME - pass remote_ip to this method.
|
211
|
-
# Make necessary changes to authentication service to make it work
|
212
|
-
# self.current_sign_in_ip = remote_ip if remote_ip
|
213
172
|
self.save
|
214
173
|
end
|
215
174
|
|
216
175
|
def end_session
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
def update_token
|
223
|
-
self.update_attribute(:token_created_at, Time.now)
|
224
|
-
end
|
176
|
+
self.last_sign_in_at = self.current_sign_in_at
|
177
|
+
self.last_sign_in_ip = self.current_sign_in_ip
|
178
|
+
|
179
|
+
self.current_sign_in_at = nil
|
180
|
+
self.current_sign_in_ip = nil
|
225
181
|
|
226
|
-
|
227
|
-
return self.token_created_at.nil? || (Time.now > self.token_created_at + (SESSION_TIME_OUT - 1.minute))
|
182
|
+
self.save
|
228
183
|
end
|
229
184
|
|
230
185
|
def assign_default_password
|
@@ -232,18 +187,13 @@ class User < Usman::ApplicationRecord
|
|
232
187
|
self.password_confirmation = DEFAULT_PASSWORD
|
233
188
|
end
|
234
189
|
|
235
|
-
def token_expired?
|
236
|
-
return self.token_created_at.nil? || (Time.now > self.token_created_at + SESSION_TIME_OUT)
|
237
|
-
end
|
238
|
-
|
239
190
|
def generate_reset_password_token
|
240
191
|
self.reset_password_token = SecureRandom.hex unless self.reset_password_token
|
241
192
|
self.reset_password_sent_at = Time.now unless self.reset_password_sent_at
|
242
193
|
end
|
243
194
|
|
244
|
-
|
245
|
-
|
246
|
-
end
|
195
|
+
# Permission Methods
|
196
|
+
# ------------------
|
247
197
|
|
248
198
|
def set_permission(feature_name, **options)
|
249
199
|
options.reverse_merge!(
|
@@ -301,23 +251,68 @@ class User < Usman::ApplicationRecord
|
|
301
251
|
end
|
302
252
|
|
303
253
|
def can_be_deleted?
|
304
|
-
|
254
|
+
suspended?
|
305
255
|
end
|
306
256
|
|
307
257
|
def can_be_edited?
|
308
258
|
!suspended?
|
309
259
|
end
|
310
260
|
|
261
|
+
# Role Methods
|
262
|
+
# ------------
|
263
|
+
|
264
|
+
def add_role(role)
|
265
|
+
return false unless self.approved?
|
266
|
+
role = Role.find_by_name(role) if role.is_a?(String)
|
267
|
+
if role
|
268
|
+
self.roles << role unless self.has_role?(role)
|
269
|
+
return true
|
270
|
+
else
|
271
|
+
return false
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def remove_role(role)
|
276
|
+
role = Role.find_by_name(role) if role.is_a?(String)
|
277
|
+
self.roles.delete(role) if role
|
278
|
+
end
|
279
|
+
|
280
|
+
def has_role?(role)
|
281
|
+
role = Role.find_by_name(role) if role.is_a?(String)
|
282
|
+
if role && role.persisted?
|
283
|
+
return true if self.super_admin
|
284
|
+
self.roles.exists?(:id => [role.id])
|
285
|
+
else
|
286
|
+
return false
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# Other Methods
|
291
|
+
# -------------
|
292
|
+
|
293
|
+
# * Return full name
|
294
|
+
# == Examples
|
295
|
+
# >>> user.display_name
|
296
|
+
# => "Joe Black"
|
297
|
+
def display_name
|
298
|
+
"#{name}"
|
299
|
+
end
|
300
|
+
|
301
|
+
def default_image_url(size="small")
|
302
|
+
"/assets/kuppayam/defaults/user-#{size}.png"
|
303
|
+
end
|
304
|
+
|
311
305
|
private
|
312
306
|
|
313
307
|
def should_validate_password?
|
314
|
-
self.new_record? || (self.new_record? == false and self.
|
308
|
+
self.new_record? || (self.new_record? == false and self.password_digest_changed?)
|
315
309
|
end
|
316
310
|
|
317
311
|
def generate_auth_token
|
318
312
|
self.auth_token = SecureRandom.hex unless self.auth_token
|
319
313
|
end
|
320
314
|
|
315
|
+
# FIXME - this should be either removed or moved to feature model
|
321
316
|
def get_feature(feature_name)
|
322
317
|
case feature_name
|
323
318
|
when Feature
|
@@ -332,25 +327,8 @@ class User < Usman::ApplicationRecord
|
|
332
327
|
return feature
|
333
328
|
end
|
334
329
|
|
335
|
-
def
|
336
|
-
self.
|
337
|
-
end
|
338
|
-
|
339
|
-
def add_role(role_name)
|
340
|
-
role = self.get_role(role_name)
|
341
|
-
self.roles << role if role && role.persists?
|
342
|
-
end
|
343
|
-
|
344
|
-
def remove_role(role_name)
|
345
|
-
role = self.get_role(role_name)
|
346
|
-
if role
|
347
|
-
self.roles.delete(role)
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
def has_role?(role_name)
|
352
|
-
role = self.get_role(role_name)
|
353
|
-
role && role.persists?
|
330
|
+
def self.find_by_email_or_username(query)
|
331
|
+
self.where("LOWER(email) = LOWER('#{query}') OR LOWER(username) = LOWER('#{query}')").first
|
354
332
|
end
|
355
333
|
|
356
334
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
module Usman
|
2
2
|
class AuthenticationService
|
3
3
|
|
4
|
-
attr_reader :login_handle, :password, :error, :user
|
4
|
+
attr_reader :login_handle, :password, :error, :user, :remote_ip
|
5
5
|
|
6
6
|
def initialize(params)
|
7
7
|
@login_handle = params[:login_handle]
|
8
8
|
@password = params[:password]
|
9
|
+
@remote_ip = params[:remote_ip]
|
9
10
|
@error = nil
|
10
|
-
|
11
|
+
|
11
12
|
check_if_user_exists
|
12
13
|
if @user
|
13
14
|
authenticate
|
14
15
|
check_if_user_is_approved
|
15
16
|
end
|
16
17
|
|
17
|
-
@user.start_session unless @error
|
18
|
+
@user.start_session(@remote_ip) unless @error
|
18
19
|
end
|
19
20
|
|
20
21
|
def invalid_login_error
|
@@ -33,7 +33,7 @@
|
|
33
33
|
<% if @current_user %>
|
34
34
|
<span style="color:#898989;">Welcome</span> <span style="color:#4b4b4b;"><%= @current_user.name %></span>
|
35
35
|
|
|
36
|
-
<%= link_to raw("Sign Out"), sign_out_path, method: :delete %>
|
36
|
+
<%= link_to raw("Sign Out"), usman.sign_out_path, method: :delete %>
|
37
37
|
<% else %>
|
38
38
|
<%= link_to raw("Sign In"), "#" %>
|
39
39
|
<% end %>
|
@@ -37,6 +37,7 @@
|
|
37
37
|
|
38
38
|
<!-- class "auto-inherit-active-class" will automatically add "active" class for parent elements who are marked already with class "active" -->
|
39
39
|
|
40
|
+
<!-- Admin Dashboard -->
|
40
41
|
<li class="<%= nav_active?('admin/dashboard') ? 'active' : '' %>">
|
41
42
|
<%= link_to raw("<i class=\"linecons-desktop\"></i> <span class='title'>Dashboard</span>"), usman.admin_dashboard_url %>
|
42
43
|
</li>
|
@@ -52,29 +53,29 @@
|
|
52
53
|
<li class="<%= nav_class("admin/users") %>">
|
53
54
|
<%= link_to raw("<i class=\"linecons-user\"></i> <span class='title'>Manage Users</span>"), usman.admin_users_url %>
|
54
55
|
</li>
|
55
|
-
|
56
|
-
<li class="<%= nav_class("admin/users") %>">
|
57
|
-
<%= link_to raw("<i class=\"linecons-lock\"></i> <span class='title'>Manage Permissions</span>"), usman.admin_permissions_url %>
|
58
|
-
</li>
|
59
56
|
</ul>
|
60
|
-
|
61
57
|
</li>
|
62
58
|
|
59
|
+
<% if @current_user.super_admin? %>
|
63
60
|
<li class="">
|
64
61
|
<a href="/xenon/xenon-files/html/dashboard-1.html">
|
65
62
|
<i class="linecons-database"></i>
|
66
63
|
<span class="title">Master Data</span>
|
67
64
|
</a>
|
65
|
+
|
68
66
|
<ul>
|
69
67
|
<li class="">
|
70
68
|
<%= link_to raw("<i class=\"linecons-diamond\"></i> <span class='title'>Manage Features</span>"), usman.admin_features_url %>
|
71
69
|
</li>
|
72
70
|
|
73
|
-
<li class="">
|
74
|
-
<%= link_to raw("<i class=\"linecons-
|
71
|
+
<li class="<%= nav_class("admin/users") %>">
|
72
|
+
<%= link_to raw("<i class=\"linecons-lock\"></i> <span class='title'>Manage Permissions</span>"), usman.admin_permissions_url %>
|
75
73
|
</li>
|
76
74
|
</ul>
|
75
|
+
|
77
76
|
</li>
|
77
|
+
<% end %>
|
78
|
+
|
78
79
|
</ul>
|
79
80
|
|
80
81
|
</div>
|
@@ -9,8 +9,11 @@
|
|
9
9
|
</div>
|
10
10
|
|
11
11
|
<div>
|
12
|
-
|
13
|
-
<%= submit_tag("Save", :class=>"btn btn-
|
12
|
+
|
13
|
+
<%= submit_tag("Save", :class=>"btn btn-primary pull-right ml-10") %>
|
14
|
+
|
15
|
+
<%= link_to raw("<i class='fa fa-close mr-5'></i><span>Cancel</span>"), "#", onclick: "closeGenericModal();", class: "pull-right ml-10 btn btn-white" %>
|
16
|
+
|
14
17
|
</div>
|
15
18
|
<%= clear_tag(10) %>
|
16
19
|
</div>
|
@@ -2,7 +2,8 @@
|
|
2
2
|
<table class="table table-hover members-table middle-align">
|
3
3
|
<thead>
|
4
4
|
<tr>
|
5
|
-
<th style="text-align: center;width:
|
5
|
+
<th style="text-align: center;width:60px">#</th>
|
6
|
+
<th style="text-align: center;width:100px"><i class="fa fa-photo"></i></th>
|
6
7
|
<th>Name</th>
|
7
8
|
<th style="width:100px;">Status</th>
|
8
9
|
<th style="text-align: center;" colspan="2">Actions</th>
|
@@ -16,6 +17,8 @@
|
|
16
17
|
|
17
18
|
<tr id="tr_feature_<%= feature.id %>">
|
18
19
|
|
20
|
+
<td class="feature-image"></td>
|
21
|
+
|
19
22
|
<td class="feature-image">
|
20
23
|
<%= link_to(admin_feature_path(feature), remote: true) do %>
|
21
24
|
<%= display_image(feature, "feature_image.image.small.url", width: "32", height: "auto", class: "img-rectangle", alt: feature.display_name) %>
|