-
-
Notifications
You must be signed in to change notification settings - Fork 508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3260] Add feature to manage partner users for a Partner as a Organization/Bank #3266
Changes from 41 commits
fa7267f
2bf70e7
7543691
76d3559
c70ed81
8a97f8c
59705a2
3ba9e15
90d7440
c7c4718
85b505c
f2799fc
2428e22
7d8bbad
530ef2d
1b7945d
eb0c08e
98d7183
a77c123
cc60914
4267d36
49eeb4f
d43f14d
f58b941
846db60
7804b87
8f15d3b
1355926
301aa3f
f58d3e3
66b225a
1849a7c
20ea8d0
2900177
3067c47
136871d
da15745
b9bdf96
59cc42a
e330716
49d936c
4128e4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# frozen_String_literal: true | ||
|
||
class PartnerUsersController < ApplicationController | ||
before_action :set_partner, only: %i[index create destroy resend_invitation] | ||
|
||
def index | ||
@users = @partner.users | ||
@user = User.new(name: "") | ||
end | ||
|
||
def create | ||
@user = UserInviteService.invite( | ||
email: user_params[:email], | ||
name: user_params[:name], | ||
roles: [Role::PARTNER], | ||
resource: @partner | ||
) | ||
if @user.valid? | ||
redirect_back(fallback_location: "/", | ||
notice: "#{@user.name} has been invited. Invitation email sent to #{@user.email}") | ||
else | ||
flash[:alert] = "Invitation failed. Check the form for errors." | ||
@users = @partner.users | ||
render :index | ||
end | ||
end | ||
|
||
def destroy | ||
user = User.find(params[:id]) | ||
|
||
if user.remove_role(Role::PARTNER, @partner) | ||
redirect_back(fallback_location: "/", notice: "Access to #{@partner.name} has been revoked for #{user.display_name}.") | ||
else | ||
redirect_back(fallback_location: "/", alert: "Invitation failed. Check the form for errors.") | ||
end | ||
end | ||
|
||
def resend_invitation | ||
user = User.find(params[:id]) | ||
|
||
if user.invitation_accepted_at.nil? | ||
user.invite! | ||
else | ||
user.errors.add(:base, "User has already accepted invitation.") | ||
end | ||
Comment on lines
+41
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can replace this with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep I think so! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'am actually thinking that a new method makes sense, maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's fair - we can add a separate method to the service that only works on an existing user and doesn't change the roles. |
||
|
||
if user.errors.none? | ||
redirect_back(fallback_location: "/", notice: "Invitation email sent to #{user.email}") | ||
else | ||
redirect_back(fallback_location: "/", alert: user.errors.full_messages.to_sentence) | ||
end | ||
end | ||
|
||
private | ||
|
||
def set_partner | ||
@partner = Partner.find(params[:partner_id]) | ||
end | ||
|
||
def user_params | ||
params.require(:user).permit(:email, :name) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -129,18 +129,6 @@ def invite | |
end | ||
end | ||
|
||
def invite_partner_user | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still referenced from config/routes.rb, but nothing submits to it, so not an immediate blocker There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I created #4459 to address |
||
partner = current_organization.partners.find(params[:partner]) | ||
UserInviteService.invite(name: params[:name], | ||
email: params[:email], | ||
roles: [Role::PARTNER], | ||
resource: partner) | ||
|
||
redirect_to partner_path(partner), notice: "We have invited #{params[:email]} to #{partner.name}!" | ||
rescue StandardError => e | ||
redirect_to partner_path(partner), error: "Failed to invite #{params[:email]} to #{partner.name} due to: #{e.message}" | ||
end | ||
|
||
def recertify_partner | ||
@partner = current_organization.partners.find(params[:id]) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<div class="card card-primary"> | ||
<div class="card-header"> | ||
<h3 class="card-title">Invite New User</h3> | ||
</div> | ||
|
||
<%= simple_form_for user, url: partner_users_path(partner) do |f| %> | ||
<div class="card-body"> | ||
<div class="form-group"> | ||
<%= f.input :name, label: "Name", placeholder: "Name", required: true %> | ||
</div> | ||
<div class="form-group"> | ||
<%= f.input :email, label: "Email", placeholder: "Email", required: true %> | ||
</div> | ||
</div> | ||
|
||
<div class="card-footer"> | ||
<%= f.submit "Invite User", class: 'btn btn-primary float-right' %> | ||
</div> | ||
<% end %> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<tr> | ||
<td><%= user.id %></td> | ||
<td><%= user.name %></td> | ||
<td><%= user.email %></td> | ||
<td> | ||
<% if user.last_sign_in_at.present? %> | ||
<%= user.last_sign_in_at.strftime('%B %-d, %Y') %> | ||
<% else %> | ||
<span class="badge bg-danger">Never</span> | ||
<% end %> | ||
</td> | ||
<td> | ||
<% if user.invitation_accepted_at %> | ||
<span class="badge bg-success">Accepted</span> | ||
<% else %> | ||
<div class='d-flex flex-column justify-content-center align-items-start'> | ||
<span class="badge bg-warning"> | ||
<div>Waiting Acceptance</div> | ||
</span> | ||
<small>Last invite sent | ||
<strong><%= time_ago_in_words(user.invitation_sent_at) %> ago</strong> on <%= user.invitation_sent_at.strftime('%B %-d, %Y') %> | ||
</small> | ||
</div> | ||
<% end %> | ||
</td> | ||
<td class='d-flex'> | ||
<% unless user.invitation_accepted_at %> | ||
<%= button_to "Resend Invite", resend_invitation_partner_user_path(partner, user), method: :post, class: "btn btn-primary btn-sm mr-2" %> | ||
<% end %> | ||
<%= button_to "Remove Access", partner_user_path(partner, user), method: :delete, data: { confirm: "Are you sure you want to remove access to #{user.name} to access #{partner.name}?" }, class: "btn btn-danger btn-sm" %> | ||
</td> | ||
</tr> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<div class="card card-success"> | ||
<div class="card-header"> | ||
<h3 class="card-title">Users</h3> | ||
</div> | ||
|
||
<div class="card-body table-responsive p-0"> | ||
<table class="table table-hover text-nowrap"> | ||
<thead> | ||
<tr> | ||
<th>Name & Email</th> | ||
<th>Last Login</th> | ||
<th>Invitation Status</th> | ||
<th>Action</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<% users.order(name: :asc).each do |user| %> | ||
<tr> | ||
<td> | ||
<div class='d-flex flex-column'> | ||
<span><%= user.name %></span> | ||
<small><%= user.email %></small> | ||
</div> | ||
</td> | ||
<td> | ||
<small> | ||
<% if user.last_sign_in_at.present? %> | ||
<%= time_ago_in_words(user.last_sign_in_at) %> ago <small>(<%= user.invitation_sent_at.strftime('%b %d %Y') %>)</small> | ||
<% else %> | ||
<span class="badge bg-danger">Never</span> | ||
<% end %> | ||
</small> | ||
</td> | ||
<td> | ||
<% if user.invitation_accepted_at %> | ||
<span class="badge bg-success"> | ||
<i class="fas fa-check"></i> Accepted | ||
</span> | ||
<% else %> | ||
<div class='d-flex flex-column justify-content-center align-items-start'> | ||
<span class="badge bg-warning"> | ||
<div>Waiting Acceptance</div> | ||
</span> | ||
<small style='font-size:10px'> | ||
Last invite sent <strong><%= time_ago_in_words(user.invitation_sent_at) %> ago on <%= user.invitation_sent_at.strftime('%b %d %Y') %></strong> | ||
</small> | ||
</div> | ||
<% end %> | ||
</td> | ||
<td class='d-flex flex-column'> | ||
<% unless user.invitation_accepted_at %> | ||
<%= button_to resend_invitation_partner_user_path(partner, user), method: :post, class: "btn btn-warning btn-xs mb-2" do %> | ||
<i class="fa fa-envelope"></i> Resend Invitation | ||
<% end %> | ||
<% end %> | ||
<%= button_to partner_user_path(partner, user), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-danger btn-xs" do %> | ||
<i class="fa fa-ban"></i> Remove Access | ||
<% end %> | ||
|
||
</td> | ||
</tr> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<section class="content-header"> | ||
<div class="container-fluid"> | ||
<div class="row mb-2"> | ||
<div class="col-sm-6"> | ||
<% content_for :title, "Partner | Users" %> | ||
<h1> | ||
<%= @partner.name %>'s Users | ||
</h1> | ||
</div> | ||
<div class="col-sm-6"> | ||
<ol class="breadcrumb float-sm-right"> | ||
<li class="breadcrumb-item"><%= link_to(dashboard_path) do %> | ||
<i class="fa fa-dashboard"></i> Home | ||
<% end %> | ||
</li> | ||
<li class="breadcrumb-item"> | ||
<%= link_to(@partner) do %> | ||
<%= @partner.name %> | ||
<% end %> | ||
</li> | ||
<li class="breadcrumb-item">Users</li> | ||
</ol> | ||
</div> | ||
</div> | ||
</div><!-- /.container-fluid --> | ||
</section> | ||
|
||
<section class="content"> | ||
<div class="container-fluid"> | ||
<div class="row"> | ||
<div class="col-md-9"> | ||
<%= render 'users', users: @users, partner: @partner %> | ||
</div> | ||
|
||
<div class="col-md-3"> | ||
<%= render 'form', user: @user, partner: @partner %> | ||
</div> | ||
</div> | ||
</div> | ||
</section> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
roles: | ||
partner: 'Regular' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only link to this controller from bank admins, but we don't here restrict access to only admins. I'll open a separate ticket to address this minor security flaw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created #4458 to address