배경:
스포츠 클럽을 위한 멀티 테넌트 관리 패널을 개발 및 유지보수하고 있습니다.
셀프 호스팅한 Discourse 포럼은 해당 클럽 회원들에게만 공개되어 있습니다. 이제 일반 대중에게도 공개하고 싶습니다. 제 SSO 통합은 로그인 시 데이터베이스에서 사용자의 전체 이름을 가져와 Discourse 사용자에게 자동으로 할당합니다.
문제:
현재 포럼을 공개할 수 없는 이유는 사용자의 전체 이름은 같은 클럽의 사용자에게만 표시되어야 하기 때문입니다.
Ruby 개발자로서의 경험은 전무합니다 (JS 개발자입니다) 하지만 지금까지 이 코드 부분을 파악했습니다:
# plugin.rb
after_initialize {
require_dependency 'basic_user_serializer'
require_dependency 'current_user'
class ::BasicUserSerializer
attributes :name
def name
# 클럽 소속을 나타내는 고정된 그룹 이름 세트
clubGroups = Array['foo', 'bar', 'baz']
# 파악하지 못한 부분:
# 현재 로그인된 사용자의 `clubGroups` 중 하나를 공유하는 경우에만 사용자 이름을 표시해야 합니다.
# 예: 'bar' 그룹에 속한 사용자로 로그인되어 있다고 하면, 이는 Bar 클럽에 속한다는 의미입니다. 'bar' 그룹에 속한 사용자들의 이름만 볼 수 있어야 합니다.
???
end
end
}
다음 사항들을 파악하지 못했습니다:
현재 사용자의 그룹을 가져오는 방법
대상 사용자의 그룹을 가져오는 방법
위 정보를 얻으면 두 배열을 clubGroups와 비교하여 사용자 이름을 표시할지 말지 결정할 수 있을 것입니다.
해당 플러그인의 코드를 살펴보는 것이 도움이 될 수 있습니다. 이 플러그인은 같은 그룹에 속한 사용자에게 아바타 플레어를 추가하여 서로를 그룹 멤버로 인식할 수 있게 해줍니다. 이는 다른 기능이지만, 게시한 사용자가 현재 사용자와 같은 그룹에 속하는지 확인하는 코드를 포함하고 있습니다.
완벽하지는 않고 최적화도 되지 않았지만 동작합니다! 그리고 그것이 가장 중요한 첫 번째 단계죠
after_initialize {
require_dependency 'basic_user_serializer'
class ::BasicUserSerializer
attributes :name
def name
if user_is_current_user
return _old_name_method
else
# TODO: 이 목록을 편집 가능하도록 만들기
clubGroups = Array['...']
if scope.user
ownGroups = GroupUser.where(user_id: scope.user.id)
.map { |gu| gu.group_id }
.map { |group_id| Group.find_by(id: group_id) }
.filter { |group| clubGroups.include? group.name }
if ownGroups.length > 0
ownGroupsIds = ownGroups.map { |g| g.id }
if GroupUser.exists?(user_id: user.id, group_id: ownGroupsIds)
return _old_name_method
end
end
end
end
return ''
end
private def _old_name_method
return Hash === user ? user[:name] : user.try(:name)
end
end
}