Exemple #1
0
        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);
        }
Exemple #2
0
 public Yield DeleteRecord(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     string name = context.GetSuffix(0, UriPathFormat.Normalized);
     DeleteRecord(name);
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #3
0
 public Yield GetEntries(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     XAtomFeed feed = _feed;
     if(feed != null) {
         response.Return(DreamMessage.Ok(MimeType.ATOM, _feed));
     } else {
         throw new DreamBadRequestException("not initialized");
     }
     yield break;
 }
Exemple #4
0
 public Yield GetAllRecords(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     XDoc result = new XDoc("list");
     lock(_directory) {
         foreach(KeyValuePair<string, DirectoryRecord> entry in _directory) {
             result.Add(entry.Value.ToXDoc());
         }
     }
     response.Return(DreamMessage.Ok(result));
     yield break;
 }
Exemple #5
0
 internal Yield DeleteQueue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     var name = context.GetParam("queuename");
     lock(_queues) {
         ITransactionalQueue<XDoc> queue;
         if(_queues.TryGetValue(name, out queue)) {
             queue.Dispose();
             Directory.Delete(Path.Combine(_rootPath, name),true);
             _queues.Remove(name);
         }
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #6
0
 public void Can_clone_a_memory_stream_message()
 {
     var text = "blah";
     var stream = new MemoryStream();
     var writer = new StreamWriter(stream);
     writer.Write(text);
     writer.Flush();
     stream.Position = 0;
     var m = new DreamMessage(DreamStatus.Ok, new DreamHeaders().Add("foo", "bar"), MimeType.TEXT, stream.Length, stream);
     m.Headers.Add("baz", "blah");
     _log.Debug("about to clone");
     var m2 = m.Clone();
     var reader = new StreamReader(m2.ToStream());
     Assert.AreEqual(text, reader.ReadToEnd());
     Assert.AreEqual(m.ContentType.ToString(), m2.ContentType.ToString());
     Assert.AreEqual(m.Headers["foo"], m2.Headers["foo"]);
     Assert.AreEqual(m.Headers["baz"], m2.Headers["baz"]);
 }
Exemple #7
0
        public Yield GetEntry(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            string id = context.GetParam("id");
            XAtomEntry entry = null;

            // get feed
            XAtomFeed feed = _feed;
            if(feed != null) {
                lock(feed) {
                    entry = new XAtomEntry(feed[string.Format("entry[id='{0}']", Self.At(id).Uri)]);
                }
            } else {
                throw new DreamBadRequestException("not initialized");
            }
            if(entry.IsEmpty) {
                response.Return(DreamMessage.NotFound("entry not found"));
            } else {
                response.Return(DreamMessage.Ok(MimeType.ATOM, entry));
            }
            yield break;
        }
Exemple #8
0
        internal Yield CreateSubscriptionSet(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            XDoc subscriptionSet = request.ToDocument();
            Tuplet<PubSubSubscriptionSet, bool> set = _dispatcher.RegisterSet(subscriptionSet);
            XUri locationUri = Self.At("subscribers", set.Item1.Location).Uri.AsPublicUri();
            DreamMessage msg = null;
            if(set.Item2) {

                // existing subs cause a Conflict with ContentLocation of the sub
                msg = DreamMessage.Conflict("The specified owner already has a registered subscription set");
                msg.Headers.ContentLocation = locationUri;
            } else {

                // new subs cause a Created with Location of the sub, plus XDoc containing the location
                XDoc responseDoc = new XDoc("subscription-set")
                    .Elem("uri.location", locationUri)
                    .Elem("access-key", set.Item1.AccessKey);
                msg = DreamMessage.Created(locationUri, responseDoc);
                msg.Headers.Location = locationUri.With("access-key", set.Item1.AccessKey);
            }
            response.Return(msg);
            yield break;
        }
Exemple #9
0
 public override DreamAccess DetermineAccess(DreamContext context, DreamMessage request)
 {
     if(context.Feature.Signature.StartsWith("subscribers/")) {
         var location = context.GetParam("location", null);
         var set = _dispatcher[location];
         if(set != null) {
             var accessKey = context.GetParam("access-key", null);
             if(string.IsNullOrEmpty(accessKey)) {
                 var cookie = DreamCookie.GetCookie(request.Cookies, "access-key");
                 if(cookie != null) {
                     accessKey = cookie.Value;
                 }
             }
             if(set.AccessKey.EqualsInvariant(accessKey)) {
                 return DreamAccess.Private;
             }
             _log.DebugFormat("no matching access-key in query or cookie for location '{0}'", location);
         } else {
             _log.DebugFormat("no subscription set for location '{0}'", location);
         }
     }
     return base.DetermineAccess(context, request);
 }
Exemple #10
0
        public Yield convert(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            string methodStr = context.GetParam("method", string.Empty);
            string aliasStr = context.GetParam("id", string.Empty);

            XUri secPage = new XUri( context.ServerUri ).At( "deki", "pages", "=Convert:" + methodStr );
            Plug _dekiSec = Plug.New( secPage );
            XDoc secDoc = _dekiSec.Get().ToDocument();

            string userURL = secDoc["user.author/@href"].AsInnerText;
            Plug _dekiUser = Plug.New( userURL );
            XDoc userDoc = _dekiUser.Get().ToDocument();
            string perms = userDoc["permissions.user"]["operations"].AsInnerText;
            if ( !perms.Contains("UNSAFECONTENT") ) {
                response.Return( DreamMessage.Forbidden("UNSAFECONTENT not enabled") );
                yield break;
            }

            XUri codePage = new XUri( context.ServerUri ).At( "deki","pages", "=Convert:" + methodStr,"contents");
            Plug _deki = Plug.New( codePage, new TimeSpan(0,0,15) );
            string bodyText = _deki.With("format", "xhtml").Get().ToDocument()["body"]["pre"].Contents;

            for ( int i = 0; i < toHTML.GetLength(0); i++ ) {
                bodyText = Regex.Replace( bodyText, toHTML[i,0], toHTML[i,1] );
            }
            //string codeStr = HttpUtility.HtmlDecode( bodyText );
            //XDoc doc = XDocFactory.From( codeStr, MimeType.ANY );
            //response.Return( DreamMessage.Ok( MimeType.TEXT, bodyText ) );

            Assembly scriptCode = CompileCode( bodyText, response );
            if ( scriptCode != null ) {
                XmlDocument outDoc = runScript( scriptCode, aliasStr );
                response.Return( DreamMessage.Ok( MimeType.XML, new XDoc(outDoc) ) );
            }
            yield break;
        }
Exemple #11
0
 public Yield CheckPrologue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.DebugFormat("checking prologue data in Env #{0}", TaskEnv.Current.GetHashCode());
     if(string.IsNullOrEmpty(PrologueData)) {
         throw new Exception("no prologue data in slot");
     }
     if(PrologueData != context.GetState<string>("prologue")) {
         throw new Exception("state from prologue didn't make it to feature");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #12
0
 public Yield CallCoroutine(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("callcoroutine start");
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     context.SetState(ContextVar);
     if(context.GetState<ContextLifeSpan>() == null) {
         throw new Exception("context instance was never set");
     }
     _log.DebugFormat("callcoroutine calling coroutine within Env #{0}", TaskEnv.Current.GetHashCode());
     yield return Coroutine.Invoke(SubCall, new Result());
     var contextVar = context.GetState<ContextLifeSpan>();
     _log.DebugFormat("callcoroutine coroutine returned within Env #{0}", TaskEnv.Current.GetHashCode());
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #13
0
 public Yield CallPlug(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("callplug start");
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     _log.Debug("setting disposable state");
     context.SetState(ContextVar);
     Result<DreamMessage> sub;
     _log.Debug("calling plug");
     yield return sub = Self.At("calledplug").GetAsync();
     _log.Debug("return from plug");
     if(!sub.Value.IsSuccessful) {
         response.Return(sub.Value);
     }
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     _log.Debug("callplug return");
     response.Return(DreamMessage.Ok());
     _log.Debug("callplug end");
     yield break;
 }
 protected Yield Protected(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #15
0
        public void Put_at_directory_path_fails()
        {
            var data = StringUtil.CreateAlphaNumericKey(10);

            _s3ClientMock.Setup(x => x.PutFile("foo/bar/", It.IsAny <AwsS3FileHandle>())).Throws(new Exception("bad puppy")).AtMostOnce().Verifiable();
            var response = _storage.AtLocalHost.At("foo", "bar").WithTrailingSlash().Put(DreamMessage.Ok(MimeType.TEXT, data), new Result <DreamMessage>()).Wait();

            Assert.IsFalse(response.IsSuccessful);
            _s3ClientMock.VerifyAll();
        }
        public void TestPostDeltas()
        {
            //Assumptions:
            // Role 'Contributor' exists
            // Role 'Viewer' exists
            //Actions:
            // Create User1, User2 and User3
            // User1 is contributor, User2 is contributor on /A/B*
            // User3 is a viewer on A* (grant added)
            //Expected result:
            // User3 is viewer on /A*
            // User1 and user2 are contributors on /A/B*

            Plug p = Utils.BuildPlugForAdmin();

            string baseTreePath = PageUtils.BuildPageTree(p);

            string       userid1 = null;
            DreamMessage msg     = UserUtils.CreateRandomContributor(p, out userid1);

            string userid2 = null;

            msg = UserUtils.CreateRandomContributor(p, out userid2);

            string userid3 = null;

            msg = UserUtils.CreateRandomContributor(p, out userid3);

            XDoc securityDoc = new XDoc("security")
                               .Start("permissions.page")
                               .Elem("restriction", "Private")
                               .End()
                               .Start("grants")
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("user").Attr("id", userid1).End()
                               .End()
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("user").Attr("id", userid2).End()
                               .End()
                               .End();

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B"), "security").
                  WithQuery("cascade=absolute").Put(securityDoc);
            Assert.AreEqual(DreamStatus.Ok, msg.Status);

            securityDoc = new XDoc("security")
                          .Start("permissions.page")
                          .Elem("restriction", "Private")
                          .End()
                          .Start("grants.added")
                          .Start("grant")
                          .Start("permissions")
                          .Elem("role", "Viewer")
                          .End()
                          .Start("user").Attr("id", userid3).End()
                          .End()
                          .End();

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").
                  WithQuery("cascade=delta").Post(securityDoc);
            Assert.AreEqual(DreamStatus.Ok, msg.Status);

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").Get();
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid3)].Contents, "Viewer");

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B/C"), "security").Get();
            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid1)].Contents, "Contributor");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid2)].Contents, "Contributor");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid3)].Contents, "Viewer");
        }
 protected Yield Protected(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #18
0
 public Yield Exception(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("in exception feature");
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(ContextVar);
     throw new CustomException();
 }
Exemple #19
0
 private Yield Epilogue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("in epilogue");
     if(request.IsSuccessful && "disposal".EqualsInvariant(context.Feature.Signature) && context.IsTaskEnvDisposed) {
         throw new Exception("context disposed in epilogue");
     }
     if("prologueepilogue".EqualsInvariant(context.Feature.Signature)) {
         _log.DebugFormat("checking prologue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if(string.IsNullOrEmpty(PrologueData)) {
             throw new Exception("no prologue data in slot");
         }
         if(PrologueData != context.GetState<string>("prologue")) {
             throw new Exception("state from prologue didn't make it to epilogue");
         }
     } else if("epilogue".EqualsInvariant(context.Feature.Signature)) {
         _log.DebugFormat("checking epilogue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if(string.IsNullOrEmpty(EpilogueData)) {
             throw new Exception("no epilogue data in slot");
         }
         if(EpilogueData != context.GetState<string>("epilogue")) {
             throw new Exception("state from feature didn't make it to epilogue");
         }
     }
     response.Return(request);
     yield break;
 }
        public void Can_put_file_with_expiration()
        {
            var data = StringUtil.CreateAlphaNumericKey(10);

            _s3ClientMock.Setup(x => x.PutFile(_storageRoot + "/foo/bar", It.Is <AwsS3FileHandle>(y => y.ValidateFileHandle(data, 10.Seconds())))).AtMostOnce().Verifiable();
            var response = _mockService.CallStorage(storage =>
                                                    storage.At("foo", "bar").With("ttl", 10).Put(DreamMessage.Ok(MimeType.TEXT, data), new Result <DreamMessage>())
                                                    );

            Assert.IsTrue(response.IsSuccessful);
            _s3ClientMock.VerifyAll();
        }
