1
1
# https://raw.githubusercontent.com/scambra/devise_invitable/master/app/controllers/devise/invitations_controller.rb
2
2
class InvitationsController < Devise ::InvitationsController
3
- before_action :authenticate_user!
4
- after_action :verify_authorized , except : %i[ edit update ] # rubocop:disable Rails/LexicallyScopedActionFilter
3
+ before_action :authenticate_inviter! , only : %i[ new create resend ]
4
+ after_action :verify_authorized , only : %i[ new create resend ]
5
+
6
+ before_action :redirect_if_invitee_already_exists , only : :create
7
+ before_action :configure_permitted_parameters , only : :create
8
+
5
9
layout "admin_layout" , only : %i[ edit update ]
6
10
7
11
include UserPermissionsControllerMethods
@@ -13,34 +17,37 @@ def new
13
17
end
14
18
15
19
def create
16
- # Prevent an error when devise_invitable invites/updates an existing user,
17
- # and accepts_nested_attributes_for tries to create duplicate permissions.
18
- if ( self . resource = User . find_by ( email : params [ :user ] [ :email ] ) )
19
- authorize resource
20
- flash [ :alert ] = "User already invited. If you want to, you can click 'Resend signup email'."
21
- respond_with resource , location : users_path
20
+ authorize User
21
+
22
+ all_params = invite_params
23
+ all_params [ :require_2sv ] = invitee_requires_2sv ( all_params )
24
+
25
+ self . resource = resource_class . invite! ( all_params , current_inviter )
26
+ if resource . errors . empty?
27
+ grant_default_permissions ( resource )
28
+ EventLog . record_account_invitation ( resource , current_user )
29
+ set_flash_message :notice , :send_instructions , email : resource . email
30
+ respond_with resource , location : after_invite_path_for ( resource )
22
31
else
23
- # workaround for invitatable not providing a build_invitation which could be authorised before saving
24
- all_params = resource_params
25
- all_params [ :require_2sv ] = new_user_requires_2sv ( all_params . symbolize_keys )
26
-
27
- user = User . new ( all_params )
28
- user . organisation_id = all_params [ :organisation_id ]
29
- authorize user
30
-
31
- self . resource = resource_class . invite! ( all_params , current_inviter )
32
- if resource . errors . empty?
33
- grant_default_permissions ( resource )
34
- set_flash_message :notice , :send_instructions , email : resource . email
35
- respond_with resource , location : after_invite_path_for ( resource )
36
- else
37
- respond_with_navigational ( resource ) { render :new }
38
- end
39
-
40
- EventLog . record_account_invitation ( @user , current_user )
32
+ respond_with_navigational ( resource ) { render :new }
41
33
end
42
34
end
43
35
36
+ # rubocop:disable Lint/UselessMethodDefinition
37
+ # Renders app/views/devise/invitations/edit.html.erb
38
+ def edit
39
+ super
40
+ end
41
+
42
+ def update
43
+ super
44
+ end
45
+
46
+ def destroy
47
+ super
48
+ end
49
+ # rubocop:enable Lint/UselessMethodDefinition
50
+
44
51
def resend
45
52
user = User . find ( params [ :id ] )
46
53
authorize user
@@ -52,86 +59,39 @@ def resend
52
59
53
60
private
54
61
55
- def after_invite_path_for ( _resource )
56
- if new_user_requires_2sv ( resource )
62
+ def after_invite_path_for ( _ )
63
+ if invitee_requires_2sv ( resource )
57
64
users_path
58
65
else
59
66
require_2sv_user_path ( resource )
60
67
end
61
68
end
62
69
63
- # TODO: remove this method when we're on a version of devise_invitable which
64
- # no longer expects it to exist (v1.2.1 onwards)
65
- def build_resource
66
- self . resource = resource_class . new ( resource_params )
67
- end
68
-
69
- def resource_params
70
- sanitised_params = UserParameterSanitiser . new (
71
- user_params : unsanitised_user_params ,
72
- current_user_role :,
73
- ) . sanitise
74
-
75
- if params [ :action ] == "update"
76
- sanitised_params . to_h . merge ( invitation_token :)
77
- else
78
- sanitised_params . to_h
70
+ def grant_default_permissions ( user )
71
+ SupportedPermission . default . each do |default_permission |
72
+ user . grant_permission ( default_permission )
79
73
end
80
74
end
81
75
82
- # TODO: once we've upgraded Devise and DeviseInvitable, `resource_params`
83
- # hopefully won't be being called for actions like `#new` anymore and we
84
- # can change the following `params.fetch(:user)` to
85
- # `params.require(:user)`. See
86
- # https://github.com/scambra/devise_invitable/blob/v1.1.5/app/controllers/devise/invitations_controller.rb#L10
87
- # and
88
- # https://github.com/plataformatec/devise/blob/v2.2/app/controllers/devise_controller.rb#L99
89
- # for details :)
90
- def unsanitised_user_params
91
- params . require ( :user ) . permit (
92
- :name ,
93
- :email ,
94
- :organisation_id ,
95
- :invitation_token ,
96
- :password ,
97
- :password_confirmation ,
98
- :require_2sv ,
99
- :role ,
100
- supported_permission_ids : [ ] ,
101
- ) . to_h
102
- end
103
-
104
- # NOTE: `current_user` doesn't exist for `#edit` and `#update` actions as
105
- # implemented in our current (out-of-date) versions of Devise
106
- # (https://github.com/plataformatec/devise/blob/v2.2/app/controllers/devise_controller.rb#L117)
107
- # and DeviseInvitable
108
- # (https://github.com/scambra/devise_invitable/blob/v1.1.5/app/controllers/devise/invitations_controller.rb#L5)
109
- #
110
- # With the old attr_accessible approach, this would fall back to the
111
- # default whitelist (i.e. equivalent to the `:normal` role) and this
112
- # this preserves that behaviour. In fact, a user accepting an invitation
113
- # only needs to modify `password` and `password_confirmation` so we could
114
- # only permit those two params for the `edit` and `update` actions.
115
- def current_user_role
116
- current_user . try ( :role ) . try ( :to_sym ) || :normal
76
+ def organisation ( params )
77
+ Organisation . find_by ( id : params [ :organisation_id ] )
117
78
end
118
79
119
- def invitation_token
120
- unsanitised_user_params . fetch ( :invitation_token , { } )
80
+ def invitee_requires_2sv ( params )
81
+ organisation ( params ) &. require_2sv? || User . admin_roles . include? ( params [ :role ] )
121
82
end
122
83
123
- def update_resource_params
124
- resource_params
125
- end
126
-
127
- def grant_default_permissions ( user )
128
- SupportedPermission . default . each do |default_permission |
129
- user . grant_permission ( default_permission )
84
+ def redirect_if_invitee_already_exists
85
+ if ( resource = User . find_by ( email : params [ :user ] [ :email ] ) )
86
+ authorize resource
87
+ flash [ :alert ] = "User already invited. If you want to, you can click 'Resend signup email'."
88
+ respond_with resource , location : users_path
130
89
end
131
90
end
132
91
133
- def new_user_requires_2sv ( params )
134
- ( params [ :organisation_id ] . present? && Organisation . find ( params [ :organisation_id ] ) . require_2sv? ) ||
135
- %w[ superadmin admin organisation_admin super_organisation_admin ] . include? ( params [ :role ] )
92
+ def configure_permitted_parameters
93
+ keys = [ :name , :organisation_id , { supported_permission_ids : [ ] } ]
94
+ keys << :role if policy ( User ) . assign_role?
95
+ devise_parameter_sanitizer . permit ( :invite , keys :)
136
96
end
137
97
end
0 commit comments