usman 0.1.5 → 0.1.6dev2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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) %>
|