Ejemplo n.º 1
0
        public async Task<ActionResult> CreateBlob(Errorable<MaybeTreeBlobPath> epath, Errorable<StageName> estage)
        {
            Debug.Assert(epath != null);
            if (epath.HasErrors) return ErrorJson(epath);
            if (estage != null && estage.HasErrors) return ErrorJson(estage);

            PersistingBlob pbl = new PersistingBlob(Request.InputStream);

            // Persist the blob from the input stream:
            var eblob = await cms.blrepo.PersistBlob(pbl);
            if (eblob.HasErrors) return ErrorJson(eblob);
            var blob = eblob.Value;

            // Now update the given root TreeID:
            var path = epath.Value;

            // Persist the new blob's effect on the Tree:
            var eptr = await cms.trrepo.PersistTreeNodesByBlobPaths(path.RootTreeID, new CanonicalBlobIDPath[] { new CanonicalBlobIDPath(path.Path, blob.ID) });
            if (eptr.HasErrors) return ErrorJson(eptr);

            TreeID newRootTreeID = eptr.Value.RootID;

            // optional 5) update stage with new root TreeID
            if (estage != null)
            {
                var epst = await cms.strepo.PersistStage(new Stage.Builder(estage.Value, newRootTreeID));
                if (epst.HasErrors) return ErrorJson(epst);
            }

            // Return the new information:
            return Json(new { blobid = blob.ID.ToString(), treeid = newRootTreeID.ToString() });
        }
