示例#1
0
        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
        }