lesli_audit 0.1.0
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 +7 -0
- data/Rakefile +5 -0
- data/app/assets/config/lesli_audit_manifest.js +38 -0
- data/app/assets/images/lesli_audit/audit-logo.svg +72 -0
- data/app/assets/javascripts/lesli_audit/application.js +3592 -0
- data/app/assets/stylesheets/lesli_audit/application.scss +35 -0
- data/app/assets/stylesheets/lesli_audit/dashboard.scss +0 -0
- data/app/controllers/lesli_audit/analytics_controller.rb +36 -0
- data/app/controllers/lesli_audit/application_controller.rb +4 -0
- data/app/controllers/lesli_audit/dashboards_controller.rb +59 -0
- data/app/helpers/lesli_audit/analytics_helper.rb +4 -0
- data/app/helpers/lesli_audit/application_helper.rb +4 -0
- data/app/helpers/lesli_audit/dashboards_helper.rb +4 -0
- data/app/jobs/lesli_audit/application_job.rb +4 -0
- data/app/mailers/lesli_audit/application_mailer.rb +6 -0
- data/app/models/lesli_audit/analytic.rb +4 -0
- data/app/models/lesli_audit/application_record.rb +5 -0
- data/app/models/lesli_audit/dashboard.rb +4 -0
- data/app/services/lesli_audit/account/activity_services.rb +69 -0
- data/app/services/lesli_audit/analytic_service.rb +151 -0
- data/app/services/lesli_audit/analytics/trend_services.rb +84 -0
- data/app/services/lesli_audit/analytics/visitor_service.rb +166 -0
- data/app/services/lesli_audit/request_services.rb +71 -0
- data/app/services/lesli_audit/users/activity_services.rb +61 -0
- data/app/services/lesli_audit/users/log_services.rb +62 -0
- data/app/services/lesli_audit/users/registration_services.rb +62 -0
- data/app/services/lesli_audit/users/role_services.rb +61 -0
- data/app/services/lesli_audit/users/working_hour_services.rb +78 -0
- data/app/views/lesli_audit/analytics/_analytic.html.erb +2 -0
- data/app/views/lesli_audit/analytics/_form.html.erb +17 -0
- data/app/views/lesli_audit/analytics/edit.html.erb +10 -0
- data/app/views/lesli_audit/analytics/index.html.erb +1 -0
- data/app/views/lesli_audit/analytics/new.html.erb +9 -0
- data/app/views/lesli_audit/analytics/show.html.erb +10 -0
- data/app/views/lesli_audit/dashboards/_dashboard.html.erb +2 -0
- data/app/views/lesli_audit/dashboards/_form.html.erb +17 -0
- data/app/views/lesli_audit/dashboards/edit.html.erb +10 -0
- data/app/views/lesli_audit/dashboards/index.html.erb +14 -0
- data/app/views/lesli_audit/dashboards/new.html.erb +9 -0
- data/app/views/lesli_audit/dashboards/show.html.erb +1 -0
- data/app/views/lesli_audit/partials/_engine-navigation.html.erb +39 -0
- data/config/routes.rb +45 -0
- data/db/migrate/v1.0/0803000110_create_lesli_audit_accounts.rb +42 -0
- data/db/migrate/v1.0/0803050110_create_lesli_audit_dashboards.rb +51 -0
- data/db/migrate/v1.0/0803050210_create_lesli_audit_dashboard_components.rb +53 -0
- data/lib/lesli_audit/engine.rb +18 -0
- data/lib/lesli_audit/version.rb +3 -0
- data/lib/lesli_audit.rb +6 -0
- data/lib/tasks/lesli_audit_tasks.rake +4 -0
- data/lib/vue/application.js +102 -0
- data/lib/vue/apps/accounts/activities.vue +48 -0
- data/lib/vue/apps/analytics/index.vue +18 -0
- data/lib/vue/apps/analytics/requests.vue +67 -0
- data/lib/vue/apps/analytics/trends.vue +149 -0
- data/lib/vue/apps/analytics/visitors.vue +91 -0
- data/lib/vue/apps/requests/index.vue +123 -0
- data/lib/vue/apps/security/passwords.vue +52 -0
- data/lib/vue/apps/security/sessions.vue +63 -0
- data/lib/vue/apps/users/activities.vue +49 -0
- data/lib/vue/apps/users/logs.vue +49 -0
- data/lib/vue/apps/users/registrations.vue +98 -0
- data/lib/vue/apps/users/roles.vue +70 -0
- data/lib/vue/apps/users/workingHours.vue +52 -0
- data/lib/vue/stores/accounts/activities.js +87 -0
- data/lib/vue/stores/analytics/visitors.js +130 -0
- data/lib/vue/stores/request.js +70 -0
- data/lib/vue/stores/security/password.js +75 -0
- data/lib/vue/stores/security/session.js +78 -0
- data/lib/vue/stores/users/activities.js +76 -0
- data/lib/vue/stores/users/logs.js +74 -0
- data/lib/vue/stores/users/registrations.js +61 -0
- data/lib/vue/stores/users/roles.js +52 -0
- data/lib/vue/stores/users/working_hours.js +92 -0
- data/license +674 -0
- data/readme.md +120 -0
- metadata +134 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
// // ·
|
|
35
|
+
body.cloud_audit-dashboard { @import "lesli/templates/dashboards"; }
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module LesliAudit
|
|
2
|
+
class AnalyticsController < ApplicationController
|
|
3
|
+
|
|
4
|
+
# GET /analytics
|
|
5
|
+
def index
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def visitors
|
|
9
|
+
respond_with_successful(AnalyticService.new(current_user, query).visitors)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def users
|
|
13
|
+
respond_with_successful(AnalyticService.new(current_user, query).users)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def devices
|
|
17
|
+
respond_with_successful(AnalyticService.new(current_user, query).devices)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def controllers
|
|
21
|
+
respond_with_successful(AnalyticService.new(current_user, query).controllers)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
28
|
+
def set_analytic
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Only allow a list of trusted parameters through.
|
|
32
|
+
def analytic_params
|
|
33
|
+
params.fetch(:analytic, {})
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module LesliAudit
|
|
2
|
+
class DashboardsController < ApplicationController
|
|
3
|
+
#before_action :set_dashboard, only: %i[ show edit update destroy ]
|
|
4
|
+
|
|
5
|
+
# GET /dashboards
|
|
6
|
+
def index
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# GET /dashboards/1
|
|
10
|
+
def show
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# GET /dashboards/new
|
|
14
|
+
def new
|
|
15
|
+
@dashboard = Dashboard.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# GET /dashboards/1/edit
|
|
19
|
+
def edit
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# POST /dashboards
|
|
23
|
+
def create
|
|
24
|
+
@dashboard = Dashboard.new(dashboard_params)
|
|
25
|
+
|
|
26
|
+
if @dashboard.save
|
|
27
|
+
redirect_to @dashboard, notice: "Dashboard was successfully created."
|
|
28
|
+
else
|
|
29
|
+
render :new, status: :unprocessable_entity
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# PATCH/PUT /dashboards/1
|
|
34
|
+
def update
|
|
35
|
+
if @dashboard.update(dashboard_params)
|
|
36
|
+
redirect_to @dashboard, notice: "Dashboard was successfully updated.", status: :see_other
|
|
37
|
+
else
|
|
38
|
+
render :edit, status: :unprocessable_entity
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# DELETE /dashboards/1
|
|
43
|
+
def destroy
|
|
44
|
+
@dashboard.destroy
|
|
45
|
+
redirect_to dashboards_url, notice: "Dashboard was successfully destroyed.", status: :see_other
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
50
|
+
def set_dashboard
|
|
51
|
+
@dashboard = Dashboard.find(params[:id])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Only allow a list of trusted parameters through.
|
|
55
|
+
def dashboard_params
|
|
56
|
+
params.fetch(:dashboard, {})
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS development platform.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
=end
|
|
32
|
+
|
|
33
|
+
module CloudAudit
|
|
34
|
+
class Analytics::ActivityServices < ApplicationLesliServices
|
|
35
|
+
|
|
36
|
+
def index
|
|
37
|
+
search_string = nil # query[:search].downcase.gsub(" ","%") unless query[:search].blank?
|
|
38
|
+
|
|
39
|
+
activities = current_user.account.activities
|
|
40
|
+
|
|
41
|
+
activities = activities.select(
|
|
42
|
+
:id,
|
|
43
|
+
:title,
|
|
44
|
+
:description,
|
|
45
|
+
:system_process,
|
|
46
|
+
:system_module,
|
|
47
|
+
"payload ->'to'->>0 as send_to",
|
|
48
|
+
Date2.new.date_time.db_timestamps()
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# search if search params was sent
|
|
52
|
+
unless search_string.blank?
|
|
53
|
+
activities = activities.where(["
|
|
54
|
+
system_module like :search_string
|
|
55
|
+
or system_process like :search_string
|
|
56
|
+
or description like :search_string
|
|
57
|
+
or title like :search_string
|
|
58
|
+
or payload->'to'->>0 like :search_string",
|
|
59
|
+
].join(" or "), {
|
|
60
|
+
search_string: "%#{search_string}%"
|
|
61
|
+
})
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
activities.page(query[:pagination][:page])
|
|
65
|
+
.per(query[:pagination][:perPage])
|
|
66
|
+
.order(created_at: :desc)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS development platform.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
=end
|
|
32
|
+
|
|
33
|
+
module LesliAudit
|
|
34
|
+
class AnalyticService < Lesli::ApplicationLesliService
|
|
35
|
+
|
|
36
|
+
LIMIT=5
|
|
37
|
+
|
|
38
|
+
# @overwrite
|
|
39
|
+
# @return {Hash} Paginated list of the records
|
|
40
|
+
# @param {query} Has of the formated queries/filters that will be applied to filter data
|
|
41
|
+
# @description
|
|
42
|
+
# @example
|
|
43
|
+
def visitors
|
|
44
|
+
|
|
45
|
+
group = 'day'
|
|
46
|
+
#group = params[:bygroup] if ['month','week','day'].include?(params[:bygroup])
|
|
47
|
+
|
|
48
|
+
# only the users of the account
|
|
49
|
+
usrs = current_user.account.users
|
|
50
|
+
|
|
51
|
+
requests = Lesli::User::Request.where(user: usrs).group("DATE_TRUNC('month', created_at)") if group == 'month'
|
|
52
|
+
requests = Lesli::User::Request.where(user: usrs).group("DATE_TRUNC('week', created_at)") if group == 'week'
|
|
53
|
+
requests = Lesli::User::Request.where(user: usrs).group("DATE_TRUNC('day', created_at)") if group == 'day'
|
|
54
|
+
|
|
55
|
+
requests = apply_filters(requests, query)
|
|
56
|
+
|
|
57
|
+
requests.limit(30).order("date DESC").select(
|
|
58
|
+
"count(id) resources",
|
|
59
|
+
"sum(request_count) requests",
|
|
60
|
+
"DATE_TRUNC('day', created_at) date"
|
|
61
|
+
).map do |request|
|
|
62
|
+
{
|
|
63
|
+
:requests => request[:requests],
|
|
64
|
+
:resources => request[:resources],
|
|
65
|
+
:date => Date2.new(request[:date]).date.to_s
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def users
|
|
71
|
+
|
|
72
|
+
requests = Lesli::User::Request
|
|
73
|
+
.joins(:user)
|
|
74
|
+
.where(user: current_user.account.users)
|
|
75
|
+
.group(:email)
|
|
76
|
+
|
|
77
|
+
requests = apply_filters(requests, query)
|
|
78
|
+
|
|
79
|
+
requests = requests.limit(LIMIT).order("requests DESC").select(
|
|
80
|
+
:email,
|
|
81
|
+
"count(lesli_user_requests.id) resources",
|
|
82
|
+
"sum(lesli_user_requests.request_count) requests"
|
|
83
|
+
).map do |request|
|
|
84
|
+
{
|
|
85
|
+
:requests => request[:requests],
|
|
86
|
+
:resources => request[:resources],
|
|
87
|
+
:email => request[:email]
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def devices
|
|
93
|
+
agents = Lesli::User::Agent.where(user: current_user.account.users)
|
|
94
|
+
agents = agents.group("platform", "browser")
|
|
95
|
+
agents = agents.limit(LIMIT).order(sum_count: :desc).sum(:count).map do |req|
|
|
96
|
+
{
|
|
97
|
+
:device => req[0].join("/"),
|
|
98
|
+
:visits => req[1]
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
return agents
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def controllers
|
|
106
|
+
requests = Lesli::User::Request.where(user: current_user.account.users).group("request_controller")
|
|
107
|
+
|
|
108
|
+
requests = apply_filters(requests, query)
|
|
109
|
+
|
|
110
|
+
requests = requests.limit(LIMIT).order("requests DESC").select(
|
|
111
|
+
:request_controller,
|
|
112
|
+
"sum(request_count) requests"
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
def apply_filters requests, params
|
|
119
|
+
|
|
120
|
+
return requests
|
|
121
|
+
|
|
122
|
+
# filter by search string
|
|
123
|
+
unless params[:search].blank?
|
|
124
|
+
requests = requests.where(
|
|
125
|
+
"lower(request_agent) like :search_string or lower(request_controller) like :search_string or lower(request_action) like :search_string",
|
|
126
|
+
{
|
|
127
|
+
search_string: "%#{params[:search].downcase.gsub(" ","%")}%"
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# filter by time
|
|
133
|
+
unless params[:bytime].blank? && params[:bytime] != 'all'
|
|
134
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day)..) if params[:bytime] == 'day'
|
|
135
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 7.day)..) if params[:bytime] == 'week'
|
|
136
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 30.day)..) if params[:bytime] == 'month'
|
|
137
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 6.month)..) if params[:bytime] == 'sixmonth'
|
|
138
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 1.year)..) if params[:bytime] == 'year'
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# filter by request format
|
|
142
|
+
if (!params[:byformat].blank? && ['html', 'json'].include?(params[:byformat]))
|
|
143
|
+
requests = requests.where(:request_action => 'show') if params[:byformat] == 'html'
|
|
144
|
+
requests = requests.where(:request_format => params[:byformat])
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
requests
|
|
148
|
+
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS development platform.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
=end
|
|
32
|
+
|
|
33
|
+
module CloudAudit
|
|
34
|
+
class Analytics::TrendServices < ApplicationLesliServices
|
|
35
|
+
|
|
36
|
+
def index
|
|
37
|
+
|
|
38
|
+
#Default period
|
|
39
|
+
period = 'day'
|
|
40
|
+
|
|
41
|
+
#Get filters from http request
|
|
42
|
+
filters = nil #params[:f]
|
|
43
|
+
|
|
44
|
+
#Get start and final date only if the request have filters
|
|
45
|
+
unless filters.blank?
|
|
46
|
+
finalDate = filters[:finalDate]
|
|
47
|
+
startDate = filters[:startDate]
|
|
48
|
+
period = filters[:groupBy]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#Default search if range date is not provided
|
|
52
|
+
user_requests = ::User::Request.select('created_at').where(created_at: (Time.now.beginning_of_day - 3.month)..)
|
|
53
|
+
|
|
54
|
+
# Verify if there are startDate and finalDate
|
|
55
|
+
unless startDate.blank? || finalDate.blank?
|
|
56
|
+
user_requests = ::User::Request.where(created_at: (startDate..finalDate))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
unless period.blank? || (period != 'day' && period != 'hour')
|
|
60
|
+
#Group by day/time depending on the period param
|
|
61
|
+
if period == 'day'
|
|
62
|
+
user_requests = user_requests.group("DATE_TRUNC('#{period}', created_at)")
|
|
63
|
+
user_requests.count.map do |request|
|
|
64
|
+
{
|
|
65
|
+
:day => request[0].strftime('%A').to_s,
|
|
66
|
+
:count => request[1]
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
elsif period == 'hour'
|
|
72
|
+
user_requests = user_requests.group("DATE_PART('#{period}', created_at)").order('date_part_hour_created_at')
|
|
73
|
+
user_requests.count.map do |request|
|
|
74
|
+
{
|
|
75
|
+
:hour => request[0],
|
|
76
|
+
:count => request[1]
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS development platform.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
=end
|
|
32
|
+
|
|
33
|
+
module LesliAudit
|
|
34
|
+
class Analytics::VisitorService < Lesli::ApplicationLesliService
|
|
35
|
+
|
|
36
|
+
LIMIT=5
|
|
37
|
+
|
|
38
|
+
# @overwrite
|
|
39
|
+
# @return {Hash} Paginated list of the records
|
|
40
|
+
# @param {query} Has of the formated queries/filters that will be applied to filter data
|
|
41
|
+
# @description
|
|
42
|
+
# @example
|
|
43
|
+
def visits
|
|
44
|
+
|
|
45
|
+
return Lesli::User::Request.group("DATE_TRUNC('day', created_at)").limit(30).order("date DESC").select(
|
|
46
|
+
"count(id) resources",
|
|
47
|
+
"sum(request_count) requests",
|
|
48
|
+
"DATE_TRUNC('day', created_at) date"
|
|
49
|
+
).map do |request|
|
|
50
|
+
{
|
|
51
|
+
:requests => request[:requests],
|
|
52
|
+
:resources => request[:resources],
|
|
53
|
+
:date => Date2.new(request[:date]).date.to_s
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
group = 'day'
|
|
58
|
+
#group = params[:bygroup] if ['month','week','day'].include?(params[:bygroup])
|
|
59
|
+
|
|
60
|
+
# only the users of the account
|
|
61
|
+
usrs = current_user.account.users
|
|
62
|
+
|
|
63
|
+
requests = ::User::Request.where(user: usrs).group("DATE_TRUNC('month', created_at)") if group == 'month'
|
|
64
|
+
requests = ::User::Request.where(user: usrs).group("DATE_TRUNC('week', created_at)") if group == 'week'
|
|
65
|
+
requests = ::User::Request.where(user: usrs).group("DATE_TRUNC('day', created_at)") if group == 'day'
|
|
66
|
+
|
|
67
|
+
requests = apply_filters(requests, query)
|
|
68
|
+
|
|
69
|
+
requests.limit(30).order("date DESC").select(
|
|
70
|
+
"count(id) resources",
|
|
71
|
+
"sum(request_count) requests",
|
|
72
|
+
"DATE_TRUNC('day', created_at) date"
|
|
73
|
+
).map do |request|
|
|
74
|
+
{
|
|
75
|
+
:requests => request[:requests],
|
|
76
|
+
:resources => request[:resources],
|
|
77
|
+
:date => Date2.new(request[:date]).date.to_s
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def users
|
|
83
|
+
requests = ::User::Request
|
|
84
|
+
.joins(:user)
|
|
85
|
+
.where(user: current_user.account.users)
|
|
86
|
+
.group(:email)
|
|
87
|
+
|
|
88
|
+
requests = apply_filters(requests, query)
|
|
89
|
+
|
|
90
|
+
requests = requests.limit(LIMIT).order("requests DESC").select(
|
|
91
|
+
:email,
|
|
92
|
+
"count(user_requests.id) resources",
|
|
93
|
+
"sum(user_requests.request_count) requests"
|
|
94
|
+
).map do |request|
|
|
95
|
+
{
|
|
96
|
+
:requests => request[:requests],
|
|
97
|
+
:resources => request[:resources],
|
|
98
|
+
:email => request[:email]
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
return requests
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def devices
|
|
106
|
+
agents = ::User::Agent.where(user: current_user.account.users)
|
|
107
|
+
agents = agents.group("platform", "browser")
|
|
108
|
+
agents = agents.limit(LIMIT).order(sum_count: :desc).sum(:count).map do |req|
|
|
109
|
+
{
|
|
110
|
+
:device => req[0].join("/"),
|
|
111
|
+
:visits => req[1]
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
return agents
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def controllers
|
|
119
|
+
requests = Lesli::User::Request.where(lesli_user: current_user.account.users).group("request_controller")
|
|
120
|
+
|
|
121
|
+
requests = apply_filters(requests, query)
|
|
122
|
+
|
|
123
|
+
requests = requests.limit(LIMIT).order("requests DESC").select(
|
|
124
|
+
:request_controller,
|
|
125
|
+
"sum(request_count) requests"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return requests
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
def apply_filters requests, params
|
|
134
|
+
|
|
135
|
+
return requests
|
|
136
|
+
|
|
137
|
+
# filter by search string
|
|
138
|
+
unless params[:search].blank?
|
|
139
|
+
requests = requests.where(
|
|
140
|
+
"lower(request_agent) like :search_string or lower(request_controller) like :search_string or lower(request_action) like :search_string",
|
|
141
|
+
{
|
|
142
|
+
search_string: "%#{params[:search].downcase.gsub(" ","%")}%"
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# filter by time
|
|
148
|
+
unless params[:bytime].blank? && params[:bytime] != 'all'
|
|
149
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day)..) if params[:bytime] == 'day'
|
|
150
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 7.day)..) if params[:bytime] == 'week'
|
|
151
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 30.day)..) if params[:bytime] == 'month'
|
|
152
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 6.month)..) if params[:bytime] == 'sixmonth'
|
|
153
|
+
requests = requests.where(created_at: (Time.now.beginning_of_day - 1.year)..) if params[:bytime] == 'year'
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# filter by request format
|
|
157
|
+
if (!params[:byformat].blank? && ['html', 'json'].include?(params[:byformat]))
|
|
158
|
+
requests = requests.where(:request_action => 'show') if params[:byformat] == 'html'
|
|
159
|
+
requests = requests.where(:request_format => params[:byformat])
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
requests
|
|
163
|
+
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|