biovision-base 0.5.170614 → 0.7.170709
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -0
- data/app/assets/images/biovision/base/placeholders/image.svg +1 -1
- data/app/assets/images/biovision/base/placeholders/region_image.svg +1 -0
- data/app/assets/stylesheets/biovision/base/admin.scss +226 -31
- data/app/assets/stylesheets/biovision/base/biovision.scss +45 -104
- data/app/assets/stylesheets/biovision/base/buttons.scss +3 -2
- data/app/assets/stylesheets/biovision/base/default.scss +66 -45
- data/app/assets/stylesheets/biovision/base/default_admin.scss +10 -0
- data/app/assets/stylesheets/biovision/base/default_application.scss +8 -0
- data/app/assets/stylesheets/biovision/base/filters.scss +4 -4
- data/app/assets/stylesheets/biovision/base/layout.scss +113 -0
- data/app/assets/stylesheets/biovision/base/message-box.scss +3 -3
- data/app/assets/stylesheets/biovision/base/regions.scss +9 -0
- data/app/assets/stylesheets/biovision/base/tootik.scss +6 -6
- data/app/assets/stylesheets/biovision/base/track.scss +7 -6
- data/app/assets/stylesheets/biovision/base/users.scss +64 -0
- data/app/controllers/admin/login_attempts_controller.rb +6 -0
- data/app/controllers/admin/privileges_controller.rb +37 -1
- data/app/controllers/admin/regions_controller.rb +37 -0
- data/app/controllers/admin/users_controller.rb +2 -2
- data/app/controllers/authentication_controller.rb +27 -26
- data/app/controllers/concerns/authentication.rb +20 -0
- data/app/controllers/my/confirmations_controller.rb +8 -3
- data/app/controllers/my/login_attempts_controller.rb +9 -0
- data/app/controllers/my/profiles_controller.rb +10 -2
- data/app/controllers/my/tokens_controller.rb +20 -0
- data/app/controllers/regions_controller.rb +73 -0
- data/app/helpers/biovision_regions_helper.rb +22 -0
- data/app/mailers/application_mailer.rb +5 -0
- data/app/mailers/user_mailer.rb +8 -0
- data/app/models/central_region.rb +49 -0
- data/app/models/concerns/required_unique_name.rb +1 -1
- data/app/models/concerns/required_unique_slug.rb +1 -1
- data/app/models/login_attempt.rb +24 -0
- data/app/models/privilege.rb +176 -1
- data/app/models/region.rb +100 -0
- data/app/models/user.rb +118 -1
- data/app/models/user_privilege.rb +52 -1
- data/app/services/code_manager/confirmation.rb +1 -1
- data/app/services/user_bouncer.rb +37 -0
- data/app/uploaders/header_image_uploader.rb +50 -0
- data/app/uploaders/region_image_uploader.rb +53 -0
- data/app/views/admin/agents/entity/_preview.jbuilder +8 -0
- data/app/views/admin/codes/index.html.erb +1 -1
- data/app/views/admin/editable_pages/index.html.erb +1 -1
- data/app/views/admin/index/index.html.erb +4 -0
- data/app/views/admin/login_attempts/_nav_item.html.erb +6 -0
- data/app/views/admin/login_attempts/entity/_in_list.html.erb +16 -0
- data/app/views/admin/login_attempts/included/_agents.jbuilder +3 -0
- data/app/views/admin/login_attempts/included/_users.jbuilder +3 -0
- data/app/views/admin/login_attempts/index.html.erb +16 -0
- data/app/views/admin/login_attempts/index.jbuilder +28 -0
- data/app/views/admin/privilege_groups/index.html.erb +1 -1
- data/app/views/admin/privileges/_toggleable.html.erb +7 -0
- data/app/views/admin/privileges/entity/_in_list.html.erb +1 -0
- data/app/views/admin/privileges/entity/_region.html.erb +12 -0
- data/app/views/admin/privileges/regions.jbuilder +10 -0
- data/app/views/admin/privileges/show.html.erb +2 -0
- data/app/views/admin/regions/_nav_item.html.erb +2 -0
- data/app/views/admin/regions/_toggleable.html.erb +7 -0
- data/app/views/admin/regions/entity/_in_list.html.erb +32 -0
- data/app/views/admin/regions/index.html.erb +22 -0
- data/app/views/admin/regions/show.html.erb +95 -0
- data/app/views/admin/tokens/index.html.erb +1 -1
- data/app/views/admin/users/_search.html.erb +1 -1
- data/app/views/admin/users/entity/_preview.jbuilder +12 -0
- data/app/views/admin/users/entity/_privilege.html.erb +23 -7
- data/app/views/admin/users/entity/_privilege_tree.html.erb +2 -2
- data/app/views/admin/users/privileges.html.erb +47 -12
- data/app/views/admin/users/show.html.erb +17 -1
- data/app/views/admin/users/tokens.html.erb +1 -1
- data/app/views/authentication/new.html.erb +1 -2
- data/app/views/layouts/admin/_footer.html.erb +8 -0
- data/app/views/layouts/application/_footer.html.erb +5 -0
- data/app/views/layouts/application/_header.html.erb +9 -0
- data/app/views/layouts/application/header/_authentication.html.erb +7 -0
- data/app/views/layouts/application/header/_logo.html.erb +3 -0
- data/app/views/layouts/application/header/_navigation.html.erb +0 -0
- data/app/views/layouts/application/header/authentication/_links.html.erb +4 -0
- data/app/views/layouts/application/header/authentication/_plate.html.erb +4 -0
- data/app/views/layouts/mailer.html.erb +13 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/my/confirmations/show.html.erb +11 -1
- data/app/views/my/index/index.html.erb +6 -4
- data/app/views/{admin/tokens → my/login_attempts}/_list.html.erb +1 -1
- data/app/views/my/login_attempts/_nav_item.html.erb +6 -0
- data/app/views/my/login_attempts/entity/_in_list.html.erb +13 -0
- data/app/views/my/login_attempts/included/_agents.jbuilder +7 -0
- data/app/views/my/login_attempts/index.html.erb +13 -0
- data/app/views/my/login_attempts/index.jbuilder +22 -0
- data/app/views/my/profiles/_nav_item.html.erb +6 -0
- data/app/views/my/profiles/new/_form.html.erb +49 -23
- data/app/views/my/profiles/new.html.erb +2 -2
- data/app/views/{admin/codes → my/tokens}/_list.html.erb +1 -1
- data/app/views/my/tokens/_nav_item.html.erb +6 -0
- data/app/views/my/tokens/_toggleable.html.erb +7 -0
- data/app/views/my/tokens/entity/_in_list.html.erb +18 -0
- data/app/views/my/tokens/index.html.erb +13 -0
- data/app/views/privileges/_form.html.erb +7 -0
- data/app/views/regions/_form.html.erb +73 -0
- data/app/views/regions/edit.html.erb +20 -0
- data/app/views/regions/new.html.erb +17 -0
- data/app/views/shared/_counters.html.erb +0 -0
- data/app/views/shared/_pagination.jbuilder +9 -0
- data/app/views/{admin/editable_pages → shared/admin}/_list.html.erb +2 -2
- data/app/views/user_mailer/login_attempt.html.erb +7 -0
- data/config/locales/common-ru.yml +5 -0
- data/config/locales/editable-pages-ru.yml +1 -1
- data/config/locales/regions-ru.yml +62 -0
- data/config/locales/users-ru.yml +48 -6
- data/config/routes.rb +19 -2
- data/db/migrate/20170301000201_create_regions.rb +32 -0
- data/db/migrate/20170302000001_create_users.rb +1 -0
- data/db/migrate/20170302000101_create_privileges.rb +2 -0
- data/db/migrate/20170302000102_create_user_privileges.rb +1 -0
- data/db/migrate/20170302000103_create_privilege_groups.rb +1 -0
- data/db/migrate/20170302000104_create_privilege_group_privileges.rb +4 -0
- data/db/migrate/20170629120000_create_login_attempts.rb +19 -0
- data/lib/biovision/base/engine.rb +6 -0
- data/lib/biovision/base/privilege_methods.rb +21 -3
- data/lib/biovision/base/version.rb +1 -1
- data/lib/tasks/{biovision/agents.rake → agents.rake} +0 -0
- data/lib/tasks/{biovision/browsers.rake → browsers.rake} +0 -0
- data/lib/tasks/{biovision/codes.rake → codes.rake} +0 -0
- data/lib/tasks/regions.rake +70 -0
- data/lib/tasks/{biovision/tokens.rake → tokens.rake} +0 -0
- data/lib/tasks/{biovision/users.rake → users.rake} +0 -0
- metadata +75 -17
- data/app/assets/stylesheets/biovision/base/fonts.scss +0 -9
- data/app/controllers/concerns/biovision/admin/privileges.rb +0 -34
- data/app/models/concerns/biovision/privilege_base.rb +0 -143
- data/app/models/concerns/biovision/user_base.rb +0 -124
- data/app/models/concerns/biovision/user_privilege_base.rb +0 -46
- data/app/views/admin/privilege_groups/_list.html.erb +0 -11
- data/app/views/authentication/_info.html.erb +0 -8
@@ -1,13 +1,13 @@
|
|
1
1
|
form.filter fieldset {
|
2
|
-
font-size: $
|
3
|
-
line-height:
|
2
|
+
font-size: $font-size-decreased;
|
3
|
+
line-height: #{$font-size-normal * 1.5};
|
4
4
|
|
5
5
|
> div {
|
6
6
|
display: flex;
|
7
7
|
flex-wrap: wrap;
|
8
8
|
|
9
9
|
input {
|
10
|
-
font-size: $
|
10
|
+
font-size: $font-size-decreased;
|
11
11
|
}
|
12
12
|
|
13
13
|
> div {
|
@@ -48,6 +48,6 @@ form.filter fieldset {
|
|
48
48
|
|
49
49
|
button {
|
50
50
|
margin: .8rem 0 0 0;
|
51
|
-
font-size: $
|
51
|
+
font-size: $font-size-decreased;
|
52
52
|
}
|
53
53
|
}
|
@@ -0,0 +1,113 @@
|
|
1
|
+
html {
|
2
|
+
font: 10px $font-family-main;
|
3
|
+
margin: 0;
|
4
|
+
padding: 0;
|
5
|
+
-webkit-text-size-adjust: none;
|
6
|
+
-moz-text-size-adjust: none;
|
7
|
+
-ms-text-size-adjust: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
h1, h2, h3, h4, h6, h6 {
|
11
|
+
color: $text-color-heading;
|
12
|
+
font-family: $font-family-heading;
|
13
|
+
font-weight: 500;
|
14
|
+
margin: 0;
|
15
|
+
}
|
16
|
+
|
17
|
+
h1 {
|
18
|
+
font-size: 3rem;
|
19
|
+
line-height: 4.2rem;
|
20
|
+
}
|
21
|
+
|
22
|
+
a:link {
|
23
|
+
color: $link-color;
|
24
|
+
text-decoration: none;
|
25
|
+
transition: color .125s;
|
26
|
+
}
|
27
|
+
|
28
|
+
a:visited {
|
29
|
+
color: $link-color-visited;
|
30
|
+
}
|
31
|
+
|
32
|
+
a:active,
|
33
|
+
a:hover {
|
34
|
+
color: $link-color-hover;
|
35
|
+
text-decoration: underline;
|
36
|
+
}
|
37
|
+
|
38
|
+
body {
|
39
|
+
color: $text-color-primary;
|
40
|
+
display: flex;
|
41
|
+
flex-direction: column;
|
42
|
+
font-size: $font-size-normal;
|
43
|
+
justify-content: space-between;
|
44
|
+
margin: 0;
|
45
|
+
min-height: 100vh;
|
46
|
+
min-width: $content-width-min;
|
47
|
+
padding: 0;
|
48
|
+
|
49
|
+
> footer,
|
50
|
+
> header {
|
51
|
+
> div {
|
52
|
+
margin: 0 auto;
|
53
|
+
padding: .4rem;
|
54
|
+
max-width: $content-width;
|
55
|
+
|
56
|
+
.authentication {
|
57
|
+
> div {
|
58
|
+
display: flex;
|
59
|
+
align-items: center;
|
60
|
+
|
61
|
+
&.links {
|
62
|
+
a:link,
|
63
|
+
a:visited {
|
64
|
+
@include nav-button;
|
65
|
+
margin: 0 .4rem;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
&.plate {
|
70
|
+
.logout {
|
71
|
+
@include action-button;
|
72
|
+
margin-left: 1rem;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
> header {
|
81
|
+
background: $background-header;
|
82
|
+
border-bottom: $border-primary;
|
83
|
+
|
84
|
+
> div {
|
85
|
+
align-items: center;
|
86
|
+
display: flex;
|
87
|
+
flex-wrap: wrap;
|
88
|
+
|
89
|
+
.logo {
|
90
|
+
margin-right: auto;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
> footer {
|
96
|
+
background: $background-footer;
|
97
|
+
border-top: $border-primary;
|
98
|
+
margin: auto 0 0 0;
|
99
|
+
|
100
|
+
> div {
|
101
|
+
color: $text-color-secondary;
|
102
|
+
font-size: $font-size-decreased;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
#main {
|
108
|
+
background: $background-main;
|
109
|
+
flex: 1;
|
110
|
+
margin: 0 auto;
|
111
|
+
max-width: $content-width;
|
112
|
+
padding: .8rem;
|
113
|
+
}
|
@@ -34,7 +34,7 @@ section.errors {
|
|
34
34
|
> h2 {
|
35
35
|
background: #fee image_url('biovision/base/icons/alert.svg') no-repeat center left 1.6rem / 1.6rem 1.6rem;
|
36
36
|
color: #400;
|
37
|
-
font-size: $
|
37
|
+
font-size: $font-size-large;
|
38
38
|
padding: 1.6rem 1.6rem 1.6rem 4.8rem;
|
39
39
|
}
|
40
40
|
|
@@ -44,8 +44,8 @@ section.errors {
|
|
44
44
|
}
|
45
45
|
|
46
46
|
.field_with_errors {
|
47
|
-
display: inline-block;
|
48
47
|
background: #fee;
|
48
|
+
display: inline-block;
|
49
49
|
}
|
50
50
|
|
51
51
|
span.not-found {
|
@@ -53,8 +53,8 @@ span.not-found {
|
|
53
53
|
cursor: default;
|
54
54
|
|
55
55
|
&:before {
|
56
|
-
content: '\26A0';
|
57
56
|
color: #f00;
|
57
|
+
content: '\26A0';
|
58
58
|
margin-right: .4rem;
|
59
59
|
}
|
60
60
|
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
// https://eliorshalev.github.io/tootik/
|
2
2
|
|
3
|
-
$tootik_background_color: #000000;
|
4
|
-
$tootik_success_color: #8bc34a;
|
5
|
-
$tootik_info_color: #29d2e4;
|
6
|
-
$tootik_warning_color: #f87d09;
|
7
|
-
$tootik_danger_color: #e91e63;
|
8
|
-
$tootik_text_color: #ffffff;
|
3
|
+
$tootik_background_color: #000000 !default;
|
4
|
+
$tootik_success_color: #8bc34a !default;
|
5
|
+
$tootik_info_color: #29d2e4 !default;
|
6
|
+
$tootik_warning_color: #f87d09 !default;
|
7
|
+
$tootik_danger_color: #e91e63 !default;
|
8
|
+
$tootik_text_color: #ffffff !default;
|
9
9
|
|
10
10
|
[data-tootik] {
|
11
11
|
position: relative;
|
@@ -14,15 +14,16 @@
|
|
14
14
|
|
15
15
|
div.track {
|
16
16
|
border: .1rem dotted;
|
17
|
-
|
17
|
+
box-sizing: border-box;
|
18
|
+
font-size: $font-size-decreased;
|
18
19
|
margin: .4rem;
|
19
20
|
padding: .4rem;
|
20
|
-
width:
|
21
|
+
width: 100%;
|
21
22
|
|
22
23
|
> div {
|
23
|
-
overflow: hidden;
|
24
|
-
text-overflow: ellipsis;
|
25
|
-
white-space: nowrap;
|
26
|
-
width: 100%;
|
24
|
+
//overflow: hidden;
|
25
|
+
//text-overflow: ellipsis;
|
26
|
+
//white-space: nowrap;
|
27
|
+
//width: 100%;
|
27
28
|
}
|
28
29
|
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
.privileges {
|
2
|
+
.entity {
|
3
|
+
> input[type=checkbox] {
|
4
|
+
&:checked ~ ul {
|
5
|
+
button,
|
6
|
+
input[type=checkbox] {
|
7
|
+
display: none;
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
div.user-search {
|
15
|
+
.message-box-warning {
|
16
|
+
background-position: left .4rem center;
|
17
|
+
font-weight: 400;
|
18
|
+
margin: .4rem;
|
19
|
+
padding: .4rem .4rem .4rem 2.4rem;
|
20
|
+
}
|
21
|
+
|
22
|
+
.results {
|
23
|
+
ul {
|
24
|
+
margin: .4rem;
|
25
|
+
padding: 0;
|
26
|
+
|
27
|
+
li {
|
28
|
+
cursor: pointer;
|
29
|
+
font-size: 1.4rem;
|
30
|
+
font-weight: 400;
|
31
|
+
line-height: 2rem;
|
32
|
+
list-style: none;
|
33
|
+
margin: 0;
|
34
|
+
padding: 0 .4rem;
|
35
|
+
|
36
|
+
&:hover {
|
37
|
+
outline: .1rem solid #070;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
.my-profile-new {
|
45
|
+
> section {
|
46
|
+
dl {
|
47
|
+
input {
|
48
|
+
max-width: 32rem;
|
49
|
+
|
50
|
+
&:not([size]) {
|
51
|
+
width: calc(100% - 1rem);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
.trap {
|
57
|
+
width: .01rem;
|
58
|
+
height: .01rem;
|
59
|
+
overflow: hidden;
|
60
|
+
position: absolute;
|
61
|
+
left: -300rem;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
@@ -1,5 +1,41 @@
|
|
1
1
|
class Admin::PrivilegesController < AdminController
|
2
2
|
include LockableEntity
|
3
3
|
include EntityPriority
|
4
|
-
include
|
4
|
+
include ToggleableEntity
|
5
|
+
|
6
|
+
before_action :set_entity, except: [:index]
|
7
|
+
before_action :check_entity_lock, only: [:toggle]
|
8
|
+
|
9
|
+
# get /admin/privileges
|
10
|
+
def index
|
11
|
+
@collection = Privilege.for_tree
|
12
|
+
end
|
13
|
+
|
14
|
+
# get /admin/privileges/:id
|
15
|
+
def show
|
16
|
+
end
|
17
|
+
|
18
|
+
# get /admin/privileges/:id/users
|
19
|
+
def users
|
20
|
+
@collection = @entity.users.page_for_administration(current_page)
|
21
|
+
end
|
22
|
+
|
23
|
+
# get /admin/privileges/:id/regions
|
24
|
+
def regions
|
25
|
+
@user = User.find_by(id: params[:user_id])
|
26
|
+
@collection = Region.visible.for_tree(params[:parent_id]).reject { |r| @entity.has_user?(@user, r) }
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def restrict_access
|
32
|
+
require_privilege :administrator
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_entity
|
36
|
+
@entity = Privilege.find_by(id: params[:id], deleted: false)
|
37
|
+
if @entity.nil?
|
38
|
+
handle_http_404("Cannot find non-deleted privilege #{params[:id]}")
|
39
|
+
end
|
40
|
+
end
|
5
41
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Admin::RegionsController < AdminController
|
2
|
+
include ToggleableEntity
|
3
|
+
include LockableEntity
|
4
|
+
|
5
|
+
before_action :set_entity, except: [:index]
|
6
|
+
before_action :check_entity_lock, only: [:toggle]
|
7
|
+
|
8
|
+
# get /admin/regions
|
9
|
+
def index
|
10
|
+
@collection = Region.for_tree
|
11
|
+
end
|
12
|
+
|
13
|
+
# get /admin/regions/:id
|
14
|
+
def show
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def restrict_access
|
20
|
+
require_privilege_group :region_managers
|
21
|
+
end
|
22
|
+
|
23
|
+
def restrict_editing
|
24
|
+
unless @entity.editable_by?(current_user)
|
25
|
+
handle_http_401('Current user cannot edit region')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_entity
|
30
|
+
@entity = Region.find_by(id: params[:id])
|
31
|
+
if @entity.nil?
|
32
|
+
handle_http_404("Cannot find region #{params[:id]}")
|
33
|
+
else
|
34
|
+
restrict_editing
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -31,14 +31,14 @@ class Admin::UsersController < AdminController
|
|
31
31
|
|
32
32
|
# put /admin/users/:id/privileges/:privilege_id
|
33
33
|
def grant_privilege
|
34
|
-
@privilege.grant(@entity)
|
34
|
+
@privilege.grant(@entity, Region.find_by(id: params[:region_id]))
|
35
35
|
|
36
36
|
render json: { data: { user_privilege_ids: @entity.user_privilege_ids } }
|
37
37
|
end
|
38
38
|
|
39
39
|
# delete /admin/users/:id/privileges/:privilege_id
|
40
40
|
def revoke_privilege
|
41
|
-
@privilege.revoke(@entity)
|
41
|
+
@privilege.revoke(@entity, Region.find_by(id: params[:region_id]))
|
42
42
|
|
43
43
|
render json: { data: { user_privilege_ids: @entity.user_privilege_ids } }
|
44
44
|
end
|
@@ -10,16 +10,9 @@ class AuthenticationController < ApplicationController
|
|
10
10
|
|
11
11
|
# post /login
|
12
12
|
def create
|
13
|
-
user
|
14
|
-
|
15
|
-
|
16
|
-
Metric.register(User::METRIC_AUTHENTICATION_SUCCESS)
|
17
|
-
redirect_to root_path
|
18
|
-
else
|
19
|
-
Metric.register(User::METRIC_AUTHENTICATION_FAILURE)
|
20
|
-
flash.now[:alert] = t(:could_not_log_in)
|
21
|
-
render :new, status: :unauthorized
|
22
|
-
end
|
13
|
+
@user = User.find_by(slug: param_from_request(:login).downcase)
|
14
|
+
@bouncer = UserBouncer.new(@user, tracking_for_entity)
|
15
|
+
bounce_or_allow
|
23
16
|
end
|
24
17
|
|
25
18
|
# delete /logout
|
@@ -39,12 +32,6 @@ class AuthenticationController < ApplicationController
|
|
39
32
|
|
40
33
|
private
|
41
34
|
|
42
|
-
def deactivate_token
|
43
|
-
token = Token.find_by token: cookies['token'].split(':').last
|
44
|
-
token.update active: false
|
45
|
-
pop_token
|
46
|
-
end
|
47
|
-
|
48
35
|
def set_foreign_site
|
49
36
|
@foreign_site = ForeignSite.with_slug(params[:provider]).first
|
50
37
|
if @foreign_site.nil?
|
@@ -54,17 +41,31 @@ class AuthenticationController < ApplicationController
|
|
54
41
|
end
|
55
42
|
end
|
56
43
|
|
57
|
-
def
|
58
|
-
if
|
59
|
-
|
60
|
-
value: cookies['pt'],
|
61
|
-
expires: 1.year.from_now,
|
62
|
-
domain: :all,
|
63
|
-
httponly: true
|
64
|
-
}
|
65
|
-
cookies['pt'] = nil
|
44
|
+
def bounce_or_allow
|
45
|
+
if @bouncer.let_user_in?(param_from_request(:password))
|
46
|
+
successful_authentication
|
66
47
|
else
|
67
|
-
|
48
|
+
failed_authentication
|
68
49
|
end
|
69
50
|
end
|
51
|
+
|
52
|
+
def successful_authentication
|
53
|
+
create_token_for_user(@user)
|
54
|
+
Metric.register(User::METRIC_AUTHENTICATION_SUCCESS)
|
55
|
+
redirect_after_success
|
56
|
+
end
|
57
|
+
|
58
|
+
def failed_authentication
|
59
|
+
Metric.register(User::METRIC_AUTHENTICATION_FAILURE)
|
60
|
+
flash.now[:alert] = t(:could_not_log_in)
|
61
|
+
render :new, status: :unauthorized
|
62
|
+
end
|
63
|
+
|
64
|
+
def redirect_after_success
|
65
|
+
return_path = cookies['return_path'].to_s
|
66
|
+
return_path = my_path unless return_path[0] == '/'
|
67
|
+
cookies.delete 'return_path', domain: :all
|
68
|
+
|
69
|
+
redirect_to return_path
|
70
|
+
end
|
70
71
|
end
|
@@ -16,4 +16,24 @@ module Authentication
|
|
16
16
|
httponly: true
|
17
17
|
}
|
18
18
|
end
|
19
|
+
|
20
|
+
def deactivate_token
|
21
|
+
token = Token.find_by token: cookies['token'].split(':').last
|
22
|
+
token.update active: false
|
23
|
+
pop_token
|
24
|
+
end
|
25
|
+
|
26
|
+
def pop_token
|
27
|
+
if cookies['pt']
|
28
|
+
cookies['token'] = {
|
29
|
+
value: cookies['pt'],
|
30
|
+
expires: 1.year.from_now,
|
31
|
+
domain: :all,
|
32
|
+
httponly: true
|
33
|
+
}
|
34
|
+
cookies.delete 'pt', domain: :all
|
35
|
+
else
|
36
|
+
cookies.delete 'token', domain: :all
|
37
|
+
end
|
38
|
+
end
|
19
39
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class My::ConfirmationsController < ApplicationController
|
2
|
-
|
2
|
+
include Authentication
|
3
|
+
|
4
|
+
# before_action :restrict_anonymous_access, only: [:create, :update]
|
3
5
|
before_action :redirect_confirmed_user, only: [:create, :update]
|
4
6
|
|
5
7
|
# get /my/confirmation
|
@@ -20,9 +22,10 @@ class My::ConfirmationsController < ApplicationController
|
|
20
22
|
# patch /my/confirmation
|
21
23
|
def update
|
22
24
|
code = Code.find_by(body: param_from_request(:code))
|
23
|
-
manager = CodeManager::Confirmation.new(code
|
25
|
+
manager = CodeManager::Confirmation.new(code)
|
24
26
|
if manager.code_is_valid?
|
25
27
|
manager.activate
|
28
|
+
create_token_for_user(code.user)
|
26
29
|
redirect_to my_path
|
27
30
|
else
|
28
31
|
redirect_to my_confirmation_path, alert: t('my.confirmations.update.invalid_code')
|
@@ -32,6 +35,8 @@ class My::ConfirmationsController < ApplicationController
|
|
32
35
|
protected
|
33
36
|
|
34
37
|
def redirect_confirmed_user
|
35
|
-
|
38
|
+
if current_user&.email_confirmed?
|
39
|
+
redirect_to my_path
|
40
|
+
end
|
36
41
|
end
|
37
42
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class My::LoginAttemptsController < ApplicationController
|
2
|
+
before_action :restrict_anonymous_access
|
3
|
+
|
4
|
+
# get /my/login_attempts
|
5
|
+
def index
|
6
|
+
@collection = LoginAttempt.page_for_owner(current_user, current_page)
|
7
|
+
@agents = Agent.where(id: @collection.pluck(:agent_id))
|
8
|
+
end
|
9
|
+
end
|
@@ -12,7 +12,7 @@ class My::ProfilesController < ApplicationController
|
|
12
12
|
# post /my/profile
|
13
13
|
def create
|
14
14
|
if params[:agree]
|
15
|
-
redirect_to root_path,
|
15
|
+
redirect_to root_path, alert: t('my.profiles.create.are_you_bot')
|
16
16
|
else
|
17
17
|
create_user
|
18
18
|
end
|
@@ -46,7 +46,7 @@ class My::ProfilesController < ApplicationController
|
|
46
46
|
if @user.save
|
47
47
|
Metric.register(User::METRIC_REGISTRATION)
|
48
48
|
create_token_for_user(@user)
|
49
|
-
|
49
|
+
redirect_after_creation
|
50
50
|
else
|
51
51
|
render :new, status: :bad_request
|
52
52
|
end
|
@@ -78,4 +78,12 @@ class My::ProfilesController < ApplicationController
|
|
78
78
|
parameters[:phone_confirmed] = false if parameters[:phone] && parameters[:phone] != current_user.phone
|
79
79
|
parameters
|
80
80
|
end
|
81
|
+
|
82
|
+
def redirect_after_creation
|
83
|
+
return_path = cookies['return_path'].to_s
|
84
|
+
return_path = my_profile_path unless return_path[0] == '/'
|
85
|
+
cookies.delete 'return_path', domain: :all
|
86
|
+
|
87
|
+
redirect_to return_path, notice: t('my.profiles.create.success')
|
88
|
+
end
|
81
89
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class My::TokensController < ApplicationController
|
2
|
+
include ToggleableEntity
|
3
|
+
|
4
|
+
before_action :restrict_anonymous_access
|
5
|
+
before_action :set_entity, except: [:index]
|
6
|
+
|
7
|
+
# get /my
|
8
|
+
def index
|
9
|
+
@collection = Token.page_for_owner(current_user, current_page)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def set_entity
|
15
|
+
@entity = Token.owned_by(current_user).find_by(id: params[:id])
|
16
|
+
if @entity.nil?
|
17
|
+
handle_http_404('Cannot find token for current user')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class RegionsController < AdminController
|
2
|
+
before_action :set_entity, only: [:edit, :update, :destroy]
|
3
|
+
before_action :restrict_editing, only: [:edit, :update, :destroy]
|
4
|
+
|
5
|
+
# post /regions
|
6
|
+
def create
|
7
|
+
@entity = Region.new(creation_parameters)
|
8
|
+
if @entity.save
|
9
|
+
cache_relatives
|
10
|
+
redirect_to admin_region_path(@entity)
|
11
|
+
else
|
12
|
+
render :new, status: :bad_request
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# get /regions/:id/edit
|
17
|
+
def edit
|
18
|
+
end
|
19
|
+
|
20
|
+
# patch /regions/:id
|
21
|
+
def update
|
22
|
+
if @entity.update(entity_parameters)
|
23
|
+
cache_relatives
|
24
|
+
redirect_to admin_region_path(@entity), notice: t('regions.update.success')
|
25
|
+
else
|
26
|
+
render :edit, status: :bad_request
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# delete /post_categories/:id
|
31
|
+
def destroy
|
32
|
+
if @entity.destroy
|
33
|
+
flash[:notice] = t('regions.destroy.success')
|
34
|
+
end
|
35
|
+
redirect_to admin_regions_path
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def restrict_access
|
41
|
+
require_privilege_group :region_managers
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_entity
|
45
|
+
@entity = Region.find_by(id: params[:id])
|
46
|
+
if @entity.nil?
|
47
|
+
handle_http_404('Cannot find region')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def restrict_editing
|
52
|
+
unless @entity.editable_by?(current_user)
|
53
|
+
redirect_to admin_region_path(@entity.id), alert: t('regions.edit.forbidden')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def entity_parameters
|
58
|
+
params.require(:region).permit(Region.entity_parameters)
|
59
|
+
end
|
60
|
+
|
61
|
+
def creation_parameters
|
62
|
+
params.require(:region).permit(Region.creation_parameters)
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache_relatives
|
66
|
+
@entity.cache_parents!
|
67
|
+
unless @entity.parent.blank?
|
68
|
+
parent = @entity.parent
|
69
|
+
parent.cache_children!
|
70
|
+
parent.save
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BiovisionRegionsHelper
|
2
|
+
# @param [Region] entity
|
3
|
+
def admin_region_link(entity)
|
4
|
+
link_to(entity.name, admin_region_path(entity.id))
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [Region] entity
|
8
|
+
def region_image_preview(entity)
|
9
|
+
unless entity.image.blank?
|
10
|
+
versions = "#{entity.image.preview_2x.url} 2x"
|
11
|
+
image_tag(entity.image.preview.url, alt: entity.name, srcset: versions)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Region] entity
|
16
|
+
def region_image_medium(entity)
|
17
|
+
unless entity.image.blank?
|
18
|
+
versions = "#{entity.image.medium_2x.url} 2x"
|
19
|
+
image_tag(entity.image.medium.url, alt: entity.name, srcset: versions)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|