string GetWidgetContent(DreamContext context, string widgetType, string id, string mode, XDoc data) { if (mode.ToLowerInvariant() != "edit") { Plug plug = Plug.New(Env.RootUri.At("wiki-data", widgetType, "render")); XDoc widgetXhtml = plug.Post(data).Document; if (widgetXhtml == null || widgetXhtml.IsEmpty) { LogUtils.LogWarning(_log, string.Format("GetWidgetContent: null/empty document for /wiki-data/{0}/render/ (data)", widgetType), data); throw new DreamAbortException(DreamMessage.BadRequest("no widget data")); } return(widgetXhtml.ToString()); } else { Plug normalizePlug = Plug.New(Env.RootUri.At("wiki-data", widgetType, "normalize")); data = normalizePlug.Post(data).Document; Plug renderPlug = Plug.New(Env.RootUri.At("wiki-data", widgetType, "render")); XDoc renderHtml = renderPlug.Post(data).Document; string jsonData = data.ToJson(); return(new XDoc("div") .Attr("class", "widget").Attr("widgetid", id).Attr("widgettype", widgetType).Attr("style", "display:none") .Start("div") .Attr("class", "data") .Value(string.Format("Widget.registerWidget({0},{1})", id, jsonData)) .End() .Start("div") .Attr("class", "view") .Add(renderHtml) .End() .ToString()); } }
public void Returns_callback_gets_request_data() { var doc = new XDoc("doc").Elem("foo", StringUtil.CreateAlphaNumericKey(6)); var success = new XDoc("yay"); var uri = new XUri("http://mock/foo/").With("foo", "baz"); MockPlug.Setup(new XUri("http://mock/foo")).Returns(invocation => { if (invocation.Verb != "POST") { return(DreamMessage.BadRequest("wrong verb: " + invocation.Verb)); } if (invocation.Uri != uri) { return(DreamMessage.BadRequest("wrong uri: " + invocation.Uri)); } if (invocation.Request.Headers["header"] != "value") { return(DreamMessage.BadRequest("wrong header value")); } if (invocation.Request.ToDocument() != doc) { return(DreamMessage.BadRequest("wrong body")); } return(DreamMessage.Ok(success)); }); var msg = Plug.New(uri).WithHeader("header", "value").Post(doc, new Result <DreamMessage>()).Wait(); Assert.IsTrue(msg.IsSuccessful, msg.ToDocument().ToPrettyString()); Assert.AreEqual(success, msg.ToDocument()); }
public DreamMessage GetPageHandler(DreamContext context, DreamMessage message) { page cur = null;//deki.GetCur(true); Max: commented out to allow compilation if (cur == null) { return(DreamMessage.BadRequest("can't load page")); } string mode = context.Uri.GetParam("mode", "raw").ToLowerInvariant(); switch (mode) { case "raw": return(DreamMessage.Ok(MimeType.HTML, cur.Text)); case "xml": string xml = string.Format(DekiWikiService.XHTML_LOOSE, cur.Text); XDoc result = XDoc.FromXml(xml); return(DreamMessage.Ok(MimeType.XHTML, result.ToXHtml())); case "export": case "edit": case "print": case "view": return(DreamMessage.Ok(MimeType.HTML, /*deki.Render(cur.Text, mode) Max:Removed to allow compilation*/ "")); } return(DreamMessage.NotImplemented(string.Format("'mode={0}' is not supported"))); }
private DreamMessage GetFile(DreamContext context) { DreamMessage message; string[] parts = context.GetSuffixes(UriPathFormat.Decoded); string filename = _resourcesPath; foreach (string part in parts) { if (part.EqualsInvariant("..")) { _log.WarnFormat("attempted to access file outside of target folder: {0}", string.Join("/", parts)); throw new DreamBadRequestException("paths cannot contain '..'"); } filename = Path.Combine(filename, part); } try { message = DreamMessage.FromFile(filename, context.Verb == Verb.HEAD); } catch (FileNotFoundException e) { message = DreamMessage.NotFound("resource not found: " + String.Join("/", context.GetSuffixes(UriPathFormat.Decoded))); } catch (Exception e) { message = DreamMessage.BadRequest("invalid path"); } return(message); }
internal DreamMessage Call(string verb, XUri uri, XDoc request) { _verb = verb; _uri = uri; _request = request; return(DreamMessage.BadRequest("unexpected call")); }
public Yield GetFileHandler(DreamContext context, DreamMessage request, Result <DreamMessage> response) { string suffixPath = string.Join("" + Path.DirectorySeparatorChar, context.GetSuffixes(UriPathFormat.Decoded)); string filename = Path.Combine(_path, suffixPath); if (Directory.Exists(filename)) { XDoc ret = new XDoc("files"); string pattern = context.GetParam("pattern", ""); AddDirectories(new DirectoryInfo(filename), pattern, ret); AddFiles(new DirectoryInfo(filename), pattern, ret); response.Return(DreamMessage.Ok(ret)); yield break; } DreamMessage message; try { message = DreamMessage.FromFile(filename, StringUtil.EqualsInvariant(context.Verb, "HEAD")); } catch (FileNotFoundException) { message = DreamMessage.NotFound("file not found"); } catch (Exception) { message = DreamMessage.BadRequest("invalid path"); } // open file and stream it to the requester response.Return(message); }
public Yield PostImport(DreamContext context, DreamMessage request, Result <DreamMessage> response) { string uri = context.GetParam("uri", null); string reltopath = context.GetParam("reltopatch", "/"); DreamMessage packageMessage = request; if (!string.IsNullOrEmpty(uri)) { Result <DreamMessage> packageResult; yield return(packageResult = Plug.New(uri).InvokeEx("GET", DreamMessage.Ok(), new Result <DreamMessage>())); packageMessage = packageResult.Value; if (!packageMessage.IsSuccessful) { throw new DreamAbortException(DreamMessage.BadRequest(string.Format("Unable to retrieve package from Uri '{0}': {1}", uri, packageMessage.Status))); } } string tempFile = Path.GetTempFileName(); Stream tempStream = File.Create(tempFile); Result <long> copyResult; // TODO (steveb): use WithCleanup() to dispose of resources in case of failure yield return(copyResult = packageMessage.ToStream().CopyTo(tempStream, packageMessage.ContentLength, new Result <long>()).Catch()); tempStream.Dispose(); if (copyResult.HasException) { response.Throw(copyResult.Exception); yield break; } ArchivePackageReader archivePackageReader = new ArchivePackageReader(File.OpenRead(tempFile)); Result <ImportManager> importerResult; Plug authorizedDekiApi = _dekiApi.WithHeaders(request.Headers); // TODO (steveb): use WithCleanup() to dispose of resources in case of failure yield return(importerResult = ImportManager.CreateAsync(authorizedDekiApi, reltopath, archivePackageReader, new Result <ImportManager>()).Catch()); if (importerResult.HasException) { archivePackageReader.Dispose(); File.Delete(tempFile); response.Throw(importerResult.Exception); yield break; } ImportManager importManager = importerResult.Value; Result importResult; yield return(importResult = importManager.ImportAsync(new Result()).Catch()); archivePackageReader.Dispose(); File.Delete(tempFile); if (importResult.HasException) { response.Throw(importResult.Exception); yield break; } response.Return(DreamMessage.Ok()); yield break; }
public void Get_via_internal_routing_follows_301_but_expects_query_to_be_in_location() { using (var hostInfo = DreamTestHelper.CreateRandomPortHost()) { var mock = MockService.CreateMockService(hostInfo); var redirectCalled = 0; var targetCalled = 0; mock.Service.CatchAllCallback = delegate(DreamContext context, DreamMessage request, Result <DreamMessage> response) { var msg = "nothing here"; var q = context.Uri.GetParam("q"); var forward = context.Uri.GetParam("forward"); if (context.Uri.LastSegment == "redirect") { _log.Debug("called redirect"); var redirect = context.Service.Self.Uri.At("target").AsPublicUri(); if (forward == "true") { redirect = redirect.With("q", q); } redirectCalled++; var headers = new DreamHeaders(); headers.Add(DreamHeaders.LOCATION, redirect.ToString()); response.Return(new DreamMessage(DreamStatus.MovedPermanently, headers)); return; } if (context.Uri.LastSegment == "target") { _log.Debug("called target"); if (q == "x") { _log.Debug("target request had query"); targetCalled++; response.Return(DreamMessage.Ok()); return; } response.Return(DreamMessage.BadRequest("missing query param")); return; } _log.DebugFormat("called uri: {0} => {1}", context.Uri, msg); response.Return(DreamMessage.NotFound(msg)); }; var uri = mock.AtLocalMachine.At("redirect"); _log.DebugFormat("calling redirect service at {0}", uri); var r = Plug.New(uri).With("q", "x").Get(new Result <DreamMessage>()).Wait(); Assert.AreEqual(DreamStatus.BadRequest, r.Status); Assert.AreEqual(1, redirectCalled, "redirect without forward called incorrectly"); Assert.AreEqual(0, targetCalled, "target without forward called incorrectly"); redirectCalled = 0; targetCalled = 0; r = Plug.New(uri).With("q", "x").With("forward", "true").Get(new Result <DreamMessage>()).Wait(); Assert.IsTrue(r.IsSuccessful, r.HasDocument ? r.ToDocument()["message"].AsText : "request failed: " + r.Status); Assert.AreEqual(1, redirectCalled, "redirect with forward called incorrectly"); Assert.AreEqual(1, targetCalled, "target with forward called incorrectly"); } }
public void Plug_extension_to_return_document_sets_exception_on_non_OK_response() { var autoMockPlug = MockPlug.Register(new XUri("mock://mock")); autoMockPlug.Expect().Verb("GET").Response(DreamMessage.BadRequest("bad puppy")); var r = Plug.New("mock://mock").Get(new Result <XDoc>()).Block(); Assert.IsTrue(r.HasException); Assert.AreEqual(typeof(DreamResponseException), r.Exception.GetType()); Assert.AreEqual(DreamStatus.BadRequest, ((DreamResponseException)r.Exception).Response.Status); }
protected page Authorize(DreamContext context, user user, DekiAccessLevel access, string pageIdName) { page result; long id = context.Uri.GetParam <long>(pageIdName, 0); if (id == 0) { string title = context.Uri.GetParam("title", ""); if (string.IsNullOrEmpty(title)) { throw new DreamAbortException(DreamMessage.NotFound("")); } result = page.GetCurByTitle(title); } else { result = page.GetCurByID((ulong)id); } // check that page was found if ((result == null) || (result.ID <= 0)) { throw new DreamAbortException(DreamMessage.NotFound("")); } // check if action is allowed string action; switch (access) { case DekiAccessLevel.Read: action = DekiWikiConstants.ACTION_READ; break; case DekiAccessLevel.Write: action = DekiWikiConstants.ACTION_EDIT; break; case DekiAccessLevel.Destroy: action = DekiWikiConstants.ACTION_DELETE; break; default: throw new DreamAbortException(DreamMessage.BadRequest(string.Format("unknown action {0}", access))); } if (!result.userCan(action, user)) { throw new DreamAbortException(DreamMessage.AccessDenied(DekiWikiService.AUTHREALM, "")); } // return page return(result); }
private DreamMessage GetFile(string filename) { DreamMessage message; try { message = DreamMessage.FromFile(filename); } catch (FileNotFoundException e) { message = DreamMessage.NotFound("file not found"); } catch (Exception e) { message = DreamMessage.BadRequest("invalid path"); } return(message); }
internal Yield ConfigureSmtp(DreamContext context, DreamMessage request, Result <DreamMessage> response) { var configuration = context.GetParam("configuration"); var settingsDoc = request.ToDocument(); _log.DebugFormat("configuring settings for configuration '{0}'", configuration); var host = settingsDoc["smtp-host"].AsText; var apikey = settingsDoc["apikey"].AsText; if (string.IsNullOrEmpty(host) && string.IsNullOrEmpty(apikey)) { response.Return(DreamMessage.BadRequest("must specify either new smtp config with a host or specify an apikey")); yield break; } SmtpSettings settings; if (string.IsNullOrEmpty(host)) { settings = new SmtpSettings() { Host = _defaultSettings.Host, Apikey = apikey, AuthPassword = _defaultSettings.AuthPassword, AuthUser = _defaultSettings.AuthUser, EnableSsl = _defaultSettings.EnableSsl, Port = _defaultSettings.Port, }; } else { _log.DebugFormat("Smtp Host: {0}", host); settings = new SmtpSettings { Host = host, AuthUser = settingsDoc["smtp-auth-user"].AsText, AuthPassword = settingsDoc["smtp-auth-password"].AsText, Apikey = apikey, // Note (arnec): ssl requires mono 2.0 and likely root certificate import via 'mozroots --import --ask-remove --machine' EnableSsl = settingsDoc["use-ssl"].AsBool ?? false }; if (settingsDoc["smtp-port"].AsInt.HasValue) { settings.Port = settingsDoc["smtp-port"].AsInt.Value; } } lock (_smtpSettings) { _smtpSettings[configuration] = settings; } response.Return(DreamMessage.Ok()); yield break; }
public void Returns_callback_gets_response_headers_if_added_after_callback() { var success = new XDoc("yay"); MockPlug.Setup(new XUri("http://mock/foo")) .Returns(invocation => { return(invocation.ResponseHeaders["foo"] != "bar" ? DreamMessage.BadRequest("wrong response header") : DreamMessage.Ok(success)); }) .WithResponseHeader("foo", "bar"); var msg = Plug.New("http://mock/foo/").Get(new Result <DreamMessage>()).Wait(); Assert.IsTrue(msg.IsSuccessful, msg.ToDocument().ToPrettyString()); Assert.AreEqual(success, msg.ToDocument()); }
public DreamMessage GetContentHandler(DreamContext context, DreamMessage message) { user user = Authenticate(context, message, DekiUserLevel.User); page page = Authorize(context, user, DekiAccessLevel.Read, "pageid"); DekiContext deki = new DekiContext(message, this.DekiConfig); bool nofollow = (context.Uri.GetParam("nofollow", 0, null) != null); string contents = page.getContent(nofollow); string xml = string.Format(DekiWikiService.XHTML_LOOSE, contents); XDoc doc = XDoc.FromXml(xml); if (doc == null) { LogUtils.LogWarning(_log, "GetContentHandler: null document page content", page.PrefixedName, contents); throw new DreamAbortException(DreamMessage.BadRequest("null document")); } XDoc result = new XDoc("list"); string type = context.Uri.GetParam("type", 0, null); string id = context.Uri.GetParam("id", 0, null); if (id != null) { XDoc widget = doc[string.Format("//default:span[@widgetid={0}]", id)]; if (widget.IsEmpty) { LogUtils.LogWarning(_log, "GetContentHandler: widget not found for ID", id); return(DreamMessage.NotFound("")); } LogUtils.LogTrace(_log, "GetContentHandler: widget by id (id, xspan)", id, widget); result.Add(ConvertFromXSpan(widget)); } else if (type != null) { foreach (XDoc widget in doc[string.Format("//default:span[@widgettype='{0}']", type)]) { result.Add(ConvertFromXSpan(widget)); } LogUtils.LogTrace(_log, "GetContentHandler: widget by type (type, #)", type, result.Count); } else { foreach (XDoc widget in doc["//default:span[@class='widget']"]) { result.Add(ConvertFromXSpan(widget)); } LogUtils.LogTrace(_log, "GetContentHandler: all widgets (#)", type, result.Count); } return(DreamMessage.Ok(result)); }
public DreamMessage PostEditHandler(DreamContext context, DreamMessage message) { XDoc xhtml = message.ContentType.Contains("/html") ? XDoc.FromHtml(new StreamReader(message.Stream, message.ContentEncoding)) : message.Document; if (xhtml == null || xhtml.IsEmpty) { LogUtils.LogWarning(_log, "PostEditHandler: null/empty input document"); throw new DreamAbortException(DreamMessage.BadRequest("null/empty input document")); } string baseHref = context.Uri.GetParam("baseHref", 0, "http://mos/"); string pageID = context.Uri.GetParam("context", ""); XHTMLConverter.Convert(xhtml, baseHref, pageID, true); ConvertAllWidgets("PostEditHandler", xhtml, "edit", pageID); return(DreamMessage.Ok(MimeType.XHTML, xhtml.ToXHtml())); }
internal Yield PublishEvent(DreamContext context, DreamMessage request, Result <DreamMessage> response) { DispatcherEvent ev; try { ev = new DispatcherEvent(request); _log.DebugFormat("{0} received event '{1}'", this.Self.Uri, ev.Id); if (ev.Channel.Scheme == "pubsub") { response.Return(DreamMessage.Forbidden("events published into this service cannot be of scheme 'pubsub'")); yield break; } _dispatcher.Dispatch(ev); response.Return(DreamMessage.Ok(ev.GetEventEnvelope())); } catch (Exception e) { response.Return(DreamMessage.BadRequest(e.Message)); } yield break; }
public DreamMessage GetNavHandler(DreamContext context, DreamMessage message) { DekiContext deki = null; // new DekiContext(message, this.DekiConfig); page cur = null; // deki.GetCur(true); Max: Commented out to allow compilation if (cur == null) { return(DreamMessage.BadRequest("can't load page")); } int maxLevel = context.Uri.GetParam <int>("max-level", 1); bool filterRedirects = context.Uri.GetParam <bool>("redirects", true); ICollection <string> columns = context.Uri.GetParams("column"); string filter = filterRedirects ? " AND page_is_redirect=0" : ""; XDoc ret = new XDoc("nav"); AddCur(deki, cur, ret, columns, filter, maxLevel); return(DreamMessage.Ok(ret)); }
public DreamMessage PostPasteHandler(DreamContext context, DreamMessage message) { XDoc xhtml = message.ContentType.Contains("/html") ? XDoc.FromHtml(new StreamReader(message.Stream, message.ContentEncoding)) : message.Document; if (xhtml == null || xhtml.IsEmpty) { LogUtils.LogWarning(_log, "PostEditHandler: null/empty input document"); throw new DreamAbortException(DreamMessage.BadRequest("null/empty input document")); } string baseHref = context.Uri.GetParam("baseHref", 0, "http://mos/"); string pageID = context.Uri.GetParam("context", ""); XHTMLConverter.Convert(xhtml, baseHref, pageID, true); MindTouch.Dream.Plug plug = MindTouch.Dream.Plug.New(Env.RootUri); foreach (XDoc nodeWithClass in xhtml["//*[@class='vcard']"]) { XDoc replacement = plug.At("wiki-data", "dekibizcard", "hcardtoedit").Post(nodeWithClass).Document; if (replacement != null && !replacement.IsEmpty) { nodeWithClass.Replace(replacement); } } bool insertMagic = context.Uri.GetParam <bool>("insertMagic", false); if (insertMagic) { Plug widgetStorage = Plug.New(Env.RootUri).At("mount", "deki-widgets"); Plug widgetToEdit = Plug.New(Env.RootUri.At("wiki-data", "dekibizcard", "edit")); XDoc files = widgetStorage.With("pattern", "*.vcf").Get().Document; foreach (XDoc fileName in files["file/name"]) { XDoc vcard = XDoc.FromVersit(widgetStorage.At(fileName.Contents).Get().Text, "dekibizcard"); XDoc widgetXhtml = widgetToEdit.Post(vcard).Document; xhtml["//body"].Add(widgetXhtml); } } return(DreamMessage.Ok(MimeType.HTML, xhtml.ToString())); }
public Yield DeleteFile(DreamContext context, DreamMessage request, Result <DreamMessage> response) { var path = GetPath(context); var result = DreamMessage.Ok(); if (Directory.Exists(path)) { // folder delete try { Directory.Delete(path, true); } catch { } } else if (File.Exists(path)) { // delete target file try { _expirationEntries.Delete(path); try { File.Delete(path); } catch { } WriteMeta(path, null, null); } catch (FileNotFoundException) { } catch (DirectoryNotFoundException) { } catch (PathTooLongException) { result = DreamMessage.BadRequest("path too long"); } catch (NotSupportedException) { result = DreamMessage.BadRequest("not supported"); } // try to clean up empty directory string folderpath = Path.GetDirectoryName(path); if (Directory.Exists(folderpath) && (Directory.GetFileSystemEntries(folderpath).Length == 0)) { try { Directory.Delete(folderpath); } catch { } } } response.Return(result); yield break; }
public Yield PutFile(DreamContext context, DreamMessage request, Result <DreamMessage> response) { string filepath = GetPath(context); string folderpath = Path.GetDirectoryName(filepath); double ttl = context.GetParam("ttl", 0.0); TimeSpan?timeToLive = null; if (ttl > 0.0) { timeToLive = TimeSpan.FromSeconds(ttl); } if (Directory.Exists(filepath)) { // filepath is actually an existing directory response.Return(DreamMessage.Conflict("there exists a directory at the specified file path")); yield break; } // create folder if need be if (!Directory.Exists(folderpath)) { Directory.CreateDirectory(folderpath); } // save request stream in target file DreamMessage result; try { request.ToStream().CopyToFile(filepath, request.ContentLength); WriteMeta(filepath, timeToLive, null); result = DreamMessage.Ok(); } catch (DirectoryNotFoundException) { result = DreamMessage.NotFound("directory not found"); } catch (PathTooLongException) { result = DreamMessage.BadRequest("path too long"); } catch (NotSupportedException) { result = DreamMessage.BadRequest("not supported"); } response.Return(result); yield break; }
void MockPlug.IMockInvokee.Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result <DreamMessage> response) { lock (this) { if (_failed) { _log.DebugFormat("we've already failed, no point checking more expectations"); response.Return(DreamMessage.InternalError()); return; } _log.DebugFormat("{0}={1}", verb, uri); XDoc requestDoc = request.HasDocument ? request.ToDocument() : null; if (_expectations.Count == _current) { _log.DebugFormat("excess"); ExcessInterception excess = new ExcessInterception(); _excess.Add(excess); ; response.Return(excess.Call(verb, uri, requestDoc)); return; } AutoMockInvokeExpectation expectation = _expectations[_current]; expectation.Call(verb, uri, request); if (!expectation.Verify()) { AddFailure(_expectations[_current].VerificationFailure); _log.DebugFormat("got failure, setting reset event ({0})", _current); _failed = true; _resetEvent.Set(); response.Return(DreamMessage.BadRequest("expectation failure")); return; } _current++; _log.DebugFormat("expected"); if (_expectations.Count == _current) { _log.DebugFormat("setting reset event"); _resetEvent.Set(); } response.Return(expectation.GetResponse()); } }
private DreamMessage ExceptionTranslation(DreamContext context, Exception exception) { if (exception is CustomException) { _log.DebugFormat("caught custom exception"); if (context.IsTaskEnvDisposed) { return(DreamMessage.BadRequest("context is disposed")); } if (ContextVar == null) { return(DreamMessage.BadRequest("context var wasn't set")); } if (ContextVar != context.GetState <ContextLifeSpan>()) { return(DreamMessage.BadRequest("context vars didn't match")); } return(DreamMessage.Ok()); } return(null); }
public Yield GetFileOrFolderListing(DreamContext context, DreamMessage request, Result <DreamMessage> response) { bool head = StringUtil.EqualsInvariant(context.Verb, "HEAD"); string path = GetPath(context); DreamMessage result; if (File.Exists(path)) { // dealing with a file request TouchMeta(path); // check if request contains a 'if-modified-since' header var lastmodified = File.GetLastWriteTime(path); if (request.CheckCacheRevalidation(lastmodified) && (lastmodified.Year >= 1900)) { response.Return(DreamMessage.NotModified()); yield break; } // retrieve file try { result = DreamMessage.FromFile(path, head); } catch (FileNotFoundException) { result = DreamMessage.NotFound("file not found"); } catch (Exception) { result = DreamMessage.BadRequest("invalid path"); } // add caching headers if file was found if (!head && result.IsSuccessful) { // add caching information; this will avoid unnecessary data transfers by user-agents with caches result.SetCacheMustRevalidate(lastmodified); } } else if (Directory.Exists(path)) { // dealing with a directory request if (head) { // HEAD for a directory doesn't really mean anything, so we just return ok, to indicate that it exists result = DreamMessage.Ok(); } else { var doc = new XDoc("files"); // list directory contents var directories = Directory.GetDirectories(path); foreach (var dir in directories) { if (dir.EndsWithInvariantIgnoreCase(META)) { continue; } doc.Start("folder") .Elem("name", Path.GetFileName(dir)) .End(); } foreach (var filepath in Directory.GetFiles(path)) { var file = new FileInfo(filepath); doc.Start("file") .Elem("name", file.Name) .Elem("size", file.Length) .Elem("date.created", file.CreationTimeUtc) .Elem("date.modified", file.LastWriteTimeUtc); var entry = SyncMeta(filepath); if (entry != null) { doc.Elem("date.expire", entry.When); doc.Elem("date.ttl", entry.TTL); } doc.End(); } result = DreamMessage.Ok(doc); } } else { // nothin here result = DreamMessage.NotFound("no such file or folder"); } response.Return(result); yield break; }
public void Page_delete_events_skip_page_auth() { XUri mockDeki = new XUri("http://mock/deki"); int dekiCalled = 0; MockPlug.Register(mockDeki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("mockDeki called at: {0}", u); dekiCalled++; r2.Return(DreamMessage.BadRequest("shouldn't have called deki")); }); XUri authorizedRecipient = new XUri("http://mock/authorized2"); AutoResetEvent authorizedResetEvent = new AutoResetEvent(false); XDoc authorizedReceived = null; MockPlug.Register(authorizedRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("authorizedRecipient called at: {0}", u); authorizedReceived = r.ToDocument(); authorizedResetEvent.Set(); r2.Return(DreamMessage.Ok()); }); XUri mockRecipient = new XUri("http://mock/r1"); int mockRecipientCalled = 0; MockPlug.Register(mockRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("mockRecipient called at: {0}", u); mockRecipientCalled++; r2.Return(DreamMessage.Ok()); }); XUri dispatcherUri = new XUri("http://mock/dispatcher"); DekiDispatcher dispatcher = new DekiDispatcher( new DispatcherConfig { ServiceUri = dispatcherUri, ServiceAccessCookie = new DreamCookie("service-key", "foo", dispatcherUri), ServiceConfig = new XDoc("config").Elem("uri.deki", mockDeki).Elem("authtoken", "abc") }, _mockRepository.Object ); XDoc sub1 = new XDoc("subscription-set") .Elem("uri.owner", authorizedRecipient) .Start("subscription") .Attr("id", "1") .Elem("channel", "event://default/deki/pages/*") .Start("recipient").Attr("authtoken", "abc").Elem("uri", authorizedRecipient).End() .End(); Thread.Sleep(100); _log.DebugFormat("registering sub set 1"); dispatcher.RegisterSet("abc", sub1, "def"); XDoc sub2 = new XDoc("subscription-set") .Elem("uri.owner", mockRecipient.At("1")) .Start("subscription") .Attr("id", "1") .Elem("uri.resource", "deki://default/pages/10") .Elem("channel", "event://default/deki/pages/*") .Start("recipient").Attr("userid", "1").Elem("uri", "http://mock/r1/match").End() .End(); Thread.Sleep(100); _log.DebugFormat("registering sub set 2"); dispatcher.RegisterSet("abc", sub2, "def"); XDoc evDoc = new XDoc("deki-event") .Attr("wikiid", "default") .Elem("channel", "event://default/deki/pages/delete") .Elem("uri", "deki://default/pages/10") .Elem("pageid", "10"); var ev = new DispatcherEvent(evDoc, new XUri("event://default/deki/pages/delete"), new XUri("deki://default/pages/10"), new XUri("http://default/deki/pages/10")); _log.DebugFormat("ready to dispatch event"); // Meh. Testing multithreaded code is wonky. This 1000ms sleep is required, otherwise the event below never fires Thread.Sleep(1000); dispatcher.Dispatch(ev); // since we're waiting for more than one dekiPageAuthEvent, we give it a chance to finish after the first triggers Assert.IsTrue(authorizedResetEvent.WaitOne(5000, false)); Assert.AreEqual(0, dekiCalled); Assert.AreEqual(0, mockRecipientCalled); Assert.AreEqual(evDoc, authorizedReceived); }
//--- Misc exception handlers --- private static DreamMessage Map(MindTouchInvalidOperationException e, DekiResources resources) { return(DreamMessage.BadRequest(e.Message)); }
private static DreamMessage Map(DekiLicenseException e, DekiResources resources) { return(DreamMessage.BadRequest(e.Message)); }
//--- generic ResourcedMindTouchException handlers --- private static DreamMessage Map(MindTouchInvalidCallException e, DekiResources resources) { return(DreamMessage.BadRequest(resources.Localize(e.Resource))); }
private DreamMessage MapPlainException(DreamContext context, Exception exception) { return(DreamMessage.BadRequest(exception.Message)); }
public Yield GetQueuedItem(DreamContext context, DreamMessage request, Result <DreamMessage> response) { uint pageId = context.GetParam <uint>("pageid", 0); string containerId = context.GetParam("containerId", null); string authtoken = null; foreach (DreamCookie cookie in request.Cookies) { if (StringUtil.EqualsInvariantIgnoreCase("authtoken", cookie.Name)) { authtoken = cookie.Value; break; } } if (pageId == 0) { _log.WarnFormat("Bad pageId"); response.Return(DreamMessage.BadRequest("Bad pageId")); yield break; } if (string.IsNullOrEmpty(containerId)) { _log.WarnFormat("Missing containerId"); response.Return(DreamMessage.BadRequest("Missing containerId")); yield break; } if (string.IsNullOrEmpty(authtoken)) { _log.WarnFormat("Unable to retrieve subscriber credentials from cookie"); response.Return(DreamMessage.BadRequest("Unable to retrieve subscriber credentials from cookie")); yield break; } Tuplet <string, DateTime> userCache; if (!_userCache.TryGetValue(authtoken, out userCache)) { Result <DreamMessage> userResult; yield return(userResult = _deki.At("users", "current").WithHeader("X-Authtoken", authtoken).GetAsync()); if (!userResult.Value.IsSuccessful) { _log.WarnFormat("Unable to retrieve user info for provided credentials"); response.Return(DreamMessage.BadRequest("Unable to retrieve user info for provided credentials")); yield break; } XDoc userDoc = userResult.Value.ToDocument(); _log.DebugFormat("caching user info for '{0}': {1}", userDoc["username"].AsText, userDoc["@href"].AsUri.AsPublicUri()); userCache = new Tuplet <string, DateTime>(userDoc["@href"].AsUri.AsPublicUri().Path, DateTime.UtcNow); lock (_userCache) { _userCache[authtoken] = userCache; } } string subscriber = userCache.Item1; lock (_subscriptions) { Subscription subscription; if (!_subscriptions.TryGetValue(pageId, out subscription)) { subscription = new Subscription(); _subscriptions[pageId] = subscription; _log.DebugFormat("created subscription for {0}", pageId); } _log.DebugFormat("checking subscription for {0}", subscriber); if (!subscription.HasChanged(subscriber)) { response.Return(DreamMessage.Ok()); yield break; } } XDoc doc = new XDoc("div") .Attr("class", "systemmsg") .Start("div") .Attr("class", "inner") .Value("The page has changed. Click ") .Start("a") .Attr("rel", "custom") .Attr("href", "") .Value("here") .End() .Value(" to reload.") .End() .Start("script") .Attr("type", "text/javascript") .Value(string.Format("$('#{0}').slideDown('slow');", containerId)) .End(); _log.DebugFormat("page {0} changed deliverd", pageId); response.Return(DreamMessage.Ok(doc)); yield break; }