Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
# frozen_string_literal: true

require 'json'

module FacultyRBAC
  # Permits RBAC queries relating to a specific group
  class Group
    class Queries
      OWN_MEMBERS = %(
        select distinct username
        from rbac_user_group ug
        where ug.group_id = ?
      )

      MEMBERS = %(
        select distinct username
        from rbac_recursive_group gg
        join rbac_user_group ug on ug.group_id = gg.member_group_id
        where gg.group_id = ?
      )

      MEMBERSHIPS = %(
        select distinct username, ug.group_id
        from rbac_recursive_group gg
        join rbac_user_group ug on ug.group_id = gg.member_group_id
        where gg.group_id = ?
      )

      OWN_MEMBER_GROUPS = %(
        select distinct member_group_id group_id
        from rbac_group_group gg
        where gg.group_id = ?
      )

      MEMBER_GROUPS = %(
        select distinct member_group_id group_id
        from rbac_recursive_group gg
        where gg.group_id = ? and gg.member_group_id <> gg.group_id
      )
    end

    def self.create(controller, **params)
      controller.db.transaction do
        gid = controller.db[:rbac_group].insert
        g = Group.new(controller, gid)
        g.register(**params) unless params.empty?
        g
      end
    end

    def initialize(controller, group_id)
      @id = group_id.to_i
      @controller = controller
    end

    attr_reader :id

    def to_i
      @id
    end

    def _db
      @controller.db
    end

    def _cte_select(name, query, *parameters)
      _db[name].with(name, _db[query, *parameters])
    end

    def delete
      _db[:rbac_group].where(id: @id).delete
    end

    def own_members
      DatasetDelegator.new(:username, _cte_select(:own_members, Queries::OWN_MEMBERS, @id))
    end

    def members
      DatasetDelegator.new(:username, _cte_select(:members, Queries::MEMBERS, @id))
    end

    def memberships
      _cte_select(:memberships, Queries::MEMBERSHIPS, @id)
    end

    def grants
      _db[:rbac_grant].where(group_id: @id).map { |grant| Grant[@controller, grant] }
    end

    def add_members(*users)
      _db[:rbac_user_group].insert_ignore.returning(:username).import(
        %i[username group_id],
        users.map { |user| [user.to_s, @id] }
      )
    end

    def own_members=(users)
      add_members(*users)
      usernames = Array(users).map(&:to_s)
      _db[:rbac_user_group].where(group_id: @id).exclude(username: usernames).delete
    end

    def remove_members(*users)
      usernames = users.map(&:to_s)
      _db[:rbac_user_group].where(username: usernames, group_id: @id).delete
    end

    def own_member_groups
      DatasetDelegator.new(:group_id, _cte_select(:own_member_groups, Queries::OWN_MEMBER_GROUPS, @id))
    end

    def member_groups
      DatasetDelegator.new(:group_id, _cte_select(:member_groups, Queries::MEMBER_GROUPS, @id))
    end

    def add_member_groups(*group_ids)
      _db[:rbac_group_group].insert_ignore.returning(:member_group_id).import(
        %i[member_group_id group_id],
        group_ids.map { |group_id| [group_id.to_i, @id] }
      )
    end

    def own_member_groups=(group_ids)
      add_member_groups(*group_ids)
      member_gids = Array(group_ids).map(&:to_i)
      _db[:rbac_group_group].where(group_id: @id).exclude(member_group_id: member_gids).delete
    end

    def remove_member_groups(*group_ids)
      member_gids = group_ids.map(&:to_i)
      _db[:rbac_group_group].where(member_group_id: member_gids, group_id: @id).delete
    end

    def register(type:, context:, description:)
      type_id = DB[:gm_grouptype].where(name: type.to_s).first![:id]
      DB[:gm_group].insert(group_id: @id, type_id: type_id, context: context.to_s, description: description.to_s)
    end

    def deregister
      DB[:gm_group].where(group_id: @id).delete
    end
  end
end