2
1
0

以下のリンクのスクリプトランナーの設定で、「プロジェクトロール」によって選択できる課題タイプを変えることができます。そのイメージで所属するロールに応じて、あるセキュリティレベルを表示させないという設定をしたいと思っていますので、この点についてアイデア・参考になるサイト、webページなどがあればご教示いただけますと幸いです。

https://library.adaptavist.com/entity/restrict-issue-types


■設定のイメージ

・あるプロジェクトを「テストPJ」とする

・プロジェクトに関わるユーザー
社内プロジェクトメンバー
A社(お客様)
B社(協力会社)

・ロール
社内ユーザー
社外ユーザー

・セキュリティレベル
社内のみ閲覧可能
A社+社内ユーザーのみ閲覧可能
B社+社内ユーザーのみ閲覧可能
プロジェクト全体への共有


以上の状況で、セキュリティレベルフィールドに以下のような挙動をさせたいです。

・社内ユーザーが選択可能なセキュリティレベル(選べるレベルの制限はなし)
社内のみ閲覧可能
A社+社内ユーザーのみ閲覧可能
B社+社内ユーザーのみ閲覧可能
プロジェクト全体への共有

・社外ユーザーが選択可能なセキュリティレベル
例:A社ユーザーの場合
A社+社内ユーザーのみ閲覧可能

例:B社ユーザーの場合
B社+社内ユーザーのみ閲覧可能

