private void BundleCommitting(HgBundleCommittedEventArgs args) { log.Info("handling BundleCommitting"); var acl = new HgAclReader().ReadAcl(hgRepository.Rc); if(acl == null) { log.Info("no acl defined for repository at '{0}'", hgRepository.FullPath); return; } // if if(!acl.Sources.Contains("serve")) { log.Info("[acl].sources does not have 'serve'"); return; } // if // // Checking in order: // - acl.deny.branches // - acl.allow.branches // - acl.deny // - acl.allow var principal = NormalizeHgPrincipal(hgPrincipalProvider.Invoke()); log.Info("verifying access for '{0}' ('{1}')", principal.Name, string.Join("', '", principal.Groups)); var denyBranches = BuildBranchMatch(principal, "acl.deny.branches", acl.DenyBranches); var allowBranches = BuildBranchMatch(principal, "acl.allow.branches", acl.AllowBranches); var deny = BuildPathMatch(principal, "acl.deny", acl.Deny); var allow = BuildPathMatch(principal, "acl.allow", acl.Allow); foreach(var changeset in args.Changesets) { log.Info("verifying access in changeset {0}", changeset.Metadata.NodeID.Short); var branch = changeset.Branch.Name; if(denyBranches != null && denyBranches(branch)) throw new HgSecurityException("User '{0}' is denied on branch '{1}' (changeset {2})".FormatWith( principal.Name, branch, changeset.Metadata.NodeID.Short)); if(allowBranches != null && !allowBranches(branch)) throw new HgSecurityException("User '{0}' is not allowed on branch '{1}' (changeset {2})".FormatWith( principal.Name, branch, changeset.Metadata.NodeID.Short)); foreach(var file in changeset.Files) { if(deny != null && deny(new HgPath(file))) throw new HgSecurityException("User '{0}' is denied on '{1}' (changeset {2})".FormatWith( principal.Name, file, changeset.Metadata.NodeID.Short)); if(allow != null && !allow(new HgPath(file))) throw new HgSecurityException("User '{0}' is not allowed on '{1}' (changeset {2})".FormatWith( principal.Name, file, changeset.Metadata.NodeID.Short)); } // foreach log.Info("access granted in changeset {0}", changeset.Metadata.NodeID.Short); } // foreach }
public HgCommitStats Commit(HgBundle hgBundle) { log.Info("committing bundle"); using(AcquireLock()) { var hgJournal = new HgJournal(Store); var hgTransaction = new HgTransaction(Store, hgJournal); var tip = Changelog.Tip; try { // // Adding changesets log.Info("committing changesets"); hgTransaction.Enlist(Changelog); int changesets; var revisions = CommitChangelog(tip, hgBundle.Changelog, Changelog.Revlog, out changesets); // // Adding manifests log.Info("committing manifests"); hgTransaction.Enlist(Manifest); var manifests = 0; Commit(revisions, hgBundle.Manifest, Manifest.Revlog, ref manifests); // // Adding file changes log.Info("committing files"); var changedFiles = 0; var changes = 0; foreach(var file in hgBundle.Files) { changedFiles++; log.Debug("committing '{0}'", file.Path.FullPath); var filelog = Store.GetFilelog(file.Path) ?? Store.CreateFilelog(file.Path); hgTransaction.Enlist(filelog); var hgBundleGroup = file.File; Commit(revisions, hgBundleGroup, filelog.Revlog, ref changes); } // foreach if(BundleCommitting != null) { var args = new HgBundleCommittedEventArgs(revisions.Keys.Select(k => Changelog[k])); BundleCommitting(args); } // if hgTransaction.Commit(); // // We need to force changelog re-read since after CommitChangelog() the changelog is // being read off a temp file. changelog = null; branchManager.RefreshBranchmap(tip == null ? 0 : tip.Metadata.Revision, Changelog.Tip.Metadata); if(BundleCommitted != null) { var args = new HgBundleCommittedEventArgs(revisions.Keys.Select(k => Changelog[k])); BundleCommitted(args); } // if return new HgCommitStats(changesets, manifests, changes, changedFiles); } // try catch(Exception e) { log.ErrorException("could not commit bundle", e); hgTransaction.Rollback(); // // Reset changelog and manifest so that they'll be reread changelog = null; manifest = null; throw; } // catch } // using }