Module: Api::Members

Extended by:
ActiveSupport::Concern
Included in:
ChallengesController, NeedsController, PeerReviewsController, ProgramsController, ProjectsController, ProposalsController, SpacesController, WorkgroupsController
Defined in:
app/controllers/concerns/api/members.rb

Instance Method Summary collapse

Instance Method Details

#get_current_role(user, obj) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'app/controllers/concerns/api/members.rb', line 78

def get_current_role(user, obj)
  if user.has_role? :owner, obj
    'owner'
  elsif user.has_role? :admin, obj
    'admin'
  elsif user.has_role? :member, obj
    'member'
  elsif user.has_role? :pending, obj
    'pending'
  end
end

#get_roles_list(role) ⇒ Object

Returns all available roles for a given role



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/controllers/concerns/api/members.rb', line 91

def get_roles_list(role)
  if role == 'owner'
    %w[owner admin member]
  elsif role == 'admin'
    %w[admin member]
  elsif role == 'member'
    ['member']
  elsif role == 'pending'
    ['pending']
  else
    []
  end
end

#has_membershipObject

With a given user id returns find or not found if the given user is a member of the given object



15
16
17
18
19
20
21
22
# File 'app/controllers/concerns/api/members.rb', line 15

def has_membership
  @user = User.find(params[:user_id])
  if @obj.users.include?(@user)
    render json: { data: 'The current user is object member' }, status: :found
  else
    render json: { data: 'The current user is not a object member' }, status: :not_found
  end
end

#inviteObject

Depending on a given param the user is either looked in the database or an email is sent to the email given in the param if the user is found in the database his role is changed and another type of email is sent



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'app/controllers/concerns/api/members.rb', line 156

def invite
  if params[:stranger_emails].present?
    params[:stranger_emails].each do |stranger_email|
      InviteStrangerEmailWorker.perform_async(current_user.id, @obj.class.name, @obj.id, stranger_email)
    end
    render json: { data: 'Stranger(s) invited' }, status: :ok
  elsif params[:user_ids].present?
    User.where(id: params[:user_ids]).each do |invitee|
      next if invitee.roles.where(name: :member, resource: @obj).any?

      invitee.add_role(:member, @obj)
      InviteUserEmailWorker.perform_async(current_user.id, @obj.class.name, @obj.id, invitee.id)
      invitee.add_edge(@obj, 'is_member_of')
    end
    render json: { data: 'User(s) invited' }, status: :ok
  end
end

#invite_as_adminObject



174
175
176
177
178
179
180
181
182
# File 'app/controllers/concerns/api/members.rb', line 174

def invite_as_admin
  User.where(id: params[:user_ids]).each do |invitee|
    next if invitee.roles.where(name: :admin, resource: @obj).any?
    invitee.add_role(:admin, @obj)
    InviteUserEmailWorker.perform_async(current_user.id, @obj.class.name, @obj.id, invitee.id)
    invitee.add_edge(@obj, 'is_admin_of')
  end
  render json: { data: 'User(s) invited' }, status: :ok
end

#joinObject

We verify if the object is not archived if not we add the user/object relation for Project Workgroup and Space objects we send a confirmation email



130
131
132
133
134
135
136
137
# File 'app/controllers/concerns/api/members.rb', line 130

def join
  return archived_object if @obj.class.name != 'PeerReview' && @obj&.status == 'archived'
  return already_joined if current_user.roles.where(resource: @obj).any?
  return join_space if @obj.class.name == 'Space'
  return join_project_or_workgroup if @obj.class.name == 'Project' || @obj.class.name == 'Workgroup'

  join_object
end

#leaveObject

for a given object the user relation is deleted



140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/controllers/concerns/api/members.rb', line 140

def leave
  if current_user.roles.where(resource: @obj).any?
    @obj.applied_roles.pluck(:name).each do |role_name|
      current_user.remove_role(role_name, @obj)
      current_user.remove_edge(@obj, "is_#{role_name}_of")
    end

    render json: { data: 'User has left the object' }, status: :ok
  else
    render json: { data: 'User is not a member of the object' }, status: :forbidden
  end
end

#members_listObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/controllers/concerns/api/members.rb', line 105

def members_list
  members = params[:status] == 'pending' ? @obj.pending_members : @obj.all_owners_admins_members

  case params[:sort]
  when 'oldest'
    members = User.select("*").from(members).order(last_active_at: :asc)
  when 'roles'
    members = User.select("*").from(members).order(Arel.sql("role='owner' DESC, role='admin' DESC, role='member' DESC"))
  else
    members = User.select("*").from(members).order(last_active_at: :desc)
  end

  includes = %i[avatar_attachment interests ressources skills]

  pagy = Pagy.new(count: members.count, items: params.key?(:items) ? params[:items] : 25, page: params.key?(:page) ? params[:page] : 1)

  render json: members[pagy.offset, pagy.items],
         each_serializer: Api::MembersSerializer,
         parent: @obj,
         root: 'members',
         adapter: :json
end

#remove_memberObject

Same logic is applied here, the given user is deleted from the relation of the given object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/controllers/concerns/api/members.rb', line 26

def remove_member
  @user = User.find(params[:user_id])

  render(json: { data: 'You cannot have zero owner' }, status: :forbidden) && return if (User.with_role(:owner,
                                                                                                        @obj).count == 1) && @user.has_role?(
                                                                                                          :owner, @obj
                                                                                                        )

  @obj.applied_roles.pluck(:name).each do |role_name|
    @user.remove_role(role_name, @obj)
    @user.remove_edge(@obj, "is_#{role_name}_of")
  end

  render json: { data: 'The user was removed' }, status: :found
end

#update_memberObject

Same logic is applied here, with given object and given user we verify user role for that object, if he has the rights on the given object he can update his role



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
# File 'app/controllers/concerns/api/members.rb', line 44

def update_member
  @user = User.find(params[:user_id])
  if (new_role = params[:new_role])
    previous_role = get_current_role(@user, @obj)
    if (new_role == 'owner') && !current_user.has_role?(:owner, @obj)
      render(json: { data: 'Only an owner can set an owner' }, status: :forbidden) && return

    elsif (new_role == 'admin') && !current_user.has_role?(:admin, @obj)
      render(json: { data: 'Only an owner or admin can set an admin' }, status: :forbidden) && return

    elsif (previous_role == 'owner') && !current_user.has_role?(:owner, @obj)
      render(json: { data: "You cannot demote an owner if you aren't one" }, status: :forbidden) && return

    elsif (User.with_role(:owner, @obj).count == 1) && (previous_role == 'owner')
      render(json: { data: 'You cannot have zero owner' }, status: :forbidden) && return

    else
      get_roles_list(previous_role).each do |role|
        @user.remove_role role, @obj
        @user.remove_edge(@obj, "is_#{role}_of")
      end
      get_roles_list(new_role).each do |role|
        @user.add_role role, @obj
        @user.add_edge(@obj, "is_#{role}_of")
      end
      # converting pending members to active members for private objects
      @obj.notif_pending_join_request_approved(@user) if (new_role == 'member') && @obj.try(:is_private?)
      render json: { data: 'New role set' }, status: :ok
    end
  else
    render json: { data: 'Malformed request' }, status: :unprocessable_entity
  end
end