]> source.dussan.org Git - gitblit.git/commitdiff
Centralized ticket editing permission controls
authorJames Moger <james.moger@gitblit.com>
Wed, 5 Mar 2014 17:26:14 +0000 (12:26 -0500)
committerJames Moger <james.moger@gitblit.com>
Wed, 5 Mar 2014 17:26:14 +0000 (12:26 -0500)
src/main/java/com/gitblit/models/UserModel.java
src/main/java/com/gitblit/wicket/pages/EditTicketPage.html
src/main/java/com/gitblit/wicket/pages/EditTicketPage.java
src/main/java/com/gitblit/wicket/pages/TicketPage.java

index fbf311a5bb086fdbd7cf907e32d2b9de76e4f5d8..fee9c172f15269984e406ba49c1458d9c9410817 100644 (file)
@@ -447,16 +447,23 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
        }\r
 \r
+       public boolean canEdit(TicketModel ticket, RepositoryModel repository) {\r
+                return isAuthenticated() &&\r
+                                (username.equals(ticket.createdBy)\r
+                                || username.equals(ticket.responsible)\r
+                                || canPush(repository));\r
+       }\r
+\r
        public boolean canReviewPatchset(RepositoryModel model) {\r
-               return isAuthenticated && canClone(model);\r
+               return isAuthenticated() && canClone(model);\r
        }\r
 \r
        public boolean canApprovePatchset(RepositoryModel model) {\r
-               return isAuthenticated && canPush(model);\r
+               return isAuthenticated() && canPush(model);\r
        }\r
 \r
        public boolean canVetoPatchset(RepositoryModel model) {\r
-               return isAuthenticated && canPush(model);\r
+               return isAuthenticated() && canPush(model);\r
        }\r
 \r
        /**\r
@@ -540,6 +547,10 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                return false;\r
        }\r
 \r
+       public boolean isAuthenticated() {\r
+               return !UserModel.ANONYMOUS.equals(this) && isAuthenticated;\r
+       }\r
+\r
        public boolean isTeamMember(String teamname) {\r
                for (TeamModel team : teams) {\r
                        if (team.name.equalsIgnoreCase(teamname)) {\r
index b3c102d984d5a2212ef695d03f80784e0c566f57..b5fe0ae539b1239456fbaa877ec89a170b8fbc5c 100644 (file)
@@ -38,8 +38,7 @@
                                </div>\r
                                </div>\r
                        </td></tr>\r
-                       <tr><th><wicket:message key="gb.type"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="type"></select></td></tr>\r
-                       <tr><th><wicket:message key="gb.status"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="status"></select></td></tr>\r
+                       <tr wicket:id="status"></tr>\r
                        <tr wicket:id="responsible"></tr>\r
                        <tr wicket:id="milestone"></tr>\r
                        <tr wicket:id="mergeto"></tr>\r
 </div>\r
 </body>\r
 \r
+<wicket:fragment wicket:id="statusFragment">\r
+       <tr><th><wicket:message key="gb.status"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="status"></select></td></tr>\r
+</wicket:fragment>\r
+\r
 <wicket:fragment wicket:id="responsibleFragment">\r
        <th><wicket:message key="gb.responsible"></wicket:message></th><td class="edit"><select class="input-large" wicket:id="responsible"></select></td>\r
 </wicket:fragment>\r
index ac7ff97ee82731fb790e37841366f34962a98329..5fa31975f16b815d3b8707cf1d8aa33fcb01fc27 100644 (file)
@@ -88,11 +88,6 @@ public class EditTicketPage extends RepositoryPage {
                        currentUser = UserModel.ANONYMOUS;\r
                }\r
 \r
-               if (!currentUser.isAuthenticated || !app().tickets().isAcceptingTicketUpdates(getRepositoryModel())) {\r
-                       // tickets prohibited\r
-                       setResponsePage(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));\r
-               }\r
-\r
                long ticketId = 0L;\r
                try {\r
                        String h = WicketUtils.getObject(params);\r
@@ -102,8 +97,10 @@ public class EditTicketPage extends RepositoryPage {
                }\r
 \r
                TicketModel ticket = app().tickets().getTicket(getRepositoryModel(), ticketId);\r
-               if (ticket == null) {\r
-                       setResponsePage(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));\r
+               if (ticket == null\r
+                               || !currentUser.canEdit(ticket, getRepositoryModel())\r
+                               || !app().tickets().isAcceptingTicketUpdates(getRepositoryModel())) {\r
+                       setResponsePage(TicketsPage.class, WicketUtils.newObjectParameter(repositoryName, "" + ticketId));\r
                }\r
 \r
                typeModel = Model.of(ticket.type);\r
@@ -223,18 +220,6 @@ public class EditTicketPage extends RepositoryPage {
                }\r
                form.add(new DropDownChoice<TicketModel.Type>("type", typeModel, typeChoices));\r
 \r
-               List<Status> statusChoices;\r
-               if (ticket.isClosed()) {\r
-                       statusChoices = Arrays.asList(ticket.status, Status.Open);\r
-               } else if (ticket.isProposal()) {\r
-                       statusChoices = Arrays.asList(TicketModel.Status.proposalWorkflow);\r
-               } else if (ticket.isBug()) {\r
-                       statusChoices = Arrays.asList(TicketModel.Status.bugWorkflow);\r
-               } else {\r
-                       statusChoices = Arrays.asList(TicketModel.Status.requestWorkflow);\r
-               }\r
-               form.add(new DropDownChoice<TicketModel.Status>("status", statusModel, statusChoices));\r
-\r
                form.add(new TextField<String>("title", titleModel));\r
                form.add(new TextField<String>("topic", topicModel));\r
 \r
@@ -249,78 +234,85 @@ public class EditTicketPage extends RepositoryPage {
                descriptionEditor.setText(ticket.body);\r
                form.add(descriptionEditor);\r
 \r
-               if (currentUser != null && currentUser.isAuthenticated && currentUser.canPush(getRepositoryModel())) {\r
-                       // responsible\r
-                       Set<String> userlist = new TreeSet<String>(ticket.getParticipants());\r
+               // status\r
+               List<Status> statusChoices;\r
+               if (ticket.isClosed()) {\r
+                       statusChoices = Arrays.asList(ticket.status, Status.Open);\r
+               } else if (ticket.isProposal()) {\r
+                       statusChoices = Arrays.asList(TicketModel.Status.proposalWorkflow);\r
+               } else if (ticket.isBug()) {\r
+                       statusChoices = Arrays.asList(TicketModel.Status.bugWorkflow);\r
+               } else {\r
+                       statusChoices = Arrays.asList(TicketModel.Status.requestWorkflow);\r
+               }\r
+               Fragment status = new Fragment("status", "statusFragment", this);\r
+               status.add(new DropDownChoice<TicketModel.Status>("status", statusModel, statusChoices));\r
+               form.add(status);\r
 \r
-                       for (RegistrantAccessPermission rp : app().repositories().getUserAccessPermissions(getRepositoryModel())) {\r
-                               if (rp.permission.atLeast(AccessPermission.PUSH) && !rp.isTeam()) {\r
-                                       userlist.add(rp.registrant);\r
-                               }\r
-                       }\r
+               // responsible\r
+               Set<String> userlist = new TreeSet<String>(ticket.getParticipants());\r
 \r
-                       List<TicketResponsible> responsibles = new ArrayList<TicketResponsible>();\r
-                       for (String username : userlist) {\r
-                               UserModel user = app().users().getUserModel(username);\r
-                               if (user != null) {\r
-                                       TicketResponsible responsible = new TicketResponsible(user);\r
-                                       responsibles.add(responsible);\r
-                                       if (user.username.equals(ticket.responsible)) {\r
-                                               responsibleModel.setObject(responsible);\r
-                                       }\r
-                               }\r
+               for (RegistrantAccessPermission rp : app().repositories().getUserAccessPermissions(getRepositoryModel())) {\r
+                       if (rp.permission.atLeast(AccessPermission.PUSH) && !rp.isTeam()) {\r
+                               userlist.add(rp.registrant);\r
                        }\r
-                       Collections.sort(responsibles);\r
-                       responsibles.add(new TicketResponsible(NIL, "", ""));\r
-                       Fragment responsible = new Fragment("responsible", "responsibleFragment", this);\r
-                       responsible.add(new DropDownChoice<TicketResponsible>("responsible", responsibleModel, responsibles));\r
-                       form.add(responsible.setVisible(!responsibles.isEmpty()));\r
-\r
-                       // milestone\r
-                       List<TicketMilestone> milestones = app().tickets().getMilestones(getRepositoryModel(), Status.Open);\r
-                       for (TicketMilestone milestone : milestones) {\r
-                               if (milestone.name.equals(ticket.milestone)) {\r
-                                       milestoneModel.setObject(milestone);\r
-                                       break;\r
+               }\r
+\r
+               List<TicketResponsible> responsibles = new ArrayList<TicketResponsible>();\r
+               for (String username : userlist) {\r
+                       UserModel user = app().users().getUserModel(username);\r
+                       if (user != null) {\r
+                               TicketResponsible responsible = new TicketResponsible(user);\r
+                               responsibles.add(responsible);\r
+                               if (user.username.equals(ticket.responsible)) {\r
+                                       responsibleModel.setObject(responsible);\r
                                }\r
                        }\r
-                       if (milestoneModel.getObject() == null && !StringUtils.isEmpty(ticket.milestone)) {\r
-                               // ensure that this unrecognized milestone is listed\r
-                               // so that we get the <nil> selection.\r
-                               TicketMilestone tms = new TicketMilestone(ticket.milestone);\r
-                               milestones.add(tms);\r
-                               milestoneModel.setObject(tms);\r
-                       }\r
-                       if (!milestones.isEmpty()) {\r
-                               milestones.add(new TicketMilestone(NIL));\r
+               }\r
+               Collections.sort(responsibles);\r
+               responsibles.add(new TicketResponsible(NIL, "", ""));\r
+               Fragment responsible = new Fragment("responsible", "responsibleFragment", this);\r
+               responsible.add(new DropDownChoice<TicketResponsible>("responsible", responsibleModel, responsibles));\r
+               form.add(responsible.setVisible(!responsibles.isEmpty()));\r
+\r
+               // milestone\r
+               List<TicketMilestone> milestones = app().tickets().getMilestones(getRepositoryModel(), Status.Open);\r
+               for (TicketMilestone milestone : milestones) {\r
+                       if (milestone.name.equals(ticket.milestone)) {\r
+                               milestoneModel.setObject(milestone);\r
+                               break;\r
                        }\r
+               }\r
+               if (milestoneModel.getObject() == null && !StringUtils.isEmpty(ticket.milestone)) {\r
+                       // ensure that this unrecognized milestone is listed\r
+                       // so that we get the <nil> selection.\r
+                       TicketMilestone tms = new TicketMilestone(ticket.milestone);\r
+                       milestones.add(tms);\r
+                       milestoneModel.setObject(tms);\r
+               }\r
+               if (!milestones.isEmpty()) {\r
+                       milestones.add(new TicketMilestone(NIL));\r
+               }\r
 \r
-                       Fragment milestone = new Fragment("milestone", "milestoneFragment", this);\r
+               Fragment milestone = new Fragment("milestone", "milestoneFragment", this);\r
 \r
-                       milestone.add(new DropDownChoice<TicketMilestone>("milestone", milestoneModel, milestones));\r
-                       form.add(milestone.setVisible(!milestones.isEmpty()));\r
+               milestone.add(new DropDownChoice<TicketMilestone>("milestone", milestoneModel, milestones));\r
+               form.add(milestone.setVisible(!milestones.isEmpty()));\r
 \r
-                       // mergeTo (integration branch)\r
-                       List<String> branches = new ArrayList<String>();\r
-                       for (String branch : getRepositoryModel().getLocalBranches()) {\r
-                               // exclude ticket branches\r
-                               if (!branch.startsWith(Constants.R_TICKET)) {\r
-                                       branches.add(Repository.shortenRefName(branch));\r
-                               }\r
+               // mergeTo (integration branch)\r
+               List<String> branches = new ArrayList<String>();\r
+               for (String branch : getRepositoryModel().getLocalBranches()) {\r
+                       // exclude ticket branches\r
+                       if (!branch.startsWith(Constants.R_TICKET)) {\r
+                               branches.add(Repository.shortenRefName(branch));\r
                        }\r
-                       branches.remove(Repository.shortenRefName(getRepositoryModel().HEAD));\r
-                       branches.add(0, Repository.shortenRefName(getRepositoryModel().HEAD));\r
-\r
-                       Fragment mergeto = new Fragment("mergeto", "mergeToFragment", this);\r
-                       mergeto.add(new DropDownChoice<String>("mergeto", mergeToModel, branches));\r
-                       form.add(mergeto.setVisible(!branches.isEmpty()));\r
-\r
-               } else {\r
-                       // user does not have permission to assign milestone or responsible\r
-                       form.add(new Label("responsible").setVisible(false));\r
-                       form.add(new Label("milestone").setVisible(false));\r
-                       form.add(new Label("mergeto").setVisible(false));\r
                }\r
+               branches.remove(Repository.shortenRefName(getRepositoryModel().HEAD));\r
+               branches.add(0, Repository.shortenRefName(getRepositoryModel().HEAD));\r
+\r
+               Fragment mergeto = new Fragment("mergeto", "mergeToFragment", this);\r
+               mergeto.add(new DropDownChoice<String>("mergeto", mergeToModel, branches));\r
+               form.add(mergeto.setVisible(!branches.isEmpty()));\r
 \r
                form.add(new Button("update"));\r
                Button cancel = new Button("cancel") {\r
index 3f92eaa061586eadfed07780bdaba7ac7c4d53a1..5e0e6820409c9c80ca64d8471dccd9ca82b2f432 100644 (file)
@@ -115,7 +115,6 @@ public class TicketPage extends TicketBasePage {
                super(params);\r
 \r
                final UserModel user = GitBlitWebSession.get().getUser() == null ? UserModel.ANONYMOUS : GitBlitWebSession.get().getUser();\r
-               final boolean isAuthenticated = !UserModel.ANONYMOUS.equals(user) && user.isAuthenticated;\r
                final RepositoryModel repository = getRepositoryModel();\r
                final String id = WicketUtils.getObject(params);\r
                long ticketId = Long.parseLong(id);\r
@@ -327,7 +326,7 @@ public class TicketPage extends TicketBasePage {
                /*\r
                 * UPDATE FORM (DISCUSSION TAB)\r
                 */\r
-               if (isAuthenticated && app().tickets().isAcceptingTicketUpdates(repository)) {\r
+               if (user.canEdit(ticket, repository) && app().tickets().isAcceptingTicketUpdates(repository)) {\r
                        if (ticket.isOpen()) {\r
                                /*\r
                                 * OPEN TICKET\r