Exemple #21
0
 public DreamMessage PostPrintHandler(DreamContext context, DreamMessage message)
 {
     return(DreamMessage.NotImplemented("missing"));
 }
        public void NewPagesMovedPagesWrongRestrictions()
        {
            //Assumptions:
            //  Role 'Contributor' exist
            //Actions:
            //  Create user user1 with "Contributor" role
            //  Create user user2 with "Contributor" role
            //  Create page page1
            //  Set page1 restriction as private
            //  Set grant to page1 for user1
            //  Set page2 restriction as private
            //  Set grant to page2 for user2
            //  Move page page2 to page1
            //Expected result:
            //  List of grants didn't change for page2

            Plug p = Utils.BuildPlugForAdmin();

            string       userid1 = null;
            DreamMessage msg     = UserUtils.CreateRandomContributor(p, out userid1);

            string pageid1   = null;
            string pagename1 = null;

            msg = PageUtils.CreateRandomPage(p, out pageid1, out pagename1);

            XDoc securityDoc = new XDoc("security")
                               .Start("permissions.page")
                               .Elem("restriction", "Private")
                               .End()
                               .Start("grants")
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("user").Attr("id", userid1).End()
                               .End()
                               .End();

            msg = p.At("pages", pageid1, "security").Put(securityDoc);
            Assert.IsTrue(msg.IsSuccessful, "Failed to set page to private");

            string userid2 = null;

            msg = UserUtils.CreateRandomContributor(p, out userid2);

            string pageid2   = null;
            string pagename2 = null;

            msg = PageUtils.CreateRandomPage(p, out pageid2, out pagename2);

            securityDoc = new XDoc("security")
                          .Start("permissions.page")
                          .Elem("restriction", "Private")
                          .End()
                          .Start("grants")
                          .Start("grant")
                          .Start("permissions")
                          .Elem("role", "Contributor")
                          .End()
                          .Start("user").Attr("id", userid2).End()
                          .End()
                          .End();

            msg = p.At("pages", pageid2, "security").Put(securityDoc);
            Assert.IsTrue(msg.IsSuccessful, "Failed to set page to private");

            msg = PageUtils.MovePage(p, pagename2, pagename1 + "/" + pagename2);

            msg = p.At("pages", pageid2, "security").Get();
            Assert.IsTrue(msg.IsSuccessful);

            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid2)].Contents, "Contributor");
            Assert.IsTrue(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid1)].IsEmpty);
        }
        public void FailedPermissionChangeWhenPartOfMultipleGroups()
        {
            //Assumptions:
            //  Role 'Contributor' exist
            //Actions:
            //  Create user user1 with "Contributor" role
            //  Create group group1 with "Contributor" role
            //  Create group group2 with "Contributor" role
            //  Assing user1 with group1 and group2
            //  Create new page
            //  Set page restriction as private
            //  Set grant to page for user1, group1 and group2
            //  Login as user1
            //  Remove group2 from list of grants
            //Expected result:
            //  List of grants doesn't content group2

            Plug p = Utils.BuildPlugForAdmin();

            string       userid   = null;
            string       username = null;
            DreamMessage msg      = UserUtils.CreateRandomContributor(p, out userid, out username);

            string groupid1 = null;

            msg = UserUtils.CreateRandomGroup(p, new string[] { userid }, out groupid1);

            string groupid2 = null;

            msg = UserUtils.CreateRandomGroup(p, new string[] { userid }, out groupid2);

            string pageid = null;

            msg = PageUtils.CreateRandomPage(p, out pageid);

            XDoc securityDoc = new XDoc("security")
                               .Start("permissions.page")
                               .Elem("restriction", "Private")
                               .End()
                               .Start("grants")
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("user").Attr("id", userid).End()
                               .End()
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("group").Attr("id", groupid1).End()
                               .End()
                               .Start("grant")
                               .Start("permissions")
                               .Elem("role", "Contributor")
                               .End()
                               .Start("group").Attr("id", groupid2).End()
                               .End()
                               .End();

            msg = p.At("pages", pageid, "security").Put(securityDoc);
            Assert.IsTrue(msg.IsSuccessful, "Failed to set page to private");

            p = Utils.BuildPlugForUser(username);

            securityDoc = new XDoc("security")
                          .Start("permissions.page")
                          .Elem("restriction", "Private")
                          .End()
                          .Start("grants.removed")
                          .Start("grant")
                          .Start("permissions")
                          .Elem("role", "Contributor")
                          .End()
                          .Start("group").Attr("id", groupid2).End()
                          .End()
                          .End();

            msg = p.At("pages", pageid, "security").Post(securityDoc);
            Assert.IsTrue(msg.IsSuccessful, "Failed to set page to private");

            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid)].Contents, "Contributor");
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[group/@id=\"{0}\"]/permissions/role", groupid1)].Contents, "Contributor");
            Assert.IsTrue(msg.ToDocument()[string.Format("grants/grant[group/@id=\"{0}\"]/permissions/role", groupid2)].IsEmpty);
        }
        public void TestCascadingWithSkipIfUnableToSet()
        {
            //Assumptions:
            //Actions:
            //  Create user with "Contributor" role
            //  Admin sets restriction:private on A/B
            //  User adds grant for self viewer on A/*
            //  User sets grant for self viewer on A/*
            //Expected result:
            //  User is viewer on A, A/B/C, A/B/D, A/E but no change on A/B

            Plug p = Utils.BuildPlugForAdmin();

            string baseTreePath = PageUtils.BuildPageTree(p);

            string       userid   = null;
            string       username = null;
            DreamMessage msg      = UserUtils.CreateRandomContributor(p, out userid, out username);

            XDoc securityDoc = new XDoc("security")
                               .Start("permissions.page")
                               .Elem("restriction", "Private")
                               .End();

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B"), "security").
                  WithQuery("cascade=none").Put(securityDoc);
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "restrict /A/B to private");

            p = Utils.BuildPlugForUser(username, "password");

            securityDoc = new XDoc("security")
                          .Start("grants.added")
                          .Start("grant")
                          .Start("permissions")
                          .Elem("role", "Viewer")
                          .End()
                          .Start("user").Attr("id", userid).End()
                          .End()
                          .End();

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").
                  WithQuery("cascade=delta").Post(securityDoc);
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "grant viewer on /A/*");

            p = Utils.BuildPlugForAdmin(); // relogin as admin

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").Get();
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid)].Contents, "Viewer", "confirm viewer grant on /A");

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B"), "security").Get();
            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private", "confirm private restriction on /A/B");
            Assert.AreEqual(msg.ToDocument()["grants/grant[2]"].IsEmpty, true, "confirm single grant on /A/B");

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B/C"), "security").Get();
            var doc = msg.ToDocument();

            Assert.AreEqual(doc[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid)].Contents, "Viewer", "confirm viewer grant on /A/B/C");
            Assert.AreEqual(string.IsNullOrEmpty(doc["permissions.page/operations"].AsText), true, "confirm no available operations on /A/B/C");

            p = Utils.BuildPlugForUser(username, "password"); // relogin as user

            securityDoc = new XDoc("security")
                          .Start("permissions.page")
                          .Elem("restriction", "Private")
                          .End()
                          .Start("grants")
                          .Start("grant")
                          .Start("permissions")
                          .Elem("role", "Contributor")
                          .End()
                          .Start("user").Attr("id", userid).End()
                          .End()
                          .End();

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").
                  WithQuery("cascade=absolute").Put(securityDoc);
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "grant contributor on /A/*");

            p = Utils.BuildPlugForAdmin(); // relogin as admin

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A"), "security").Get();
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid)].Contents, "Contributor", "confirm contributor grant on /A");

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B"), "security").Get();
            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private", "reconfirm private restriction on /A/B");
            Assert.AreEqual(msg.ToDocument()["grants/grant[2]"].IsEmpty, true, "reconfirm single grant on /A/B");

            msg = p.At("pages", "=" + XUri.DoubleEncode(baseTreePath + "/A/B/C"), "security").Get();
            Assert.AreEqual(msg.ToDocument()[string.Format("grants/grant[user/@id=\"{0}\"]/permissions/role", userid)].Contents, "Contributor", "confirm contributor grant on /A/B/C");
            Assert.AreEqual(msg.ToDocument()["permissions.page/restriction"].Contents, "Private", "confirm private restriction on /A/B/C");
        }
