summaryrefslogtreecommitdiff
path: root/app/controllers/concerns/membership_actions.rb
blob: 409e6d4c4d2cf372b7b4a3a40645af9db67821e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
module MembershipActions
  include MembersPresentation
  extend ActiveSupport::Concern

  def create
    create_params = params.permit(:user_ids, :access_level, :expires_at)
    result = Members::CreateService.new(current_user, create_params).execute(membershipable)

    if result[:status] == :success
      redirect_to members_page_url, notice: 'Users were successfully added.'
    else
      redirect_to members_page_url, alert: result[:message]
    end
  end

  def update
    update_params = params.require(root_params_key).permit(:access_level, :expires_at)
    member = membershipable.members_and_requesters.find(params[:id])
    member = Members::UpdateService
      .new(current_user, update_params)
      .execute(member)
      .present(current_user: current_user)

    present_members([member])
    respond_to do |format|
      format.js { render 'shared/members/update', locals: { member: member } }
    end
  end

  def destroy
    member = membershipable.members_and_requesters.find(params[:id])
    Members::DestroyService.new(current_user).execute(member)

    respond_to do |format|
      format.html do
        message = "User was successfully removed from #{source_type}."
        redirect_to members_page_url, notice: message
      end

      format.js { head :ok }
    end
  end

  def request_access
    membershipable.request_access(current_user)

    redirect_to polymorphic_path(membershipable),
                notice: 'Your request for access has been queued for review.'
  end

  def approve_access_request
    access_requester = membershipable.requesters.find(params[:id])
    Members::ApproveAccessRequestService
      .new(current_user, params)
      .execute(access_requester)

    redirect_to members_page_url
  end

  def leave
    member = membershipable.members_and_requesters.find_by!(user_id: current_user.id)
    Members::DestroyService.new(current_user).execute(member)

    notice =
      if member.request?
        "Your access request to the #{source_type} has been withdrawn."
      else
        "You left the \"#{membershipable.human_name}\" #{source_type}."
      end

    respond_to do |format|
      format.html do
        redirect_path = member.request? ? member.source : [:dashboard, membershipable.class.to_s.tableize]
        redirect_to redirect_path, notice: notice
      end

      format.json { render json: { notice: notice } }
    end
  end

  def resend_invite
    member = membershipable.members.find(params[:id])

    if member.invite?
      member.resend_invite

      redirect_to members_page_url, notice: 'The invitation was successfully resent.'
    else
      redirect_to members_page_url, alert: 'The invitation has already been accepted.'
    end
  end

  protected

  def membershipable
    raise NotImplementedError
  end

  def root_params_key
    case membershipable
    when Namespace
      :group_member
    when Project
      :project_member
    else
      raise "Unknown membershipable type: #{membershipable}!"
    end
  end

  def members_page_url
    case membershipable
    when Namespace
      polymorphic_url([membershipable, :members])
    when Project
      project_project_members_path(membershipable)
    else
      raise "Unknown membershipable type: #{membershipable}!"
    end
  end

  def source_type
    @source_type ||= membershipable.class.to_s.humanize(capitalize: false)
  end
end