Skip to content

Pre-commit hook to protect ref paths from non-FF updates or deletes #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2012

Conversation

plm
Copy link

@plm plm commented Feb 4, 2012

Group membership is used for authorization.

…eletes unless the user is a member of an authorized team

This script is derived from groovy/blockpush.groovy
@plm
Copy link
Author

plm commented Feb 5, 2012

I'll add some unit tests, with my plan to implement a test for each scenario as an authorized and a non-authorized user:

  • Fast forward commit.
  • Creation of a new branch.
  • Creation of a tag.
  • Deleting a branch.
  • Deleting a tag.
  • Non-FF commit with --force option.

Do you think it's worth externalizing the protected paths and team names? I could make them configuration options in gitblit.properties much like the current properties for email integration.

My current plan was to edit the script with my environment-specific values after initial installation, but this may not be desirable for most users.

@plm
Copy link
Author

plm commented Feb 5, 2012

I revised the initial implementation so commands can now be rejected with a specific result type (for example, DELETE commands are rejected with a REJECTED_NODELETE result).

I added the following unit tests:

  • Create a new branch (succeeds, no authz)
  • Create a new tag (succeeds, no authz)
  • Fast forward commit (succeeds, no authz)
  • Delete an unprotected branch (succeeds, no authz)
  • Delete a protected branch (fails, authz denied because mock user is not in "admin" group)
  • Delete a tag (fails, authz denied because mock user is not in "admin" group)

I did not implement the non-fast forward commit test, since I would need a mock ReceiveCommand which has the UPDATE_NONFASTFORWARD type (setType(Type) is package protected). I also didn't make changes to the mock user so I could simulate membership in the "admin" group.

@gitblit
Copy link
Collaborator

gitblit commented Feb 5, 2012

One goal of the groovy push hook mechanism was to provide gitolite-ish control. I implemented a dumb proof-of-concept, which is not distributed with Gitblit, to verify that I could block a push. There have been a couple requests for this type of control and there is an open issue (http://code.google.com/p/gitblit/issues/detail?id=36) for it. Your proposed contribution is heading that direction.

I definitely think that paths/permissions should be externalized if this is to be the most useful. However, I don't want to put that data in gitblit.properties. My thinking on this was to write a nice unit-testable Java class that would parse a permissions file - possibly reusing as much gitolite syntax as possible - for familiarity of those users wanting this power. Then write a groovy script which instantiated the permissions parser and checked each receive command against the parsed rules. The script would be fairly short with most of the brains in the parser class.

The name of the permissions file would be fixed - or maybe the extension would be fixed - so that the permission file(s) could be backed-up using the federation mechanism.

Interested in tackling that?

@plm
Copy link
Author

plm commented Feb 5, 2012

I am using Gitblit to manage corporate Git repositories, and having Gitolite-style granular access control would be highly desirable. However, I'm hacking Gitblit in my (limited) free time, so I am focused on targeted improvements that I can contribute back to Gitblit.

My "protect-refs" deployment plan is to modify the installed script to include the appropriate team name(s) in the authorized list, and then enumerate all possible protected refs for any managed repository. I can then apply this hook script to each repository and manage authorized group membership via the Gitblit UI.

For the general use case, hard-coding the group names and protected refs is undesirable as it means each Gitblit installation would require customization of the hook script before it is ready for use. Your approach definitely sounds like one which is more suitable for deeper integration into the core Gitblit code.

For my use case, the hook script approach gets me a reliable authorization solution for the next few months as my company ramps up Git usage.

I am very interested seeing issue #36 resolved, but from a practical perspective I don't want to officially sign up for implementing features and then not be able to dedicate the time required for completion.

@gitblit
Copy link
Collaborator

gitblit commented Feb 6, 2012

No problem. It will get done... eventually by someone. :) Once you have a script you are happy with I will merge it, but I may not distribute it until the rules/permissions can be externalized. I may use it as the starting point for issue 36.

@plm
Copy link
Author

plm commented Feb 7, 2012

I deployed the protect-refs script today with the few environment-specific modifications I mentioned and it is working well. Feel free to merge the script and tests when you're ready; they're "done" from my perspective.

@gitblit
Copy link
Collaborator

gitblit commented Feb 9, 2012

I'm not ignoring your pull request. I'm just sitting on it for a week or so to give your deployment some runtime to make sure you are happy with it.

@plm
Copy link
Author

plm commented Feb 9, 2012

So far I'm very happy with the hook script.

I've been able to verify authorization is required for rewinding canonical branches and tags.

gitblit added a commit that referenced this pull request Feb 16, 2012
Pre-commit hook to protect ref paths from non-FF updates or deletes
@gitblit gitblit merged commit 91780e2 into gitblit-org:master Feb 16, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants