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() }); }
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); }
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); }
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); }
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); }
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); }
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); }
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 }
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))); }
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); }
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)); }
/// <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)); } }
private Errorable <NodeEntitlements> IdentifierNotPresentError() { return(Errorable.Failure <NodeEntitlements>( "Entitlement identifier missing from entitlement token.")); }
private Errorable <NodeEntitlements> MachineNotEntitledError(IPAddress address) { return(Errorable.Failure <NodeEntitlements>( $"Token does not grant entitlement for {address}")); }
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); }
public void GivenValue_ReturnsResultWithNoErrors() { var result = Errorable.Success(42); result.Errors.Should().HaveCount(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); }
public static void ShowError(Errorable e) { MessageBox.Show("Error " + e.errorCode + " : " + e.errorMessage, "", MessageBoxButtons.OK, MessageBoxIcon.Warning); }
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); }
public void GivenValue_ReturnsResultWithValue() { var result = Errorable.Success(42); result.HasValue.Should().BeTrue(); }
public void GivenSingleValue_ReturnsResultWithOneError() { var result = Errorable.Failure <int>("Error"); result.Errors.Should().HaveCount(1); }
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); }
private Errorable <NodeEntitlements> ApplicationNotEntitledError(string application) { return(Errorable.Failure <NodeEntitlements>( $"Token does not grant entitlement for {application}")); }
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); }
private static Errorable <NodeEntitlements> TokenNotYetValidError(DateTime notBefore) { var timestamp = notBefore.ToString(TimestampParser.ExpectedFormat); return(Errorable.Failure <NodeEntitlements>($"Token will not be valid until {timestamp}")); }
public void WhenSuccess_ReturnsExpectedValue() { var result = Errorable.Success(42); result.Value.Should().Be(42); }
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); }
private static Errorable <NodeEntitlements> TokenExpiredError(DateTime expires) { var timestamp = expires.ToString(TimestampParser.ExpectedFormat); return(Errorable.Failure <NodeEntitlements>($"Token expired at {timestamp}")); }
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); }