]> source.dussan.org Git - gitblit.git/commitdiff
Return command-specific rejection result if authz check fails.
authorPhilip L. McMahon <philip.l.mcmahon@gmail.com>
Sun, 5 Feb 2012 06:01:35 +0000 (22:01 -0800)
committerPhilip L. McMahon <philip.l.mcmahon@gmail.com>
Sun, 5 Feb 2012 06:01:35 +0000 (22:01 -0800)
groovy/protect-refs.groovy

index 2df813417d3bf780d0cd07706aa920dbb52d96ba..065cf5d88031f1816420eca79a7dd2dda94eba7b 100644 (file)
-/*
- * Copyright 2011 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import com.gitblit.GitBlit
-import com.gitblit.models.RepositoryModel
-import com.gitblit.models.UserModel
-
-import org.eclipse.jgit.transport.ReceiveCommand
-import org.eclipse.jgit.transport.ReceiveCommand.Result
-import org.eclipse.jgit.transport.ReceiveCommand.Type
-import org.slf4j.Logger
-
-/**
- * Sample Gitblit Pre-Receive Hook: protect-refs
- * 
- * This script provides basic authorization for receive command types for a list
- * of known ref patterns. Command types and unmatched ref patterns will be
- * ignored, meaning this script has an "allow by default" policy.
- *
- * This script works best when a repository requires authentication on push, but
- * can be used to enforce fast-forward commits or prohibit ref deletion by
- * setting the authorizedTeams variable to an empty list.
- *
- * The Pre-Receive hook is executed after an incoming push has been parsed,
- * validated, and objects have been written but BEFORE the refs are updated.
- * This is the appropriate point to block a push for some reason.
- *
- * This script is only executed when pushing to *Gitblit*, not to other Git
- * tooling you may be using.
- * 
- * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties
- * or web.xml then it will be executed by any repository when it receives a
- * push.  If you choose to share your script then you may have to consider
- * tailoring control-flow based on repository access restrictions.
- * 
- * Scripts may also be specified per-repository in the repository settings page.
- * Shared scripts will be excluded from this list of available scripts.
- *
- * This script is dynamically reloaded and it is executed within it's own
- * exception handler so it will not crash another script nor crash Gitblit.
- * 
- * If you want this hook script to fail and abort all subsequent scripts in the
- * chain, "return false" at the appropriate failure points.
- *
- * Bound Variables:
- *  gitblit            Gitblit Server                  com.gitblit.GitBlit
- *  repository Gitblit Repository              com.gitblit.models.RepositoryModel
- *  user               Gitblit User                    com.gitblit.models.UserModel
- *  commands   JGit commands                   Collection<org.eclipse.jgit.transport.ReceiveCommand>
- *  url                        Base url for Gitblit    String
- *  logger             Logger instance                 org.slf4j.Logger
- *  
- */
-
-def protectedCmds = [ Type.UPDATE_NONFASTFORWARD, Type.DELETE ]
-def protectedRefs = [ "refs/heads/master", "refs/tags/.+" ]
-def authorizedTeams = [ "admins" ]
-def blocked = false
-
-for (ReceiveCommand command : commands) {
-       def updateType = command.type
-       def updatedRef = command.refName
-       
-       // find first regex which matches updated ref
-       def protectedRef = protectedRefs.find { updatedRef.matches ~it }
-       
-       // ...and check if command type requires authz check
-       if (protectedRef && updateType in protectedCmds) {
-       
-               // verify user is a member of any authorized team
-               def team = authorizedTeams.find { user.isTeamMember it }
-               if (team) {
-                       logger.info "authorized ${command} for ${team} member ${user.username}"
-               } else {
-                       command.setResult(Result.REJECTED_OTHER_REASON, "${user.username} cannot ${updateType} protected ref ${repository.name}:${updatedRef} (matched pattern ${protectedRef})")
-                       blocked = true
-               }
-       }
-}
-
-if (blocked) {
-       // return false to break the push hook chain
-       return false
-}
\ No newline at end of file
+/*\r
+ * Copyright 2012 Philip L. McMahon.\r
+ *\r
+ * Derived from blockpush.groovy, copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+import com.gitblit.GitBlit\r
+import com.gitblit.models.RepositoryModel\r
+import com.gitblit.models.UserModel\r
+\r
+import org.eclipse.jgit.transport.ReceiveCommand\r
+import org.eclipse.jgit.transport.ReceiveCommand.Result\r
+import org.slf4j.Logger\r
+\r
+/**\r
+ * Sample Gitblit Pre-Receive Hook: protect-refs\r
+ * \r
+ * This script provides basic authorization of receive command types for a list\r
+ * of known ref patterns. Command types and unmatched ref patterns will be\r
+ * ignored, meaning this script has an "allow by default" policy.\r
+ *\r
+ * This script works best when a repository requires authentication on push, but\r
+ * can be used to enforce fast-forward commits or prohibit ref deletion by\r
+ * setting the *authorizedTeams* variable to an empty list and adding a ".+"\r
+ * entry to the *protectedRefs* list.\r
+ *\r
+ * The Pre-Receive hook is executed after an incoming push has been parsed,\r
+ * validated, and objects have been written but BEFORE the refs are updated.\r
+ * This is the appropriate point to block a push for some reason.\r
+ *\r
+ * This script is only executed when pushing to *Gitblit*, not to other Git\r
+ * tooling you may be using.\r
+ * \r
+ * If this script is specified in *groovy.preReceiveScripts* of gitblit.properties\r
+ * or web.xml then it will be executed by any repository when it receives a\r
+ * push.  If you choose to share your script then you may have to consider\r
+ * tailoring control-flow based on repository access restrictions.\r
+ * \r
+ * Scripts may also be specified per-repository in the repository settings page.\r
+ * Shared scripts will be excluded from this list of available scripts.\r
+ *\r
+ * This script is dynamically reloaded and it is executed within it's own\r
+ * exception handler so it will not crash another script nor crash Gitblit.\r
+ * \r
+ * This script may reject one or more commands, but will never return false.\r
+ * Subsequent scripts, if any, will always be invoked.\r
+ *\r
+ * Bound Variables:\r
+ *  gitblit            Gitblit Server                  com.gitblit.GitBlit\r
+ *  repository Gitblit Repository              com.gitblit.models.RepositoryModel\r
+ *  user               Gitblit User                    com.gitblit.models.UserModel\r
+ *  commands   JGit commands                   Collection<org.eclipse.jgit.transport.ReceiveCommand>\r
+ *  url                        Base url for Gitblit    String\r
+ *  logger             Logger instance                 org.slf4j.Logger\r
+ *  \r
+ */\r
+\r
+// map of protected command types to returned results type\r
+// commands not included will skip authz check\r
+def protectedCmds = [\r
+       UPDATE_NONFASTFORWARD:  Result.REJECTED_NONFASTFORWARD,\r
+       DELETE:                                 Result.REJECTED_NODELETE\r
+]\r
+\r
+// list of regex patterns for protected refs\r
+def protectedRefs = [\r
+       "refs/heads/master",\r
+       "refs/tags/.+"\r
+]\r
+\r
+// teams which are authorized to perform protected commands on protected refs\r
+def authorizedTeams = [ "admins" ]\r
+\r
+for (ReceiveCommand command : commands) {\r
+       def updateType = command.type\r
+       def updatedRef = command.refName\r
+       \r
+       // find first regex which matches updated ref, if any\r
+       def refPattern = protectedRefs.find { updatedRef.matches ~it }\r
+       \r
+       // find rejection result for update type, if any\r
+       def result = protectedCmds[updateType.name()]\r
+       \r
+       // command requires authz if ref is protected and has a mapped rejection result\r
+       if (refPattern && result) {\r
+       \r
+               // verify user is a member of any authorized team\r
+               def team = authorizedTeams.find { user.isTeamMember it }\r
+               if (team) {\r
+                       // don't adjust command result\r
+                       logger.info "${user.username} authorized for ${updateType} of protected ref ${repository.name}:${updatedRef} (${command.oldId.name} -> ${command.newId.name})"\r
+               } else {\r
+                       // mark command result as rejected\r
+                       command.setResult(result, "${user.username} cannot ${updateType} protected ref ${repository.name}:${updatedRef} matching pattern ${refPattern}")\r
+               }\r
+       }\r
+}\r