社内ユーザーの権限で「プロジェクト全体への共有」は許可する。
しかし、社外ユーザーには「プロジェクト全体への共有」という形で全体への情報共有はさせないようにしたい。

    Commentコメントを追加...

    1 回答

    1.  
      2
      1
      0

      セキュリティレベルであれば、ユーザーが含まれないセキュリティレベルは設定できないので、
      オプションを変更しなくてもいいのでは...?
      と思ったのですが、
      広く公開させることを特定のユーザーにはさせたくないということですね...!!

      ロールが「社内ロール」か「社外ロール」とのことで、A 社か B 社の判定をどのようにするかが考慮できておりませんが、
      「社外ロール」のユーザーの場合には「プロジェクト全体への共有」オプションを表示させないということは以下でできたように思えますがいかがでしょうか。

      import com.atlassian.jira.component.ComponentAccessor;
      import java.util.HashMap;
      import com.atlassian.jira.security.roles.ProjectRoleManager;
      
      def EXTERNAL_ROLE_NAME = "社外ユーザー";
      def EXCLUDE_SECURITY_NAME = "プロジェクト全体への共有";
      
      def issueSecurityLevelManager = ComponentAccessor.getIssueSecurityLevelManager();
      def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager);
      def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
      def securityLevelField = getFieldById("security");
      
      def remoteUsersRoles = projectRoleManager.getProjectRoles(user, issueContext.projectObject)*.name
      
      if (EXTERNAL_ROLE_NAME in remoteUsersRoles) {
          def projectObj = underlyingIssue?.getProjectObject();
          if (!projectObj) {  
            projectObj = getIssueContext().getProjectObject();
          }
      
          def securityLevels = issueSecurityLevelManager.getUsersSecurityLevels(projectObj, user);
          def map = new HashMap<Long, String>();
          map.put(-1L, "None");
          for (def securityLevel : securityLevels) {
              if (!securityLevel.getName().equals(EXCLUDE_SECURITY_NAME)) {
                  map.put(securityLevel.getId(), securityLevel.getName());
              }
          }
          securityLevelField.setFieldOptions(map);
      }

      EXTERNAL_ROLE_NAME には、社外ユーザーが属しているロールの名前を、
      EXCLUDE_SECURITY_NAME には、社外ユーザーには表示させたくないセキュリティレベルの名前を指定してください。

      1. gussan

        Shuzaburo Dobaさん
        ご回答いただきありがとうございます!

        広く公開させることを特定のユーザーにはさせたくないということですね...!!

        まさにおっしゃる通りです。要領を得ないご説明で申し訳ございません。ご提示くださったスクリプトを試し次第、またお返事させていただきます。以上簡単にですが、いったんのお返事になります。

      2. gussan

        Shuzaburo Dobaさん
        設定を試してみました。想定している挙動になっていそうです!
        コードの中身の理解が追い付いていないので、その点含めてまた明日にでも見直してみます。

        今回の設定は緊急に必要で、設定期限が差し迫っていたので大変助かりました。
        それにしても、コードをみればみるほど、今の私にはちょっと思いつきそうにないです。。勉強しようと思います。

        また、Shuzaburo Dobaさんには実は以前にもお助けいただいたことがあり、前回に引き続き本当に感謝です。ありがとうございました!

        次は社内のJira環境への実装を目指したいと思います。

      3. gussan

        一段落つき次第「回答を受け入れる」ボタンを押したいと思います。

      4. Shuzaburo Doba

        gussan

        大変恐れ入ります。
        お役に立てそうであればうれしいです!

        説明が不親切ですみませんでした。

        上記コードではロールとセキュリティレベルを "名前” で判定しましたが、
        場合によっては必ず一意である "ID" を使用した判定の方がよろしいかもしれません。

        その場合は、以下のようなイメージを Behaviours の Initialiser に設定すれば動いたのではないかと思います。

        import com.atlassian.jira.component.ComponentAccessor;
        import java.util.HashMap;
        import com.atlassian.jira.security.roles.ProjectRoleManager;
        
        // セキュリティレベルを選択させたくなユーザーロールの ID
        def EXTERNAL_ROLE_ID = 10500L;
        // 非表示にしたいセキュリティレベルの ID
        def EXCLUDE_SECURITY_ID = 10602L;
        
        def issueSecurityLevelManager = ComponentAccessor.getIssueSecurityLevelManager();
        def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager);
        def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
        def securityLevelField = getFieldById("security");
        def project = issueContext.projectObject;
        
        // ユーザーが所属するロールの ID リストを取得する
        def remoteUsersRoles = projectRoleManager.getProjectRoles(user, project)*.id;
        
        // ユーザーのロール ID リストに EXTERNAL_ROLE_ID が含まれていれば EXCLUDE_SECURITY_ID のセキュリティレベルを非表示にする
        if (EXTERNAL_ROLE_ID in remoteUsersRoles) {
            // ユーザーが表示できるセキュリティレベルのリストを取得する
            def securityLevels = issueSecurityLevelManager.getUsersSecurityLevels(project, user);
            // 選択オプションを格納する Map
            def map = new HashMap<Long, String>();
            // 先頭に None のオプションを追加する
            map.put(-1L, "None");
            // ユーザーが選択できるセキュリティレベルから、EXCLUDE_SECURITY_ID のセキュリティレベルを取り除く
            for (def securityLevel : securityLevels) {
                // セキュリティレベルが EXCLUDE_SECURITY_ID のものでなければ map に格納
                if (!securityLevel.getId().equals(EXCLUDE_SECURITY_ID)) {
                    map.put(securityLevel.getId(), securityLevel.getName());
                }
            }
            // フィールドにオプション map を設定
            securityLevelField.setFieldOptions(map);
        }

        EXTERNAL_ROLE_ID には外部ユーザーが所属するロールの ID を、
        EXCLUDE_SECURITY_ID には、非表示にさせたいセキュリティレベルの ID を指定してください。

        ロールやセキュリティレベルの ID は、各項目を編集したりするときの URL から確認することができます。

      5. gussan

        Shuzaburo Doba

        追加の情報のご提示ありがとうございます!

        コードへのコメントの記載ありがとうございます。大変わかりやすくとてもありがたいです。
        >説明が不親切ですみませんでした。
        ⇒いえいえとんでもないです。ご提示くださり、ものすごく助かっています。

        確かにおっしゃるとおりIDを使用する方が良いかもしれません。
        ただ、運用していく上で、プロジェクトごとにセキュリティレベルスキームを分ける場合だと、プロジェクトを作成するたびに毎回IDを置き換えたスクリプトをかく必要がでてくるという点が気になりますね。

        ご提示くださった2つのコードをもとに、もうすこしどちらがよいか等、設定を検討してみたいと思います。

      6. Shuzaburo Doba

        gussan

        恐れ入ります。ありがとうございます!
        少しでも参考になっていましたらとてもうれしいです(スマイル)

      Commentコメントを追加...