Exemple #25
0
 public Yield PrologueEpilogue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #26
0
 public Yield ContainerScope(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     ServiceScope[Self.Uri.Path] = context.Container.Resolve <ILifetimeTest>();
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #27
0
            public Yield TestCreateForCrossService(DreamContext context, DreamMessage request, Result<DreamMessage> response)
            {
                string filename = Path.GetTempFileName();
                using(Stream s = File.OpenWrite(filename)) {
                    byte[] data = Encoding.UTF8.GetBytes(TEST_CONTENTS);
                    s.Write(data, 0, data.Length);
                }
                _log.Debug("created file");

                // derive shared storage path
                Plug sharedStorage = Plug.New(Storage.Uri.WithoutLastSegment().At(TEST_SHARED_PATH));
                _log.DebugFormat("shared storage: {0}", sharedStorage.Uri);

                // add a file
                sharedStorage.AtPath(TEST_FILE_URI).Put(DreamMessage.FromFile(filename, false));
                File.Delete(filename);
                _log.Debug("put file");

                // get file and compare contents
                string contents = sharedStorage.AtPath(TEST_FILE_URI).Get().ToText();
                Assert.AreEqual(TEST_CONTENTS, contents);
                _log.Debug("got file");
                response.Return(DreamMessage.Ok());
                yield break;
            }
 public Yield Public(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #29
0
        public Yield TestCreateTtlExpire(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            // add a file
            Storage.AtPath(TEST_FILE_URI).With("ttl", "2").Put(DreamMessage.Ok(MimeType.TEXT, TEST_CONTENTS));
            _log.DebugFormat("File stored at: {0}", DateTime.UtcNow);

            // get file and compare contents
            string contents = Storage.AtPath(TEST_FILE_URI).Get().ToText();
            Assert.AreEqual(TEST_CONTENTS, contents);
            _log.DebugFormat("check file at: {0}", DateTime.UtcNow);
            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(4));

            // get file and compare contents
            _log.DebugFormat("Checking for expired file at: {0}", DateTime.UtcNow);
            DreamMessage getResponse = Storage.AtPath(TEST_FILE_URI).GetAsync().Wait();
            Assert.AreEqual(DreamStatus.NotFound, getResponse.Status);

            response.Return(DreamMessage.Ok());
            yield break;
        }
Exemple #30
0
        /// <summary>
        /// Get a user out of an authtoken from a request if it's valid.
        /// </summary>
        /// <returns></returns>
        private static UserBE UserFromAuthTokenInRequest(DreamContext context, bool impersonationOnly)
        {
            DreamMessage request   = context.Request;
            string       authToken = context.Uri.GetParam(DekiWikiService.AUTHTOKEN_URIPARAM, null);
            UserBE       user      = null;

            // Check if auth token is in a cookie
            if ((authToken == null) && request.HasCookies)
            {
                DreamCookie authCookie = DreamCookie.GetCookie(request.Cookies, DekiWikiService.AUTHTOKEN_COOKIENAME);
                if ((authCookie != null) && (!authCookie.Expired))
                {
                    authToken = authCookie.Value;
                }
            }

            // Check if auth token is in a header or passed in as query parameter
            authToken = authToken ?? request.Headers[DekiWikiService.AUTHTOKEN_HEADERNAME];

            // Extract user name from auth token if it's valid
            if (authToken != null)
            {
                user = ValidateAuthToken(authToken, impersonationOnly);

                // check whether licensestate prevents user from being authenticated
                var license = DekiContext.Current.LicenseManager;
                LicenseStateType licensestate = license.LicenseState;
                if ((licensestate == LicenseStateType.EXPIRED || licensestate == LicenseStateType.INVALID || licensestate == LicenseStateType.INACTIVE) &&
                    !PermissionsBL.IsUserAllowed(user, Permissions.ADMIN)
                    )
                {
                    if (DekiContext.Current.Instance.Log.IsWarnEnabled)
                    {
                        switch (licensestate)
                        {
                        case LicenseStateType.EXPIRED:
                            DekiContext.Current.Instance.Log.WarnFormat("UserFromAuthTokenInRequest: Expired license {0}, reverting non-admin user to anonymous", license.LicenseExpiration);
                            break;

                        case LicenseStateType.INVALID:
                            DekiContext.Current.Instance.Log.WarnFormat("UserFromAuthTokenInRequest: Invalid license, reverting non-admin user to anonymous");
                            break;

                        case LicenseStateType.INACTIVE:
                            DekiContext.Current.Instance.Log.WarnFormat("UserFromAuthTokenInRequest: Inactive license, reverting non-admin user to anonymous");
                            break;
                        }
                    }
                    user = null;
                }
                else
                {
                    DekiContext.Current.AuthToken = authToken;
                }
            }
            if (PermissionsBL.ValidateRequestApiKey())
            {
                uint userIdOverride = 0;
                if (uint.TryParse(context.GetParam(DekiWikiService.IMPERSONATE_USER_QUERYNAME, null), out userIdOverride))
                {
                    UserBE userOverride = UserBL.GetUserById(userIdOverride);
                    if (userOverride != null)
                    {
                        user = userOverride;
                        DekiContext.Current.Instance.Log.InfoFormat("APIKEY provided. Impersonating user id '{0}': {1}", user.ID, user.Name);
                    }
                }
            }
            return(user);
        }
Exemple #31
0
 public Yield Scope(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     Scoped = context.Container.Resolve <IFoo>();
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #32
0
        //--- Class Methods ---
        public static UserBE Authenticate(DreamContext context, DreamMessage request, uint serviceId, bool autoCreateExternalUser, bool allowAnon, out bool altPassword)
        {
            UserBE user = null;

            altPassword = false;

            // Case 1: username/fullname, password, provider (login window)
            //      1. Validate & retrieve fullname using credentials
            //          Failed -> return null
            //      2. Populate user object
            //          A. Populates user info
            //          B. Populates group info in user object
            //      3. Does fullname exist?
            //          Yes -> Update user (email, fullname, ...)
            //          No  -> Create user
            //      4. Update Group information
            //      5. return user object
            //
            // Case 2: fullname, password (http, api, ...)
            //      1. Lookup full name, exist?
            //          Yes -> return user
            //          No -> return null
            //
            // Case 3: auth-token (header auth)
            //      0. Valid auth token?
            //          No -> return null
            //      1. Lookup user by name
            //          Found -> return user
            //          Else  -> return null

            string    userName      = null;
            string    password      = null;
            UserBE    userFromToken = null;
            ServiceBE authService   = null;

            // Extract authtoken and impersonation authtoken from request.
            // AllowAnon is false when in GET/POST: users/authenticate or when ?authenticate=true.
            // Standard user authtokens are ignored when AllowAnon=false but impersonation tokens are accepted.
            bool impersonationOnly = !allowAnon;

            userFromToken = UserFromAuthTokenInRequest(context, impersonationOnly);

            if (userFromToken == null)
            {
                HttpUtil.GetAuthentication(context.Uri.ToUri(), request.Headers, out userName, out password);
            }

            // check if we need to retrieve authentication service information
            if (serviceId > 0)
            {
                authService = ServiceBL.GetServiceById(serviceId);
                if (authService == null)
                {
                    throw new AuthServiceIdInvalidArgumentException(serviceId);
                }
                if (authService.Type != ServiceType.AUTH)
                {
                    throw new AuthNotAnAuthServiceInvalidArgumentException(serviceId);
                }
            }

            // check if a username was provided
            if (!string.IsNullOrEmpty(userName))
            {
                //Case 2: Given username + password
                if (authService == null)
                {
                    //Assuming local user or existing external account
                    user = DbUtils.CurrentSession.Users_GetByName(userName);
                    if (user != null)
                    {
                        serviceId   = user.ServiceId;
                        authService = ServiceBL.GetServiceById(serviceId);
                    }
                    else
                    {
                        LoginAccessDenied(context, request, userName, null, password);
                    }
                }
                if (authService == null)
                {
                    throw new AuthServiceIdInvalidArgumentException(serviceId);
                }
                if (authService.Type != ServiceType.AUTH)
                {
                    throw new AuthNotAnAuthServiceInvalidArgumentException(serviceId);
                }
                if (user == null)
                {
                    //Performing auth on local account
                    if (ServiceBL.IsLocalAuthService(authService))
                    {
                        user = DbUtils.CurrentSession.Users_GetByName(userName);
                    }
                    else
                    {
                        //Performing external auth. Lookup by external user name
                        user = DbUtils.CurrentSession.Users_GetByExternalName(userName, authService.Id);
                    }
                    if (user != null && user.ServiceId != authService.Id)
                    {
                        ServiceBE currentUsersAuthService = ServiceBL.GetServiceById(user.ServiceId);
                        if (currentUsersAuthService != null)
                        {
                            throw new AuthLoginExternalUserConflictException(currentUsersAuthService.Description);
                        }
                        throw new LoginExternalUserUnknownConflictException();
                    }
                }

                //Local account in the db.
                if (user != null && ServiceBL.IsLocalAuthService(authService))
                {
                    //Validate password for local account or validate the apikey
                    if (!IsValidAuthenticationForLocalUser(user, password, out altPassword))
                    {
                        // try impersonation using the ApiKey
                        if (string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey())
                        {
                            DekiContext.Current.Instance.Log.InfoFormat("user '{0}' authenticated via apikey impersonation", userName);
                        }
                        else
                        {
                            LoginAccessDenied(context, request, userName, user.ID, password);
                        }
                    }
                }

                // User was not found in the db and not being asked to create it.
                if (user == null && !autoCreateExternalUser)
                {
                    LoginAccessDenied(context, request, userName, null, password);
                }

                // Creating local account if apikey checks out and our authservice is local
                if (user == null && string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey() && ServiceBL.IsLocalAuthService(authService))
                {
                    XDoc newUserDoc = new XDoc("user")
                                      .Elem("username", userName);
                    DreamMessage newUserResponse = DekiContext.Current.ApiPlug.At("users")
                                                   .With("apikey", DreamContext.Current.GetParam("apikey", string.Empty))
                                                   .Post(newUserDoc);
                    user = UserBL.GetUserById(newUserResponse.ToDocument()["/user/@id"].AsUInt ?? 0);
                    if (user != null && !string.IsNullOrEmpty(password))
                    {
                        user = UserBL.SetPassword(user, password, false);
                    }
                }

                // Got an external account
                // Passing in the user object from db if it was found.
                List <GroupBE> externalGroups = null;
                if (!ServiceBL.IsLocalAuthService(authService))
                {
                    bool   bypassAuthentication = false;
                    string externalName;
                    if (user == null || string.IsNullOrEmpty(user.ExternalName))
                    {
                        externalName = userName;
                    }
                    else
                    {
                        externalName = user.ExternalName;
                    }

                    // If apikey is valid, try to bypass auth with the external provider
                    // and only lookup user/group details.
                    if (string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey())
                    {
                        DekiContext.Current.Instance.Log.InfoFormat("user '{0}' authenticating being bypassed via apikey impersonation", userName);
                        bypassAuthentication = true;
                    }

                    user = ExternalServiceSA.BuildUserFromAuthService(authService, user, userName, bypassAuthentication, externalName, password, out externalGroups);
                }

                // User was not found or did not authenticate with external provider
                if (user == null)
                {
                    LoginAccessDenied(context, request, userName, null, password);
                }
                else
                {
                    //New user creation from external provider
                    if (user.ID == 0)
                    {
                        if (!autoCreateExternalUser)
                        {
                            LoginAccessDenied(context, request, userName, null, password);
                        }
                    }
                    else
                    {
                        //user exists
                        // TODO (steveb): ???
                    }
                    if (user.UserActive)
                    {
                        user = UserBL.CreateOrUpdateUser(user);
                        if (externalGroups != null)
                        {
                            UserBL.UpdateUsersGroups(user, externalGroups.ToArray());
                        }
                    }
                }
            }
            else if (userFromToken != null)
            {
                // valid token exists that resolved to a user
                user = userFromToken;
            }
            else if (allowAnon)
            {
                // Anonymous user
                user = DbUtils.CurrentSession.Users_GetByName(DekiWikiService.ANON_USERNAME);
            }
            if (user == null)
            {
                //No credentials. Or token not provided or is invalid.
                LoginAccessDenied(context, request, null, null, password);
            }
            else if (!user.UserActive && !PermissionsBL.ValidateRequestApiKey())
            {
                //If a valid api key is provided, override the disabled account flag
                throw new AuthUserDisabledForbiddenException(user.Name);
            }
            return(user);
        }
 private Yield Private(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
        public Yield GetPageComments(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            CheckResponseCache(context, false);

            PageBE page = PageBL_AuthorizePage(context, null, Permissions.READ, false);
            uint   count, offset;

            string        filterStr = context.GetParam("filter", "nondeleted");
            CommentFilter filter;

            switch (filterStr.ToLowerInvariant())
            {
            case "any":
                filter = CommentFilter.ANY;
                break;

            case "nondeleted":
                filter = CommentFilter.NONDELETED;
                break;

            default:
                throw new CommentFilterInvalidArgumentException();
            }
            bool   includeDescendantPages = false;
            string depth = context.GetParam("depth", "0");

            switch (depth.ToLowerInvariant())
            {
            case "0":
                includeDescendantPages = false;
                break;

            case "infinity":
                includeDescendantPages = true;
                break;

            default:
                throw new DreamBadRequestException(string.Format("Invalid depth value '{0}'. Supported values are '0' and 'infinity'.", depth));
            }

            uint postedByUserIdtmp = context.GetParam <uint>("postedbyuserid", 0);
            uint?postedByUserId    = null;

            if (postedByUserIdtmp > 0)
            {
                postedByUserId = postedByUserIdtmp;
            }

            SortDirection sortDir;
            string        sortField;

            Utils.GetOffsetAndCountFromRequest(context, 100, out count, out offset, out sortDir, out sortField);
            sortDir = sortDir == SortDirection.UNDEFINED ? SortDirection.ASC : sortDir; // default sort is ascending by timestamp
            uint totalCount;
            XUri commentsUri           = DekiContext.Current.ApiUri.At("pages", page.ID.ToString(), "comments");
            IList <CommentBE> comments = CommentBL.RetrieveCommentsForPage(page, filter, includeDescendantPages, postedByUserId, sortDir, offset, count, out totalCount);

            XDoc     ret = null;
            MimeType mimetype;

            switch (context.GetParam("format", "xml").ToLowerInvariant())
            {
            case "xml":
                ret      = CommentBL.GetCommentXml(comments, true, null, includeDescendantPages, offset, sortDir, null, commentsUri, totalCount);
                mimetype = MimeType.XML;
                break;

            case "atom":
                ret      = CommentBL.GetCommentXmlAsAtom(comments, context.Uri, page);
                mimetype = MimeType.ATOM;
                break;

            default:
                throw new DreamBadRequestException("Invalid format. Valid formats are 'xml' and 'atom'.");
            }

            response.Return(DreamMessage.Ok(mimetype, ret));
            yield break;
        }
 internal Yield Internal(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #36
0
        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;
        }
 internal Yield Internal(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #38
0
 public Result <AwsSqsSendResponse> Send(string queue, AwsSqsMessage message, Result <AwsSqsSendResponse> result)
 {
     try {
         var msgQueue = GetQueue(queue);
         ThrowIfQueueIsNull(msgQueue);
         if (msgQueue == null)
         {
             throw new AwsSqsRequestException("AWS.SimpleQueueService.NonExistentQueue", DreamMessage.InternalError());
         }
         var enqueued = new QueueEntry(message, queue);
         lock (msgQueue) {
             msgQueue.Add(enqueued);
         }
         _messageCounter++;
         result.Return(new SendResponse(enqueued.Message));
         return(result);
     } catch (Exception e) {
         result.Throw(e);
         return(result);
     }
 }
 private Yield Private(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     response.Return(DreamMessage.Ok());
     yield break;
 }
Exemple #40
0
        private void MoveGroups()
        {
            DreamMessage msg = _dekiPlug.At("groups").With("limit", int.MaxValue).GetAsync().Wait();

            if (msg.Status != DreamStatus.Ok)
            {
                WriteLineToConsole("Error while receiving groups from Deki. Groups not converted.");
                WriteErrorResponse(msg);
                return;
            }

            Dictionary <string, string> dekiGroups = new Dictionary <string, string>();

            XDoc groupsDoc = msg.AsDocument();

            foreach (XDoc groupDoc in groupsDoc["//group"])
            {
                string dekiGroupName = groupDoc["groupname"].AsText;
                dekiGroups[dekiGroupName.ToLower()] = null;
            }

            string[] confluenceGroupNames = _confluenceService.GetGroups();

            foreach (string confluenceGroupName in confluenceGroupNames)
            {
                string dekiGroupName;
                if (!_convertedGroups.ContainsKey(confluenceGroupName.ToLower()))
                {
                    int groupNum = 0;
                    dekiGroupName = confluenceGroupName;
                    while (dekiGroups.ContainsKey(dekiGroupName.ToLower()))
                    {
                        groupNum++;
                        dekiGroupName = confluenceGroupName + groupNum.ToString();
                    }
                    if (dekiGroupName != confluenceGroupName)
                    {
                        WriteLineToConsole("Confluence group \"" + confluenceGroupName + "\" converted as \"" + dekiGroupName + "\" becouse of existing same group in Deki");
                    }

                    XDoc newGroupDoc = new XDoc("group");
                    newGroupDoc.Elem("name", dekiGroupName)
                    .Start("users");

                    foreach (ACConverterUserInfo convertedUser in _convertedUsers.Values)
                    {
                        if (Array.IndexOf(convertedUser.ConfluenceUserGroupNames, confluenceGroupName) >= 0)
                        {
                            newGroupDoc.Start("user").Attr("id", convertedUser.DekiUserId).End();
                        }
                    }

                    newGroupDoc.End();

                    Log.DebugFormat("Creating group: {0}", dekiGroupName);

                    DreamMessage res = _dekiPlug.At("groups").PostAsync(newGroupDoc).Wait();
                    if (res.Status != DreamStatus.Ok)
                    {
                        WriteLineToLog("Error converting group \"" + confluenceGroupName + "\"");
                        WriteErrorResponse(res);
                        WriteErrorRequest(newGroupDoc);
                        continue;
                    }

                    XDoc resGroupsDoc   = res.AsDocument();
                    int  newDekiGroupId = resGroupsDoc["@id"].AsInt.Value;

                    ACConverterGroupInfo convertedGroup =
                        new ACConverterGroupInfo(confluenceGroupName, dekiGroupName, newDekiGroupId);
                    _convertedGroups[confluenceGroupName.ToLower()] = convertedGroup;
                }
                else
                {
                    //This group already converted during previous ACConverter start
                    dekiGroupName = _convertedGroups[confluenceGroupName.ToLower()].DekiGroupName;

                    XDoc usersDoc = new XDoc("users");
                    foreach (ACConverterUserInfo convertedUser in _convertedUsers.Values)
                    {
                        if (Array.IndexOf(convertedUser.ConfluenceUserGroupNames, confluenceGroupName) >= 0)
                        {
                            usersDoc.Start("user").Attr("id", convertedUser.DekiUserId).End();
                        }
                    }
                    DreamMessage res = _dekiPlug.At("groups", _convertedGroups[confluenceGroupName.ToLower()].DekiGroupId.ToString(),
                                                    "users").PutAsync(usersDoc).Wait();
                    if (res.Status != DreamStatus.Ok)
                    {
                        WriteLineToLog("Error converting group's users");
                        WriteErrorResponse(res);
                        WriteErrorRequest(usersDoc);
                    }
                }
            }
        }
 public Yield GetImage(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     yield return(context.Relay(Storage.At(context.GetParam("name")), request, response));
 }
        public Yield ValidateOpenIdResponse(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            XUri publicUri = new XUri(context.GetParam("url", null));
            NameValueCollection queryColl = System.Web.HttpUtility.ParseQueryString(context.GetParam("query", null));

            // process the response, including validating the endpoint of the claimed identifier.
            OpenIdRelyingParty openid = new OpenIdRelyingParty(null, publicUri, queryColl);
            var openIdResponse        = openid.Response;

            if (openIdResponse != null)
            {
                switch (openIdResponse.Status)
                {
                case AuthenticationStatus.Authenticated:

                    // Throw an exception if there is a regex for acceptable
                    // identifiers defined, and the ID does not match.
                    if (!String.IsNullOrEmpty(_validIdPattern))
                    {
                        Regex identifierAccept = new Regex(_validIdPattern);
                        if (!identifierAccept.IsMatch(openIdResponse.ClaimedIdentifier))
                        {
                            _log.InfoFormat("Identifier {0} denied access by valid-id-pattern regular expression {1}", openIdResponse.ClaimedIdentifier, _validIdPattern);
                            throw new DreamBadRequestException("This service is configured to deny access to this OpenID identifier.");
                        }
                    }

                    var claimsResponse = openIdResponse.GetExtension <ClaimsResponse>();
                    var fetchResponse  = openIdResponse.GetExtension <FetchResponse>();

                    XDoc result = new XDoc("openid");
                    result.Attr("validated", true);
                    result.Elem("identifier", openIdResponse.ClaimedIdentifier);

                    // SREG response
                    if (claimsResponse != null)
                    {
                        string email = claimsResponse.Email;
                        if (email != null)
                        {
                            result.Elem("email", email);
                            _log.DebugFormat("E-mail address from SREG: {0}", email);
                        }
                    }
                    // AX response
                    if (fetchResponse != null)
                    {
                        foreach (AttributeValues v in fetchResponse.Attributes)
                        {
                            if (v.TypeUri == WellKnownAttributes.Contact.Email)
                            {
                                IList <string> emailAddresses = v.Values;
                                string         email          = emailAddresses.Count > 0 ? emailAddresses[0] : null;
                                result.Elem("email", email);
                                _log.DebugFormat("E-mail address from AX: {0}", email);
                            }
                        }
                    }
                    response.Return(DreamMessage.Ok(result));
                    break;

                case AuthenticationStatus.Canceled:
                    _log.InfoFormat("Authentication was cancelled by the user.");
                    throw new DreamBadRequestException("Authentication was cancelled by the user.");

                case AuthenticationStatus.Failed:
                    _log.InfoFormat("Authentication failed: " + openIdResponse.Exception.Message);
                    throw new DreamBadRequestException("Authentication failed: " + openIdResponse.Exception.Message);

                default:
                    _log.WarnFormat("Authentication error: " + openIdResponse.Exception.Message);
                    throw new DreamBadRequestException("Authentication error: " + openIdResponse.Exception.Message);
                }
            }
            else
            {
                _log.Warn("OpenID response was null");
                throw new DreamBadRequestException("No OpenID response was returned.");
            }
            yield break;
        }
Exemple #43
0
 public Yield CalledPlug(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("calledplug start");
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar != null) {
         throw new Exception("called plug context instance already exists");
     }
     context.SetState(new ContextLifeSpan(Guid.NewGuid()));
     _log.Debug("calledplug return");
     response.Return(DreamMessage.Ok());
     _log.Debug("calledplug end");
     yield break;
 }
        public Yield UserLogin(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            string userSuppliedIdentifier = context.GetParam("url", null);

            if (String.IsNullOrEmpty(userSuppliedIdentifier))
            {
                _log.Info("No identifier was specified");
                throw new DreamBadRequestException("No identifier was specified.");
            }

            XUri   returnUri = new XUri(context.GetParam("returnurl", null));
            String realm     = context.GetParam("realm", null);

            if (String.IsNullOrEmpty(realm))
            {
                realm = returnUri.WithoutPathQueryFragment().ToString();
            }

            IAuthenticationRequest openIdRequest;

            // dummy parameters required by DotNetOpenId 2.x; in 3.x, you can
            // just pass null to the OpenIdRelyingParty constructor.
            Uri identifierUri            = new Uri(userSuppliedIdentifier);
            NameValueCollection queryCol = System.Web.HttpUtility.ParseQueryString(identifierUri.Query);
            OpenIdRelyingParty  openid   = new OpenIdRelyingParty(null, identifierUri, queryCol);

            // creating an OpenID request will authenticate that
            // the endpoint exists and is an OpenID provider.
            _log.DebugFormat("Creating OpenID request: identifier {0}, return URL {1}, realm {2}", userSuppliedIdentifier, returnUri.ToString(), realm);

            try {
                openIdRequest = openid.CreateRequest(
                    userSuppliedIdentifier,
                    realm,
                    returnUri.ToUri());
            } catch (OpenIdException ex) {
                _log.WarnFormat("'{0}' rejected as OpenID identifier: {1}", userSuppliedIdentifier, ex.Message);
                throw new DreamBadRequestException(string.Format("'{0}' is not a valid OpenID identifier. {1}", userSuppliedIdentifier, ex.Message));
            }

            // Ask for the e-mail address on this request.
            // Use both SREG and AX, to increase the odds of getting it.
            openIdRequest.AddExtension(new ClaimsRequest {
                Email = DemandLevel.Require,
            });

            var fetch = new FetchRequest();

            fetch.AddAttribute(new AttributeRequest(WellKnownAttributes.Contact.Email, true));
            openIdRequest.AddExtension(fetch);

            // The RedirectingResponse either contains a "Location" header for
            // a HTTP GET, which will return in the response as 'endpoint', or
            // a HTML FORM which needs to be displayed to the user, which will
            // return in the response as 'form'.
            IResponse wr = openIdRequest.RedirectingResponse;

            XDoc result = new XDoc("openid");

            if (String.IsNullOrEmpty(wr.Headers["Location"]))
            {
                System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
                string formBody = enc.GetString(wr.Body);
                _log.DebugFormat("OpenID redirect by HTML FORM: {0}", formBody);
                result.Attr("form", formBody);
            }
            else
            {
                string redirectUrl = wr.Headers["Location"];
                _log.DebugFormat("OpenID redirect URL: {0}", redirectUrl);
                result.Attr("endpoint", redirectUrl);
            }

            response.Return(DreamMessage.Ok(result));
            yield break;
        }
Exemple #45
0
 public Yield CheckEpilogue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     EpilogueData = StringUtil.CreateAlphaNumericKey(8);
     _log.DebugFormat("setting epilogue data in Env #{0}", TaskEnv.Current.GetHashCode());
     context.SetState("epilogue", EpilogueData);
     response.Return(DreamMessage.Ok());
     yield break;
 }
        public void TestDeleteWithNoCascadeAndReset()
        {
            // 1. Create page tree
            // 2. Create user with Contributor role
            // (3) Assert all pages have been created
            // 4. Restrict A/B/D as private (user has no delete/update access)
            // 5. Delete /A as user
            // (6) Assert A is reset and the rest of the pages are untouched

            Plug p = Utils.BuildPlugForAdmin();
            string baseTreePath = PageUtils.BuildPageTree(p);
            string contrUserId = null;
            string contrUserName = null;
            DreamMessage msg = UserUtils.CreateRandomContributor(p, out contrUserId, out contrUserName);

            DreamMessage pageAresponse = PageUtils.GetPage(p, baseTreePath + "/A");
            DreamMessage pageABresponse = PageUtils.GetPage(p, baseTreePath + "/A/B");
            DreamMessage pageABCresponse = PageUtils.GetPage(p, baseTreePath + "/A/B/C");
            DreamMessage pageABDresponse = PageUtils.GetPage(p, baseTreePath + "/A/B/D");
            DreamMessage pageAEresponse = PageUtils.GetPage(p, baseTreePath + "/A/E");

            Assert.AreEqual("A", pageAresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("B", pageABresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("C", pageABCresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("D", pageABDresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("E", pageAEresponse.ToDocument()["//title"].Contents);

            int pageA = pageAresponse.ToDocument()["@id"].AsInt.Value;
            int pageAB = pageABresponse.ToDocument()["@id"].AsInt.Value;
            int pageABC = pageABCresponse.ToDocument()["@id"].AsInt.Value;
            int pageABD = pageABDresponse.ToDocument()["@id"].AsInt.Value;
            int pageAE = pageAEresponse.ToDocument()["@id"].AsInt.Value;

            PageUtils.RestrictPage(p, baseTreePath + "/A/B/D", "none", "Private");

            p = Utils.BuildPlugForUser(contrUserName);
            Assert.AreEqual(DreamStatus.Ok, PageUtils.DeletePageByName(p, baseTreePath + "/A", false).Status);

            p = Utils.BuildPlugForAdmin();
            DreamMessage pageAresponse2 = PageUtils.GetPage(p, baseTreePath + "/A");
            DreamMessage pageABresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B");
            DreamMessage pageABCresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B/C");
            DreamMessage pageABDresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B/D");
            DreamMessage pageAEresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/E");

            Assert.AreEqual(DreamStatus.Ok, pageAresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABDresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageAEresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABCresponse2.Status);

            int pageA2 = pageAresponse2.ToDocument()["@id"].AsInt.Value;
            int pageAB2 = pageABresponse2.ToDocument()["@id"].AsInt.Value;
            int pageABC2 = pageABCresponse2.ToDocument()["@id"].AsInt.Value;
            int pageABD2 = pageABDresponse2.ToDocument()["@id"].AsInt.Value;
            int pageAE2 = pageAEresponse2.ToDocument()["@id"].AsInt.Value;

            Assert.AreNotEqual(pageA, pageA2);
            Assert.AreEqual(pageAB, pageAB2);
            Assert.AreEqual(pageABC, pageABC2);
            Assert.AreEqual(pageABD, pageABD2);
            Assert.AreEqual(pageAE, pageAE2);
        }
Exemple #47
0
 public Yield Disposal(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     if(context.IsTaskEnvDisposed) {
         throw new Exception("context disposed in feature");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
        public void TestDeleteWithCascadeOnNoAccessNode()
        {
            // 1. Create page tree
            // 2. Create user with Contributor role
            // (3) Assert all pages have been created
            // 4. Restrict A/B as private (user has no delete/update  4. Restrict A/B as private (user has no delete/update access)
            // 5. Delete /A/B* as user
            // (6) Assert "Forbidden" response returned
            // (7) Assert no changes made

            Plug p = Utils.BuildPlugForAdmin();
            string baseTreePath = PageUtils.BuildPageTree(p);
            string contrUserId = null;
            string contrUserName = null;
            UserUtils.CreateRandomContributor(p, out contrUserId, out contrUserName);

            DreamMessage pageAresponse = PageUtils.GetPage(p, baseTreePath + "/A");
            DreamMessage pageABresponse = PageUtils.GetPage(p, baseTreePath + "/A/B");
            DreamMessage pageABCresponse = PageUtils.GetPage(p, baseTreePath + "/A/B/C");
            DreamMessage pageABDresponse = PageUtils.GetPage(p, baseTreePath + "/A/B/D");
            DreamMessage pageAEresponse = PageUtils.GetPage(p, baseTreePath + "/A/E");

            Assert.AreEqual("A", pageAresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("B", pageABresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("C", pageABCresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("D", pageABDresponse.ToDocument()["//title"].Contents);
            Assert.AreEqual("E", pageAEresponse.ToDocument()["//title"].Contents);

            int pageA = pageAresponse.ToDocument()["@id"].AsInt.Value;
            int pageAB = pageABresponse.ToDocument()["@id"].AsInt.Value;
            int pageABC = pageABCresponse.ToDocument()["@id"].AsInt.Value;
            int pageABD = pageABDresponse.ToDocument()["@id"].AsInt.Value;
            int pageAE = pageAEresponse.ToDocument()["@id"].AsInt.Value;

            PageUtils.RestrictPage(p, baseTreePath + "/A/B", "none", "Private");

            p = Utils.BuildPlugForUser(contrUserName);
            string path = "=" + XUri.DoubleEncode(baseTreePath + "/A/B");
            DreamMessage deleteResponse = p.At("pages", path).WithQuery("recursive=" + "true").DeleteAsync().Wait();
            Assert.AreEqual(DreamStatus.Forbidden, deleteResponse.Status);

            p = Utils.BuildPlugForAdmin();
            DreamMessage pageAresponse2 = PageUtils.GetPage(p, baseTreePath + "/A");
            DreamMessage pageABresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B");
            DreamMessage pageABCresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B/C");
            DreamMessage pageABDresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/B/D");
            DreamMessage pageAEresponse2 = PageUtils.GetPage(p, baseTreePath + "/A/E");

            Assert.AreEqual(DreamStatus.Ok, pageAresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABDresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageAEresponse2.Status);
            Assert.AreEqual(DreamStatus.Ok, pageABCresponse2.Status);

            int pageA2 = pageAresponse2.ToDocument()["/page/@id"].AsInt.Value;
            int pageAB2 = pageABresponse2.ToDocument()["/page/@id"].AsInt.Value;
            int pageABC2 = pageABCresponse2.ToDocument()["/page/@id"].AsInt.Value;
            int pageABD2 = pageABDresponse2.ToDocument()["/page/@id"].AsInt.Value;
            int pageAE2 = pageAEresponse2.ToDocument()["/page/@id"].AsInt.Value;

            Assert.AreEqual(pageA, pageA2);
            Assert.AreEqual(pageAB, pageAB2);
            Assert.AreEqual(pageABC, pageABC2);
            Assert.AreEqual(pageABD, pageABD2);
            Assert.AreEqual(pageAE, pageAE2);
        }
Exemple #49
0
 public Yield Ping(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(ContextVar);
     response.Return(DreamMessage.Ok());
     yield break;
 }
        //--- Methods ---
        void IHttpHandler.ProcessRequest(HttpContext httpContext)
        {
            var          key     = new object();
            DreamMessage request = null;

            try {
                string verb       = httpContext.Request.HttpMethod;
                XUri   requestUri = HttpUtil.FromHttpContext(httpContext);
                _env.AddActivityDescription(key, string.Format("Incoming: {0} {1}", verb, requestUri));
                _log.DebugMethodCall("ProcessRequest", verb, requestUri);

                // create request message
                request = new DreamMessage(DreamStatus.Ok, new DreamHeaders(httpContext.Request.Headers), MimeType.New(httpContext.Request.ContentType), httpContext.Request.ContentLength, httpContext.Request.InputStream);
                DreamUtil.PrepareIncomingMessage(request, httpContext.Request.ContentEncoding, string.Format("{0}://{1}{2}", httpContext.Request.Url.Scheme, httpContext.Request.Url.Authority, httpContext.Request.ApplicationPath), httpContext.Request.UserHostAddress, httpContext.Request.UserAgent);

                // TODO (arnec): should this happen before PrepareIncomingMessage?
                request.Headers.DreamTransport = _handler.GetRequestBaseUri(httpContext.Request).ToString();

                // process message
                var response = _env.SubmitRequestAsync(verb, requestUri, httpContext.User, request, new Result <DreamMessage>(TimeSpan.MaxValue)).Block();
                request.Close();
                var item = response.HasException ? DreamMessage.InternalError(response.Exception) : response.Value;

                // set status
                if (_log.IsDebugEnabled)
                {
                    _log.DebugMethodCall("ProcessRequest[Status]", item.Status, String.Format("{0}{1}", httpContext.Request.Url.GetLeftPart(UriPartial.Authority), httpContext.Request.RawUrl).Replace("/index.aspx", "/"));
                }
                httpContext.Response.StatusCode = (int)item.Status;

                // remove internal headers
                item.Headers.DreamTransport = null;
                item.Headers.DreamPublicUri = null;

                // create stream for response (this will force the creation of the 'Content-Length' header as well)
                Stream stream = item.ToStream();

                // copy headers
                foreach (KeyValuePair <string, string> pair in item.Headers)
                {
                    _log.TraceMethodCall("ProcessRequest[Header]", pair.Key, pair.Value);
                    httpContext.Response.AppendHeader(pair.Key, pair.Value);
                }

                // add set-cookie headers to response
                if (item.HasCookies)
                {
                    foreach (DreamCookie cookie in item.Cookies)
                    {
                        httpContext.Response.AppendHeader(DreamHeaders.SET_COOKIE, cookie.ToSetCookieHeader());
                    }
                }

                // send message stream
                long size = item.ContentLength;
                if (((size == -1) || (size > 0)) && (stream != Stream.Null))
                {
                    stream.CopyTo(httpContext.Response.OutputStream, size, new Result <long>(TimeSpan.MaxValue)).Wait();
                }
                item.Close();
            } catch (Exception ex) {
                _log.ErrorExceptionMethodCall(ex, "CommonRequestHandler");
                if (request != null)
                {
                    request.Close();
                }
                if (httpContext != null)
                {
                    httpContext.Response.Close();
                }
            } finally {
                _env.RemoveActivityDescription(key);
            }
        }
Exemple #51
0
 public Yield Spawn(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     context.SetState(ContextVar);
     ContextLifeSpan capturedInner = null;
     yield return Async.Fork(() =>
     {
         var innerContextVar = DreamContext.Current.GetState<ContextLifeSpan>();
         capturedInner = innerContextVar;
         if(innerContextVar == ContextVar) {
             throw new Exception("spawned context instances were same");
         }
         if(innerContextVar.Guid != guid) {
             throw new Exception("spawned context guid is wrong");
         }
         if(innerContextVar.IsDisposed) {
             throw new Exception("subcall: context is disposed");
         }
     }, new Result());
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(capturedInner == contextVar) {
         throw new Exception("outer instance was changed to inner");
     }
     if(!capturedInner.IsDisposed) {
         throw new Exception("inner instance wasn't disposed after closure completion");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
        public void Contents_TestMerge_CorrectContents()
        {
            // Log in as ADMIN
            Plug p = Utils.BuildPlugForAdmin();

            // Create some content to test merge
            string contentA   = "<p>This is some wonderful content</p><p>I love writing tests</p>";
            string contentB   = "<p>bing bong ping pong</p><p>I love writing tests</p>";
            string contentC   = "<p>This is some wonderful content</p><p>Expect a cool merge right here</p>";
            string contentRes = "<p>bing bong ping pong</p><p>Expect a cool merge right here</p>";

            // Upload contentA to page and save edittime
            string       path = PageUtils.GenerateUniquePageName();
            DreamMessage msg  = p.At("pages", "=" + XUri.DoubleEncode(path), "contents").Post(DreamMessage.Ok(MimeType.TEXT_UTF8, contentA), new Result <DreamMessage>()).Wait();

            Assert.AreEqual(DreamStatus.Ok, msg.Status, "Setting page contents to contentA failed");
            msg = PageUtils.GetPage(p, path);
            string edittime = msg.ToDocument()["date.edited"].AsText;

            Assert.IsNotNull(edittime, "No date.edited in page document!");

            // Have it wait a second
            Wait.For(() => { return(false); }, TimeSpan.FromSeconds(1));

            // Upload content B as Admin
            msg = p.At("pages", "=" + XUri.DoubleEncode(path), "contents").With("edittime", edittime).Post(DreamMessage.Ok(MimeType.TEXT_UTF8, contentB), new Result <DreamMessage>()).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "Setting page contents to contentB failed");

            // Create a user and upload content C as user
            string userid;
            string username;

            UserUtils.CreateRandomContributor(p, out userid, out username);

            // Upload content C as user
            p   = Utils.BuildPlugForUser(username);
            msg = p.At("pages", "=" + XUri.DoubleEncode(path), "contents").With("edittime", edittime).Post(DreamMessage.Ok(MimeType.TEXT_UTF8, contentC), new Result <DreamMessage>()).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "Setting page contents to contentB failed");

            // Retrieve page contents and verify merge
            msg = p.At("pages", "=" + XUri.DoubleEncode(path), "contents").Get(new Result <DreamMessage>()).Wait();
            Assert.AreEqual(contentRes, msg.ToDocument()["body"].AsText ?? String.Empty, "Unexpected contents after merge");
        }
Exemple #53
0
 private Yield Prologue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("in prologue");
     if("disposal".EqualsInvariant(context.Feature.Signature) && context.IsTaskEnvDisposed) {
         throw new Exception("context disposed in prologue");
     }
     PrologueData = StringUtil.CreateAlphaNumericKey(8);
     _log.DebugFormat("setting prologue data in Env #{0}", TaskEnv.Current.GetHashCode());
     context.SetState("prologue", PrologueData);
     response.Return(DreamMessage.Ok());
     yield break;
 }
 public Yield UnLockFile(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     response.Return(new DreamMessage(DreamStatus.NoContent, null));
     yield break;
 }
Exemple #55
0
            public Yield TestCreateRetrieveDelete(DreamContext context, DreamMessage request, Result<DreamMessage> response)
            {
                string filename = Path.GetTempFileName();
                using(Stream s = File.OpenWrite(filename)) {
                    byte[] data = Encoding.UTF8.GetBytes(TEST_CONTENTS);
                    s.Write(data, 0, data.Length);
                }
                _log.Debug("created file");

                // add a file
                _log.DebugFormat("storage path: {0}", Storage.Uri);
                Storage.AtPath(TEST_FILE_URI).Put(DreamMessage.FromFile(filename, false));
                File.Delete(filename);
                _log.Debug("put file");

                // get file and compare contents
                string contents = Storage.AtPath(TEST_FILE_URI).Get().ToText();
                Assert.AreEqual(TEST_CONTENTS, contents);
                _log.Debug("got file");

                // delete file
                Storage.AtPath(TEST_FILE_URI).Delete();
                _log.Debug("deleted file");
                response.Return(DreamMessage.Ok());
                yield break;
            }
        public Yield GetFile(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE       parentPage   = null;
            DreamMessage responseMsg  = null;
            ResourceBE   fileRevision = GetAttachment(context, request, Permissions.READ, true, false, out parentPage);

            if (fileRevision.IsHidden)
            {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            }

            // check if only file information is requested
            if (context.Verb == Verb.HEAD)
            {
                response.Return(new DreamMessage(DreamStatus.Ok, null, fileRevision.MimeType, (long)fileRevision.Size, Stream.Null));
                yield break;
            }
            try {
                if (request.CheckCacheRevalidation(fileRevision.Timestamp))
                {
                    responseMsg = DreamMessage.NotModified();
                }
                if (responseMsg == null)
                {
                    #region Preview related parameter parsing
                    string sFormat    = context.GetParam("format", string.Empty);
                    string sRatio     = context.GetParam("ratio", string.Empty);
                    uint   height     = context.GetParam <uint>("height", 0);
                    uint   width      = context.GetParam <uint>("width", 0);
                    string cachedSize = context.GetParam("size", string.Empty);

                    // check 'ratio' parameter
                    RatioType ratio = RatioType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sRatio))
                    {
                        switch (sRatio.ToLowerInvariant().Trim())
                        {
                        case "var":
                        case "variable":
                            ratio = RatioType.VARIABLE;
                            break;

                        case "fixed":
                            ratio = RatioType.FIXED;
                            break;

                        default:
                            throw new AttachmentFileRatioInvalidArgumentException();
                        }
                    }

                    // check 'size' parameter
                    SizeType size = SizeType.UNDEFINED;
                    if (!string.IsNullOrEmpty(cachedSize) && !SysUtil.TryParseEnum(cachedSize.Trim(), out size))
                    {
                        throw new AttachmentFilesizeInvalidArgumentException();
                    }

                    // check 'format' parameter
                    FormatType format = FormatType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sFormat) && !SysUtil.TryParseEnum(sFormat.Trim(), out format))
                    {
                        throw new AttachmentFileFormatInvalidArgumentException();
                    }
                    #endregion

                    //if any preview related parameters are set, do preview logic. Otherwise return the file
                    StreamInfo file = null;
                    if ((size != SizeType.UNDEFINED && size != SizeType.ORIGINAL) ||
                        ratio != RatioType.UNDEFINED ||
                        format != FormatType.UNDEFINED ||
                        height != 0 ||
                        width != 0
                        )
                    {
                        file = AttachmentPreviewBL.RetrievePreview(fileRevision, height, width, ratio, size, format);
                    }
                    else
                    {
                        var isMSWebDAV = MSWEBDAV_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                        file = DekiContext.Current.Instance.Storage.GetFile(fileRevision, SizeType.ORIGINAL, !isMSWebDAV);
                    }

                    // prepare response
                    if (file == null)
                    {
                        throw new AttachmentDoesNotExistFatalException(fileRevision.ResourceId, fileRevision.Revision);
                    }

                    if (file.Uri != null)
                    {
                        responseMsg = DreamMessage.Redirect(file.Uri);
                    }
                    else
                    {
                        bool inline = fileRevision.MetaXml.ImageHeight.HasValue;

                        // see if we can use the MimeType map for allowing inlining
                        if (!inline)
                        {
                            // if IE inline security is not disabled
                            bool isIE = false;
                            if (!DekiContext.Current.Instance.EnableUnsafeIEContentInlining)
                            {
                                // check the user agent to see if we're dealing with IE
                                isIE = MSIE_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                            }

                            // see if the mime-type could allow inlining
                            inline = DekiContext.Current.Instance.MimeTypeCanBeInlined(fileRevision.MimeType);
                            if (inline && isIE)
                            {
                                // check whether the creator of the file had unsafecontent permission, to override IE security
                                IList <ResourceBE> revisions         = ResourceBL.Instance.GetResourceRevisions(fileRevision.ResourceId, ResourceBE.ChangeOperations.CONTENT, SortDirection.DESC, 1);
                                UserBE             lastContentEditor = UserBL.GetUserById(revisions[0].UserId);
                                inline = PermissionsBL.IsUserAllowed(lastContentEditor, parentPage, Permissions.UNSAFECONTENT);
                            }
                        }
                        responseMsg = DreamMessage.Ok(fileRevision.MimeType, file.Length, file.Stream);
                        responseMsg.Headers["X-Content-Type-Options"] = "nosniff";
                        responseMsg.Headers.ContentDisposition        = new ContentDisposition(inline, fileRevision.Timestamp, null, null, fileRevision.Name, file.Length, request.Headers.UserAgent);

                        // MSIE6 will delete a downloaded file before the helper app trying to use it can get to it so we
                        //have to do custom cache control headers for MSIE6 so that the file can actually be opened
                        if (MSIE6_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty))
                        {
                            responseMsg.Headers["Expires"]   = "0";
                            responseMsg.Headers.Pragma       = "cache";
                            responseMsg.Headers.CacheControl = "private";
                        }
                        else
                        {
                            responseMsg.SetCacheMustRevalidate(fileRevision.Timestamp);
                        }
                    }
                }
            } catch {
                if (responseMsg != null)
                {
                    responseMsg.Close();
                }
                throw;
            }
            response.Return(responseMsg);
            yield break;
        }
Exemple #57
0
        public Yield TestCreateRetrieveHeadDelete(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            string filename = Path.GetTempFileName();
            using(Stream s = File.OpenWrite(filename)) {
                byte[] data = Encoding.UTF8.GetBytes(TEST_CONTENTS);
                s.Write(data, 0, data.Length);
            }
            _log.Debug("created file");

            // add a file
            Storage.AtPath(TEST_FILE_URI).Put(DreamMessage.FromFile(filename, false));
            File.Delete(filename);
            _log.Debug("put file");

            // get file and compare contents
            DreamMessage headResponse = Storage.AtPath(TEST_FILE_URI).Invoke(Verb.HEAD, DreamMessage.Ok());
            Assert.AreEqual(TEST_CONTENTS.Length, headResponse.ContentLength);
            _log.Debug("got content length");

            // delete file
            Storage.AtPath(TEST_FILE_URI).Delete();
            _log.Debug("deleted file");
            response.Return(DreamMessage.Ok());
            yield break;
        }
        //--- Methods ---
        private ResourceBE GetAttachment(DreamContext context, DreamMessage request, Permissions access)
        {
            PageBE p;

            return(GetAttachment(context, request, access, false, false, out p));
        }
Exemple #59
0
 public Yield GetHttp(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     yield return context.Relay(_redirect.At(context.GetSuffixes(UriPathFormat.Original)), request, response);
 }
Exemple #60
0
 public Yield Lifetime(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     LifetimeTest = context.Container.Resolve <ILifetimeTest>() as LifetimeTest;
     response.Return(DreamMessage.Ok());
     yield break;
 }