Ejemplo n.º 2
0
        public async Task<ActionResult> GetRefByName(Errorable<RefName> erefName)
        {
            if (erefName.HasErrors) return ErrorJson(erefName);

            var erf = await cms.rfrepo.GetRefByName(erefName.Value);
            if (erf.HasErrors) return ErrorJson(erf);

            Ref rf = erf.Value;
            return Json(new { @ref = rf.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 3
0
        public async Task<ActionResult> GetCommitByTagName(Errorable<TagName> etagName)
        {
            if (etagName.HasErrors) return ErrorJson(etagName);

            var ecm = await cms.cmrepo.GetCommitByTagName(etagName.Value);
            if (ecm.HasErrors) return ErrorJson(ecm);

            var cm = ecm.Value;

            return Json(new { tag = cm.Item1.ToJSON(), commit = cm.Item2.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 4
0
        public async Task<ActionResult> GetTagByName(Errorable<TagName> etagName)
        {
            if (etagName.HasErrors) return ErrorJson(etagName);

            var etg = await cms.tgrepo.GetTagByName(etagName.Value);
            if (etg.HasErrors) return Json(new { errors = etg.Errors.ToJSON() }, JsonRequestBehavior.AllowGet);

            Tag tg = etg.Value;
            Debug.Assert(tg != null);

            return Json(new { tag = tg.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 5
0
        public async Task<ActionResult> GetBlobByPath(Errorable<TreeBlobPath> epath)
        {
            if (epath.HasErrors) return ErrorJson(epath);

            var eblob = await cms.tpsbrepo.GetBlobByTreePath(epath.Value);
            if (eblob.HasErrors) return ErrorJson(eblob);

            TreePathStreamedBlob blob = eblob.Value;
            Debug.Assert(blob != null);

            return new StreamedBlobResult(blob.StreamedBlob);
        }
Ejemplo n.º 6
0
        public async Task<ActionResult> GetBlob(Errorable<BlobID.Partial> epid)
        {
            if (epid.HasErrors) return ErrorJson(epid);

            var eid = await cms.blrepo.ResolvePartialID(epid.Value);
            if (eid.HasErrors) return ErrorJson(eid);

            var eblob = await cms.blrepo.GetBlob(eid.Value);
            if (eblob.HasErrors) return ErrorJson(eblob);

            return new StreamedBlobResult(eblob.Value);
        }
Ejemplo n.º 7
0
        public async Task<ActionResult> GetCommitByID(Errorable<CommitID.Partial> epid)
        {
            if (epid.HasErrors) return ErrorJson(epid);

            var eid = await cms.cmrepo.ResolvePartialID(epid.Value);
            if (eid.HasErrors) return ErrorJson(eid);

            var ecm = await cms.cmrepo.GetCommit(eid.Value);
            if (ecm.HasErrors) return ErrorJson(ecm);

            Commit cm = ecm.Value;

            return Json(new { commit = cm.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 8
0
        public async Task<ActionResult> GetTagByID(Errorable<TagID.Partial> epid)
        {
            if (epid.HasErrors) return ErrorJson(epid);

            var eid = await cms.tgrepo.ResolvePartialID(epid.Value);
            if (eid.HasErrors) return ErrorJson(eid);

            var etg = await cms.tgrepo.GetTag(eid.Value);
            if (etg.HasErrors) return ErrorJson(etg);

            Tag tg = etg.Value;
            Debug.Assert(tg != null);

            return Json(new { tag = tg.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
        public async Task<Errorable<TreePathStreamedBlob>[]> GetBlobsByTreePaths(params TreeBlobPath[] treePaths)
        {
#if false
            var blobs =
                from tp in treePaths
                let tr = await trrepo.GetTreeIDByPath(new TreeTreePath(tp.RootTreeID, tp.Path.Tree))
            // await operator cannot currently be used in query expressions.
#else
            // Estimated size:
            var blobs = new Errorable<TreePathStreamedBlob>[treePaths.Length];
            
            for (int i = 0; i < treePaths.Length; ++i)
            {
                var tp = treePaths[i];

                var etrm = await trrepo.GetTreeIDByPath(new TreeTreePath(tp.RootTreeID, tp.Path.Tree)).ConfigureAwait(continueOnCapturedContext: false);
                if (etrm.HasErrors) blobs[i] = etrm.Errors;

                var trm = etrm.Value;
                if (!trm.TreeID.HasValue)
                {
                    blobs[i] = null;
                    continue;
                }

                // Get the tree:
                var etr = await trrepo.GetTree(trm.TreeID.Value).ConfigureAwait(continueOnCapturedContext: false);
                if (etr.HasErrors) blobs[i] = etr.Errors;

                TreeNode tr = etr.Value;

                // Get the blob out of this tree:
                // TODO: standardize name comparison semantics:
                var trbl = tr.Blobs.SingleOrDefault(x => x.Name == tp.Path.Name);
                if (trbl == null)
                {
                    blobs[i] = null;
                    continue;
                }
                
                // Finally return the streamed blob:
                // TODO: unknown length of blob; is it a problem?
                blobs[i] = new TreePathStreamedBlob(tp, new StreamedBlob(blrepo, trbl.BlobID));
            }

            return blobs;
#endif
        }
Ejemplo n.º 10
0
            private static Errorable <LPU> ResolveUnit(
                Func <string, Errorable <LPU> > argResolve,
                Func <string, List <LPU>, Errorable <LPU> > macroReinvResolve,
                LPU x)
            {
                Errorable <List <LPU> > resolveAcc(IEnumerable <LPU> args) =>
                Acc(args.Select(a => ResolveUnit(argResolve, macroReinvResolve, a)));

                Errorable <LPU> reloc(Errorable <ParseUnit> pu)
                {
                    return(pu.isValid ? new LPU(pu.value, x.location) : Errorable <LPU> .Fail(pu.errors));
                }

                return(x.unit.Match(
                           macroVar: argResolve,
                           macroReinv: macroReinvResolve,
                           paren: ns => reloc(resolveAcc(ns).Map(ParseUnit.Paren)),
                           words: ns => reloc(resolveAcc(ns).Map(ParseUnit.Words)),
                           nswords: ns => reloc(resolveAcc(ns).Map(ParseUnit.NoSpaceWords)),
                           postfix: ns => reloc(resolveAcc(ns).Map(ParseUnit.Postfix)),
                           deflt: () => Errorable <LPU> .OK(x)));
            }
Ejemplo n.º 11
0
        public async Task<ActionResult> RenderBlob(Errorable<TreeBlobPath> epath, DateTimeOffset? viewDate)
        {
            Debug.Assert(epath != null);
            if (epath.HasErrors) return ErrorJson(epath);
            var path = epath.Value;

            // Get the stream for the blob by its path:
            var eblob = await cms.tpsbrepo.GetBlobByTreePath(epath.Value);
            if (eblob.HasErrors) return ErrorJson(eblob);

            TreePathStreamedBlob blob = eblob.Value;
            if (blob == null) return new HttpNotFoundResult(String.Format("A blob could not be found off tree {0} by path '{0}'", path.RootTreeID.ToString(), path.Path.ToString()));

            // Render the blob:
            var renderer = new RenderingSystemContext(cms, viewDate);
            var ehtml = await renderer.Engine.RenderBlob(blob);
            if (ehtml.HasErrors) return ErrorJson(ehtml);

            var html = ehtml.Value;

            // HTML5 output:
            return Content((string)html, "application/xhtml+xml", Encoding.UTF8);
        }
Ejemplo n.º 12
0
        public Task <Errorable <BlobID>[]> DeleteBlobs(params BlobID[] ids)
        {
            if (ids == null)
            {
                throw new ArgumentNullException("ids");
            }
            if (ids.Length == 0)
            {
                return(Task.FromResult(new Errorable <BlobID> [0]));
            }

            // Delete each blob synchronously:
            Errorable <BlobID>[] results = new Errorable <BlobID> [ids.Length];
            for (int i = 0; i < ids.Length; ++i)
            {
                BlobID id = ids[i];
                results[i] = deleteBlob(id);
            }

            // TODO: Run through all the 'objects' directories and prune empty ones.
            // Too eager? Could cause conflicts with other threads.

            return(Task.FromResult(results));
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Verify the provided software entitlement token
        /// </summary>
        /// <param name="tokenString">A software entitlement token to verify.</param>
        /// <param name="expectedAudience">The audience for whom the token should be intended.</param>
        /// <param name="expectedIssuer">The issuer who should have created the token.</param>
        /// <param name="application">The specific application id of the application </param>
        /// <param name="ipAddress">Address of the machine requesting token validation.</param>
        /// <returns>Either a software entitlement describing the approved entitlement, or errors
        /// explaining why it wasn't approved.</returns>
        public Errorable <NodeEntitlements> Verify(
            string tokenString,
            string expectedAudience,
            string expectedIssuer,
            string application,
            IPAddress ipAddress)
        {
            var validationParameters = new TokenValidationParameters
            {
                ValidateAudience         = true,
                ValidAudience            = expectedAudience,
                ValidateIssuer           = true,
                ValidIssuer              = expectedIssuer,
                ValidateLifetime         = true,
                RequireExpirationTime    = true,
                RequireSignedTokens      = SigningKey != null,
                ClockSkew                = TimeSpan.FromSeconds(60),
                IssuerSigningKey         = SigningKey,
                ValidateIssuerSigningKey = true,
                TokenDecryptionKey       = EncryptionKey
            };

            try
            {
                var handler   = new JwtSecurityTokenHandler();
                var principal = handler.ValidateToken(tokenString, validationParameters, out var token);

                if (!VerifyApplication(principal, application))
                {
                    return(ApplicationNotEntitledError(application));
                }

                if (!VerifyIpAddress(principal, ipAddress))
                {
                    return(MachineNotEntitledError(ipAddress));
                }

                var entitlementIdClaim = principal.FindFirst(Claims.EntitlementId);
                if (entitlementIdClaim == null)
                {
                    return(IdentifierNotPresentError());
                }

                var result = new NodeEntitlements()
                             .FromInstant(new DateTimeOffset(token.ValidFrom))
                             .UntilInstant(new DateTimeOffset(token.ValidTo))
                             .AddApplication(application)
                             .WithIdentifier(entitlementIdClaim.Value)
                             .AddIpAddress(ipAddress);

                var virtualMachineIdClaim = principal.FindFirst(Claims.VirtualMachineId);
                if (virtualMachineIdClaim != null)
                {
                    result = result.WithVirtualMachineId(virtualMachineIdClaim.Value);
                }

                return(Errorable.Success(result));
            }
            catch (SecurityTokenNotYetValidException exception)
            {
                return(TokenNotYetValidError(exception.NotBefore));
            }
            catch (SecurityTokenExpiredException exception)
            {
                return(TokenExpiredError(exception.Expires));
            }
            catch (SecurityTokenException exception)
            {
                return(InvalidTokenError(exception.Message));
            }
        }
Ejemplo n.º 14
0
 private Errorable <NodeEntitlements> IdentifierNotPresentError()
 {
     return(Errorable.Failure <NodeEntitlements>(
                "Entitlement identifier missing from entitlement token."));
 }
Ejemplo n.º 15
0
 private Errorable <NodeEntitlements> MachineNotEntitledError(IPAddress address)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Token does not grant entitlement for {address}"));
 }
Ejemplo n.º 16
0
        public async Task<ActionResult> Create(Errorable<RefName> erefName, CommitRequest cmj)
        {
            if (erefName.HasErrors) return ErrorJson(erefName);
            if (cmj == null) return Json(new { success = false });

            // First get the ref and its CommitID, if it exists:
            Ref rf;
            var erf = await cms.rfrepo.GetRefByName(erefName.Value);
            if (erf.HasErrors)
            {
                // Skip the RefNameDoesNotExistError error (should only be one - using All() makes sure that any other errors will fall out):
                if (!erf.Errors.All(err => err is RefNameDoesNotExistError))
                    return ErrorJson(erf);
                rf = null;
            }
            else rf = erf.Value;

            // Map from the JSON CommitModel:
            var ecb = cmj.FromJSON();
            if (ecb.HasErrors) return ErrorJson(ecb);

            Commit.Builder cb = ecb.Value;
            
            // Add the ref's CommitID as the parent, if the ref exists:
            if ((rf != null) && (cb.Parents.Count == 0))
            {
                cb.Parents.Add(rf.CommitID);
            }

            // Persist the commit:
            var epcm = await cms.cmrepo.PersistCommit(cb);
            if (epcm.HasErrors) return ErrorJson(epcm);

            Commit pcm = epcm.Value;

            // Persist the ref with this new CommitID:
            Ref.Builder rfb = new Ref.Builder(erefName.Value, pcm.ID);
            erf = await cms.rfrepo.PersistRef(rfb);
            if (erf.HasErrors) return ErrorJson(erf);

            rf = erf.Value;

            // Return the commit model as JSON again:
            return Json(new { @ref = rf.ToJSON(), commit = pcm.ToJSON() }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 17
0
            public void GivenValue_ReturnsResultWithNoErrors()
            {
                var result = Errorable.Success(42);

                result.Errors.Should().HaveCount(0);
            }
Ejemplo n.º 18
0
            public void GivenSingleValue_ReturnsResultWithoutValue()
            {
                var result = Errorable.Failure <int>("Error");

                result.HasValue.Should().BeFalse();
            }
        public Task<Errorable<BlobID>[]> DeleteBlobs(params BlobID[] ids)
        {
            if (ids == null) throw new ArgumentNullException("ids");
            if (ids.Length == 0) return Task.FromResult(new Errorable<BlobID>[0]);

            // Delete each blob synchronously:
            Errorable<BlobID>[] results = new Errorable<BlobID>[ids.Length];
            for (int i = 0; i < ids.Length; ++i)
            {
                BlobID id = ids[i];
                results[i] = deleteBlob(id);
            }

            // TODO: Run through all the 'objects' directories and prune empty ones.
            // Too eager? Could cause conflicts with other threads.

            return Task.FromResult(results);
        }
Ejemplo n.º 20
0
 public static void ShowError(Errorable e)
 {
     MessageBox.Show("Error " + e.errorCode + " : " + e.errorMessage, "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
 }
Ejemplo n.º 21
0
        public async Task<ActionResult> GetCommitTree(Errorable<CommitID.Partial> epid, int depth = 10)
        {
            if (epid.HasErrors) return ErrorJson(epid);

            // Attempt to resolve the partial ID:
            var eid = await cms.cmrepo.ResolvePartialID(epid.Value);
            if (eid.HasErrors) return ErrorJson(eid);
            
            var ecmtr = await cms.cmrepo.GetCommitTree(eid.Value, depth);
            if (ecmtr.HasErrors) return ErrorJson(ecmtr);

            CommitTree cmtr = ecmtr.Value;

            return Json(new { depth = depth, commit_tree = toJSON(cmtr.RootID, cmtr.Commits) }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 22
0
            public void GivenValue_ReturnsResultWithValue()
            {
                var result = Errorable.Success(42);

                result.HasValue.Should().BeTrue();
            }
Ejemplo n.º 23
0
            public void GivenSingleValue_ReturnsResultWithOneError()
            {
                var result = Errorable.Failure <int>("Error");

                result.Errors.Should().HaveCount(1);
            }
Ejemplo n.º 24
0
        public async Task<ActionResult> CompareBlobs(Errorable<BlobID.Partial> epida, Errorable<BlobID.Partial> epidb)
        {
            if (epida.HasErrors || epidb.HasErrors) return Json(new { errors = (epida.Errors + epidb.Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            // Resolve the partial IDs:
            var eids = await cms.blrepo.ResolvePartialIDs(epida.Value, epidb.Value);
            if (eids[0].HasErrors || eids[1].HasErrors) return Json(new { errors = (eids[0].Errors + eids[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            BlobID idA = eids[0].Value;
            BlobID idB = eids[1].Value;

            // Get the Blobs:
            var ebls = await cms.blrepo.GetBlobs(idA, idB);
            if (ebls[0].HasErrors || ebls[1].HasErrors) return Json(new { errors = (ebls[0].Errors + ebls[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            IStreamedBlob blA = ebls[0].Value, blB = ebls[1].Value;

            // Stream in both blobs' contents to string values:
            var etextA = await blA.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextA.HasErrors) return ErrorJson(etextA);
            
            var etextB = await blB.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextB.HasErrors) return ErrorJson(etextB);

            // TODO: update to a better diff engine that supports merging...

            // Create a diff engine:
            IDiffer differ = new Differ();
            ISideBySideDiffBuilder builder = new SideBySideDiffBuilder(differ);

            // Run the diff engine to get the output model:
            // NOTE: I would prefer it to read in via a Stream but perhaps that is not possible given the algorithm implemented.
            var sxs = builder.BuildDiffModel(etextA.Value, etextB.Value);

            // Return the result as JSON:
            return Json(sxs.ToJSON(), JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 25
0
 private Errorable <NodeEntitlements> ApplicationNotEntitledError(string application)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Token does not grant entitlement for {application}"));
 }
Ejemplo n.º 26
0
        public async Task<ActionResult> GetCommitTree(Errorable<RefName> erefName, int depth = 10)
        {
            if (erefName.HasErrors) return ErrorJson(erefName);

            var ecmtr = await cms.cmrepo.GetCommitTreeByRefName(erefName.Value, depth);
            if (ecmtr.HasErrors) return ErrorJson(ecmtr);

            Tuple<Ref, CommitTree> cmtr = ecmtr.Value;

            return Json(new { @ref = cmtr.Item1.ToJSON(), depth = depth, commit_tree = toJSON(cmtr.Item2.RootID, cmtr.Item2.Commits) }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 27
0
        private static Errorable <NodeEntitlements> TokenNotYetValidError(DateTime notBefore)
        {
            var timestamp = notBefore.ToString(TimestampParser.ExpectedFormat);

            return(Errorable.Failure <NodeEntitlements>($"Token will not be valid until {timestamp}"));
        }
Ejemplo n.º 28
0
            public void WhenSuccess_ReturnsExpectedValue()
            {
                var result = Errorable.Success(42);

                result.Value.Should().Be(42);
            }
Ejemplo n.º 29
0
        public async Task<ActionResult> GetTreeByID(Errorable<TreeID.Partial> epid)
        {
            if (epid.HasErrors) return ErrorJson(epid);

            var eid = await cms.trrepo.ResolvePartialID(epid.Value);
            if (eid.HasErrors) return ErrorJson(eid);

            var etree = await cms.trrepo.GetTree(eid.Value);
            if (etree.HasErrors) return ErrorJson(etree);

            var tree = etree.Value;

            return Json(new { tree = projectTreeJSON(tree) }, JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 30
0
        private static Errorable <NodeEntitlements> TokenExpiredError(DateTime expires)
        {
            var timestamp = expires.ToString(TimestampParser.ExpectedFormat);

            return(Errorable.Failure <NodeEntitlements>($"Token expired at {timestamp}"));
        }
Ejemplo n.º 31
0
 private static Errorable <NodeEntitlements> InvalidTokenError(string reason)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Invalid token ({reason})"));
 }
        private async Task <Errorable <TreeNode> > getTree(TreeID id)
        {
            FileInfo fi = system.getPathByID(id);

            if (!fi.Exists)
            {
                return(new TreeIDRecordDoesNotExistError(id));
            }

            byte[] buf;
            int    nr = 0;

            using (var fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 16384, true))
            {
                // TODO: implement an async buffered Stream:
                buf = new byte[16384];
                nr  = await fs.ReadAsync(buf, 0, 16384).ConfigureAwait(continueOnCapturedContext: false);

                if (nr >= 16384)
                {
                    // My, what a large tree you have!
                    throw new NotSupportedException();
                }
            }

            TreeNode.Builder tb = new TreeNode.Builder(new List <TreeTreeReference>(), new List <TreeBlobReference>());

            // Parse the Tree:
            using (var ms = new MemoryStream(buf, 0, nr, false))
                using (var sr = new StreamReader(ms, Encoding.UTF8))
                {
                    string line;

                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.StartsWith("tree "))
                        {
                            string linked_treeid = line.Substring(5, (TreeID.ByteArrayLength * 2));
                            string name          = line.Substring(6 + (TreeID.ByteArrayLength * 2));

                            // Attempt to parse the TreeID and verify its existence:
                            Errorable <TreeID> trid = TreeID.TryParse(linked_treeid);
                            if (trid.HasErrors)
                            {
                                return(trid.Errors);
                            }
                            if (!system.getPathByID(trid.Value).Exists)
                            {
                                return(new TreeIDRecordDoesNotExistError(trid.Value));
                            }
                            tb.Trees.Add(new TreeTreeReference.Builder(name, trid.Value));
                        }
                        else if (line.StartsWith("blob "))
                        {
                            string linked_blobid = line.Substring(5, (TreeID.ByteArrayLength * 2));
                            string name          = line.Substring(6 + (TreeID.ByteArrayLength * 2));

                            // Attempt to parse the BlobID and verify its existence:
                            Errorable <BlobID> blid = BlobID.TryParse(linked_blobid);
                            if (blid.HasErrors)
                            {
                                return(blid.Errors);
                            }
                            if (!system.getPathByID(blid.Value).Exists)
                            {
                                return(new BlobIDRecordDoesNotExistError(blid.Value));
                            }
                            tb.Blobs.Add(new TreeBlobReference.Builder(name, blid.Value));
                        }
                    }
                }

            // Create the immutable Tree from the Builder:
            TreeNode tr = tb;

            // Validate the computed TreeID:
            if (tr.ID != id)
            {
                return(new ComputedTreeIDMismatchError(tr.ID, id));
            }

            return(tr);
        }