clear-code / redmine_full_text_search

Full text search for Redmine
MIT License
63 stars 24 forks source link

Improve search functionality #29

Closed okkez closed 7 years ago

okkez commented 7 years ago

権限まわりをGroonga側に寄せる方法がよくわからない。


ログイン必須かどうかは関係なし。

326b032 までだと、Groonga側に作るテーブルはsearcher_recordsだけ。

Redmine本体側だと、projectにmemberがいてmemberにroleが設定されている。

project <- member <- role (permissions)
                └─ user(group)

Groonga側のテーブルが searcher_records 1つだけだと、権限まわりの情報を表現できない。

権限のカスタマイズをしていなければ、searcher_records.project_id はあるので公開プジェクトのidと User.current.projects.map(&:id) を渡せば検索できる。

okkez commented 7 years ago

@kou 何かアイデアがあれば、教えてください。。。

kou commented 7 years ago

Project.allowed_to_conditionIssue.visible_conditionを見ると複雑なのでこれをGroongaレベルでも再実装するのは(バグって見えちゃいけないものが見えるのが怖いので)避けたいですね。。。

別途SQLを3回実行することになってしまいますが、こんなんでいけないですかねぇ。SQLはクエリーキャッシュが効く気がするのであんまり遅くならないかも。

--filter \
  '(in_values(project_id, #{User.current.visible_project_ids.join(", ")}) &! \
    in_values(original_type, "Issue", "Journal") || \
   (original_type == "Issue" && \
    in_values(original_id, #{Issue.visible.pluck(:id).join(", ")})) || \
   (original_type == "Journal" && \
    in_values(original_id, #{Journal.visible.pluck(:id).join(", ")}))'
okkez commented 7 years ago

なるほど filter でがんばるんですね!あとで試してみます。

kou commented 7 years ago

IssueJournalのvisibleなIDのリストは長くなりそうなので、invisibleなIDのリストにできた方がよさそうなんですが、そうするとそのロジックをプラグイン側でメンテナンスしないといけなくなるのがアレなんですよねぇ。

SQLでNOT visibleなconditionみたいな条件が効率よく動くならそっちの方がいいかもしれません。(全体からのNOTは効率よくなりにくいので難しい気がしますが。。。)

okkez commented 7 years ago

original_idのリストが長くなりそうな気がしたのでfiterで↓のようにしようと考えています。 数が多いので、一つだけ例示します。これだと権限の数だけSQLを発行すればいいです。 プロジェクトの数はそんなに多くないはずなので、最初はこれでいいかなぁと思います。

(original_type == "Issue" && is_private == false && in_values(project_id, #{Project.allowed_to(user, :view_issues).pluck(:id).join(",")})
kou commented 7 years ago

プライベートなやissue/journalは全部対象外にするってことですね。 最初のステップとしては妥当だと思います。

okkez commented 7 years ago

:memo:

okkez commented 7 years ago

:memo: 残作業

okkez commented 7 years ago

以上について動作を確認した。