示例#1
0
        internal static string EncodeUriCharacters(string text)
        {
            StringBuilder result = null;
            int           start  = 0;

            for (int i = 0; i < text.Length; ++i)
            {
                if (text[i] >= 127)
                {
                    if (result == null)
                    {
                        result = new StringBuilder();
                    }
                    result.Append(text, start, i - start);
                    result.Append(XUri.Encode(text[i].ToString()));
                    start = i + 1;
                }
            }
            if (result != null)
            {
                result.Append(text, start, text.Length - start);
                return(result.ToString());
            }
            return(text);
        }
示例#2
0
        public override User GetUser(string user)
        {
            User         u        = null;
            DreamMessage response = _dekiPlug.At("users", "=" + XUri.Encode(user)).GetAsync().Wait();

            if (response.IsSuccessful)
            {
                XDoc         userDoc = response.ToDocument();
                string       email   = userDoc["email"].AsText;
                List <Group> groups  = new List <Group>();

                groups.Add(new Group(REMOTEDEKIUSERS));
                foreach (XDoc groupDoc in userDoc["groups/group"])
                {
                    string groupName = groupDoc["groupname"].AsText;
                    if (!string.IsNullOrEmpty(groupName))
                    {
                        groups.Add(new Group(groupName));
                    }
                }

                u = new User(user, email, groups.ToArray());
            }
            else
            {
                throw new DreamAbortException(response);
            }


            return(u);
        }
示例#3
0
        public void TestAttachmentDescriptionAssociations()
        {
            DreamMessage msg = null;
            Plug         p   = Utils.BuildPlugForAdmin();

            string pageId1, pageId2 = null;

            msg = PageUtils.CreateRandomPage(p, out pageId1);
            msg = PageUtils.CreateRandomPage(p, out pageId2);

            string description  = null;
            string fileid       = null;
            string filename     = null;
            string propertyEtag = null;
            string propertyName = "urn:deki.mindtouch.com#description";

            //Create initial file rev
            FileUtils.UploadRandomFile(p, pageId1, null, null, out fileid, out filename);

            //set initial file description
            description = "Content r1 on p1";
            msg         = p.At("files", fileid, "properties").WithHeader("Slug", XUri.Encode(propertyName)).PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, description)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "POST property got non 200");
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, description, "Contents don't match!");
            propertyEtag = msg.ToDocument()["/property/@etag"].AsText;

            //Validate intitial file description
            msg = p.At("files", fileid, "info").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "GET file info returned non 200:" + msg.ToString());
            Assert.AreEqual(description, msg.ToDocument()["description"].AsText, "Unexpected description");

            //update file description
            description = "Content r1 on p1 updated description 1";
            msg         = p.At("files", fileid, "properties", XUri.DoubleEncode(propertyName)).WithHeader(DreamHeaders.ETAG, propertyEtag).PutAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, description)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "PUT property got non 200");
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, description, "Contents don't match!");
            propertyEtag = msg.ToDocument()["/property/@etag"].AsText;

            //New file revision
            msg = p.At("pages", pageId1, "files", "=" + filename).PutAsync(DreamMessage.Ok(MimeType.ANY_TEXT, "Some content")).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "File upload failed: " + msg.ToString());

            //Updated file description
            description = "Content r2 on p1";
            msg         = p.At("files", fileid, "properties", XUri.DoubleEncode(propertyName)).WithHeader(DreamHeaders.ETAG, propertyEtag).PutAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, description)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "PUT property got non 200");
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, description, "Contents don't match!");
            propertyEtag = msg.ToDocument()["/property/@etag"].AsText;

            //Move file
            msg = p.At("files", fileid, "move").With("to", pageId2).Post();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "File move failed:" + msg.ToString());

            //Update file description
            description = "Content r2 on p2";
            msg         = p.At("files", fileid, "properties", XUri.DoubleEncode(propertyName)).WithHeader(DreamHeaders.ETAG, propertyEtag).PutAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, description)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "PUT property got non 200");
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, description, "Contents don't match!");
            propertyEtag = msg.ToDocument()["/property/@etag"].AsText;
        }
示例#4
0
        public void PutFileProperties()
        {
            Plug p = Utils.BuildPlugForAdmin();

            string       id   = null;
            string       path = null;
            DreamMessage msg  = PageUtils.CreateRandomPage(p, out id, out path);

            string propertyContent = Utils.GetSmallRandomText();
            string propertyName    = Utils.GenerateUniqueName();

            string fileid = null;

            msg = FileUtils.UploadRandomFile(p, id, out fileid);

            msg = p.At("files", fileid, "properties").WithHeader("Slug", XUri.Encode(propertyName)).PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, propertyContent)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status);
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, propertyContent, "Contents don't match!");

            msg = p.At("files", fileid, "properties", propertyName).GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "Non 200 status on get:property content: " + msg.ToString());
            Assert.AreEqual(propertyContent, msg.AsText(), "Contents don't match!");

            PageUtils.DeletePageByID(p, id, true);
        }
示例#5
0
        public void PostPutDeleteSiteProperties()
        {
            Plug   p = Utils.BuildPlugForAdmin();
            string propertyContent = Utils.GetSmallRandomText();
            string propertyName    = Utils.GenerateUniqueName();

            DreamMessage msg = null;

            try {
                msg = p.At("site", "properties").WithHeader("Slug", XUri.Encode(propertyName)).PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, propertyContent)).Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "POST property got non 200");
                Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, propertyContent, "Contents don't match!");

                msg = p.At("site", "properties", propertyName).GetAsync().Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "GET property returned non 200");
                Assert.AreEqual(propertyContent, msg.AsText(), "Contents don't match!");

                propertyContent = Utils.GetSmallRandomText();
                msg             = p.At("site", "properties", propertyName).WithHeader(DreamHeaders.ETAG, msg.Headers.ETag).PutAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, propertyContent)).Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "PUT property returned non 200");

                msg = p.At("site", "properties", propertyName).GetAsync().Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "GET property returned non 200");
                Assert.AreEqual(propertyContent, msg.AsText(), "Contents don't match on second rev!");
            } finally {
                msg = p.At("site", "properties", propertyName).DeleteAsync().Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "Delete status non 200");
            }
            msg = p.At("site", "properties", propertyName).GetAsync().Wait();
            Assert.AreEqual(DreamStatus.NotFound, msg.Status, "Deleted property get status non 404");
        }
示例#6
0
        public void SaveGetPageProperty()
        {
            Plug p = Utils.BuildPlugForAdmin();

            string       id   = null;
            string       path = null;
            DreamMessage msg  = PageUtils.CreateRandomPage(p, out id, out path);

            string content = Utils.GetSmallRandomText();

            //NOTE: PUT: resource/{properties}/{key} is allowing property creation. Creating properties this way is undocumented and not recommended but was added for import/export
            //Test property creation via PUT
            //msg = p.At("pages", id, "properties", "foo").PutAsync(DreamMessage.Ok(MimeType.TEXT, content)).Wait();
            //Assert.AreEqual(DreamStatus.Conflict, msg.Status);

            msg = p.At("pages", id, "properties").WithHeader("Slug", XUri.Encode("foo")).PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, content)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "post properties returned non 200 status: " + msg.ToString());

            //TODO: validate response XML for 200's
            msg = p.At("pages", id, "properties", "foo", "info").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property returned non 200 status: " + msg.ToString());
            Assert.AreEqual(content, msg.ToDocument()["/property[@name= 'foo']/contents"].AsText, "Contents don't match!");

            XUri contentsUri = msg.ToDocument()["/property[@name = 'foo']/contents/@href"].AsUri;

            Assert.IsTrue(contentsUri != null, "Couldn't find content href");
            Plug p2 = Plug.New(contentsUri).WithTimeout(p.Timeout).WithHeaders(p.Headers).WithCredentials(p.Credentials);

            msg = p2.GetAsync().Wait();
            Assert.IsTrue(msg.Status == DreamStatus.Ok, "get property contents by uri didnt return status 200: " + msg.ToString());
            Assert.IsTrue(msg.ContentType.Match(MimeType.TEXT), "get property content type didnt match: " + msg.ToString());
            Assert.IsTrue(msg.AsText() == content, "get property content didnt match: " + msg.ToString());
        }
 public Result <Stream> GetConvertedScore(string scoreId, string fileName, Result <Stream> aResult)
 {
     theServiceUri
     .At("scores", scoreId, XUri.Encode(fileName))
     .Get(new Result <DreamMessage>())
     .WhenDone(delegate(Result <DreamMessage> answer)
     {
         if (!answer.Value.IsSuccessful)
         {
             if (answer.Value.Status == DreamStatus.NotFound)
             {
                 aResult.Return((Stream)null);
             }
             else
             {
                 aResult.Throw(answer.Exception);
             }
         }
         else
         {
             aResult.Return(answer.Value.ToStream());
         }
     }
               );
     return(aResult);
 }
示例#8
0
 public static string AnchorEncode(string section)
 {
     return(XUri.Encode(section.Trim().Replace(' ', '_')).ReplaceAll(
                "%3A", ":",
                "%", "."
                ));
 }
        public Yield FeatureGetAuthenticate(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            string user = Authenticate(context, request);

            string password;

            HttpUtil.GetAuthentication(context.Uri.ToUri(), request.Headers, out user, out password);
            yield return(context.Relay(Self.At("users", XUri.Encode(user)).WithCredentials(user, password), request, response));
        }
示例#10
0
        public static Plug With(this Plug aPlug, ChangeOptions aChangeOptions)
        {
            switch (aChangeOptions.Feed)
            {
            case ChangeFeed.LongPoll:
            case ChangeFeed.Normal:
                aPlug = aPlug.With(Constants.FEED, Constants.FEED_NORMAL);
                break;

            case ChangeFeed.Continuous:
                aPlug = aPlug.With(Constants.FEED, Constants.FEED_CONTINUOUS);
                break;

            default:
                //Never get here
                break;
            }

            if (!String.IsNullOrEmpty(aChangeOptions.Filter))
            {
                aPlug = aPlug.With(Constants.FILTER, XUri.Encode(aChangeOptions.Filter));
            }
            if (!String.IsNullOrEmpty(aChangeOptions.View))
            {
                aPlug = aPlug.With(Constants.FILTER, XUri.Encode(Constants.VIEW));
                aPlug = aPlug.With(Constants.VIEW_PARAMETER, aChangeOptions.View);
            }
            if (aChangeOptions.Heartbeat.HasValue)
            {
                aPlug = aPlug.With(Constants.HEARTBEAT, aChangeOptions.Heartbeat.Value);
            }
            if (aChangeOptions.IncludeDocs.HasValue)
            {
                aPlug = aPlug.With(Constants.INCLUDE_DOCS, aChangeOptions.IncludeDocs.Value ? "true" : "false");
            }
            if (aChangeOptions.Limit.HasValue)
            {
                aPlug = aPlug.With(Constants.LIMIT, aChangeOptions.Limit.Value);
            }
            if (aChangeOptions.Since.HasValue)
            {
                aPlug = aPlug.With(Constants.SINCE, aChangeOptions.Since.Value);
            }
            if (aChangeOptions.Timeout.HasValue)
            {
                aPlug = aPlug.With(Constants.TIMEOUT, aChangeOptions.Timeout.Value);
            }

            return(aPlug);
        }
示例#11
0
        //--- Methods ---

        /// <summary>
        /// Convert to Content-Disposition header string.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder result = new StringBuilder();

            if (Inline)
            {
                result.Append("inline");
            }
            else
            {
                result.Append("attachment");
            }
            if (CreationDate != null)
            {
                result.Append("; creation-date=\"").Append(CreationDate.Value.ToUniversalTime().ToString("r")).Append("\"");
            }
            if (ModificationDate != null)
            {
                result.Append("; modification-date=\"").Append(ModificationDate.Value.ToUniversalTime().ToString("r")).Append("\"");
            }
            if (!string.IsNullOrEmpty(FileName))
            {
                bool gotFilename = false;
                if (!string.IsNullOrEmpty(UserAgent))
                {
                    if (URL_ENCODE_REGEX.IsMatch(UserAgent))
                    {
                        // Filename is uri encoded to support non ascii characters.
                        // + is replaced with %20 for IE otherwise it saves names containing spaces with plusses.
                        result.Append("; filename=\"").Append(XUri.Encode(FileName).Replace("+", "%20")).Append("\"");
                        gotFilename = true;
                    }
                    else if (MIME_ENCODE_REGEX.IsMatch(UserAgent))
                    {
                        result.Append("; filename=\"=?UTF-8?B?").Append(Convert.ToBase64String(Encoding.UTF8.GetBytes(FileName))).Append("?=\"");
                        gotFilename = true;
                    }
                }
                if (!gotFilename)
                {
                    result.Append("; filename=\"").Append(Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(FileName))).Append("\"");
                }
            }
            if (Size != null)
            {
                result.Append("; size=").Append(Size.Value);
            }
            return(result.ToString());
        }
示例#12
0
        public void DeleteAndOverwritePageProperty()
        {
            //Set a property foo with content c1
            //Delete the property foo
            //Validate that foo doesn't exist
            //Set property to content c2
            //Validate property content of c2

            string       C1      = "C1";
            string       C2      = "C2";
            Plug         p       = Utils.BuildPlugForAdmin();
            string       id      = null;
            string       path    = null;
            XDoc         content = null;
            DreamMessage msg     = PageUtils.CreateRandomPage(p, out id, out path);

            //Set foo with c1
            content = new XDoc("deltest").Start("somevalue").Value(C1).End();
            msg     = p.At("pages", id, "properties").WithHeader("Slug", XUri.Encode("foo")).PostAsync(DreamMessage.Ok(content)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "put property returned non 200 status: " + msg.ToString());
            msg = p.At("pages", id, "properties", "foo", "info").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property returned non 200 status: " + msg.ToString());
            msg = p.At("pages", id, "properties", "foo").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property contents returned non 200 status: " + msg.ToString());
            Assert.AreEqual(content.ToPrettyString(), msg.ToDocument().ToPrettyString(), "Contents don't match!");

            //Delete foo
            msg = p.At("pages", id, "properties", "foo").DeleteAsync(DreamMessage.Ok()).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "delete property returned non 200 status: " + msg.ToString());

            //Validate that foo doesn't exist
            msg = p.At("pages", id, "properties", "foo", "info").GetAsync(DreamMessage.Ok()).Wait();
            Assert.AreEqual(DreamStatus.NotFound, msg.Status, "get deleted property returned non 404 status: " + msg.ToString());

            //Set property to content c2
            content = new XDoc("deltest").Start("somevalue").Value(C2).End();
            msg     = p.At("pages", id, "properties").WithHeader("Slug", XUri.Encode("foo")).PostAsync(DreamMessage.Ok(content)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "put property returned non 200 status: " + msg.ToString());
            msg = p.At("pages", id, "properties", "foo", "info").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property returned non 200 status: " + msg.ToString());

            //Validate property content of c2
            msg = p.At("pages", id, "properties", "foo").GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property contents returned non 200 status: " + msg.ToString());
            Assert.AreEqual(content.ToPrettyString(), msg.ToDocument().ToPrettyString(), "Contents don't match!");
        }
示例#13
0
        public void PostUserProperties()
        {
            Plug p = Utils.BuildPlugForAdmin();

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

            string propertyContent = Utils.GetSmallRandomText();
            string propertyName    = Utils.GenerateUniqueName();

            msg = p.At("users", id, "properties").WithHeader("Slug", XUri.Encode(propertyName)).PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, propertyContent)).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status);
            Assert.AreEqual(msg.ToDocument()["/property/contents"].AsText, propertyContent, "Contents don't match!");

            msg = p.At("users", id, "properties", propertyName).GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status);
            Assert.AreEqual(propertyContent, msg.AsText(), "Contents don't match!");
        }
示例#14
0
        public void GetDateTag()
        {
            // 1. Create random page
            // 2. Generate random date tag and attach to page
            // (3a) Assert retrived tag value equals to that of generated string
            // (3b) Assert tag exists according to tag ID
            // (4a) Same as 3a, but using the tag value in the path
            // (4b) Same as 3b, but using the tag value in the path
            // 5. Delete page

            Plug         p    = Utils.BuildPlugForAdmin();
            string       id   = null;
            string       path = null;
            DreamMessage msg  = PageUtils.CreateRandomPage(p, out id, out path);

            DateTime date  = DateTime.UtcNow;
            string   value = "date:" + date.ToString("yyyy-MM-dd");

            XDoc tagsDoc = new XDoc("tags")
                           .Start("tag").Attr("value", value).End();

            DreamMessage tempmsg = p.At("pages", id, "tags").Put(tagsDoc);

            Assert.IsTrue(tempmsg.Status == DreamStatus.Ok, "PUT request failed");

            // GET:site/tags/{id}
            uint tag_id = tempmsg.ToDocument()["tag/@id"].AsUInt ?? 0;

            msg = p.At("site", "tags", tag_id.ToString()).GetAsync().Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, String.Format("GET request failed! TAG_ID: {0} ||| PUT_MSG: {1} ||| GET_MSG: {2} ||| value: {3}", tag_id, tempmsg.ToString(), msg.ToString(), value));
            Assert.IsTrue(msg.ToDocument()["@value"].AsText == value, "Tag value does not match generated string! {id}");
            Assert.IsFalse(msg.ToDocument()[string.Format("pages/page[@id=\"{0}\"]", id)].IsEmpty, "Tag with specified ID does not exist! {id}");

            // GET:site/tags/{=tag_value}
            msg = p.At("site", "tags", string.Format("={0}", XUri.Encode(value))).Get();
            Assert.IsTrue(msg.Status == DreamStatus.Ok, "GET request failed! {=tag_value}");
            Assert.IsTrue(msg.ToDocument()["@value"].AsText == value, "Tag value does not match generated string! {=tag_value}");
            Assert.IsFalse(msg.ToDocument()[string.Format("pages/page[@id=\"{0}\"]", id)].IsEmpty, "Tag with specified ID does not exist! {=tag_value}");

            PageUtils.DeletePageByID(p, id, true);
        }
示例#15
0
        public override Group GetGroup(string group)
        {
            Group        g        = null;
            DreamMessage response = _dekiPlug.At("groups", "=" + XUri.Encode(group)).GetAsync().Wait();

            if (response.IsSuccessful)
            {
                XDoc   groupDoc  = response.ToDocument();
                string groupName = groupDoc["groupname"].AsText;
                if (!string.IsNullOrEmpty(groupName))
                {
                    g = new Group(groupName);
                }
            }
            else
            {
                throw new DreamAbortException(response);
            }

            return(g);
        }
示例#16
0
        public void GetTextTag()
        {
            // 1. Create random page
            // 2. Generate random text tag and attach to page
            // (3a) Assert retrived tag value equals to that of generated string
            // (3b) Assert tag exists according to tag ID
            // (4a) Same as 3a, but using the tag value in the path
            // (4b) Same as 3b, but using the tag value in the path
            // 5. Delete page

            Plug         p    = Utils.BuildPlugForAdmin();
            string       id   = null;
            string       path = null;
            DreamMessage msg  = PageUtils.CreateRandomPage(p, out id, out path);

            Guid guid = Guid.NewGuid();

            XDoc tagsDoc = new XDoc("tags")
                           .Start("tag").Attr("value", guid.ToString()).End();

            msg = p.At("pages", id, "tags").Put(tagsDoc);
            Assert.IsTrue(msg.Status == DreamStatus.Ok, "PUT request failed");

            // GET:site/tags/{id}
            uint tag_id = msg.ToDocument()["tag/@id"].AsUInt ?? 0;

            msg = p.At("site", "tags", tag_id.ToString()).Get();
            Assert.IsTrue(msg.Status == DreamStatus.Ok, "GET request failed {id}");
            Assert.IsTrue(msg.ToDocument()["@value"].AsText == guid.ToString(), "Tag value does not match generated string! {id}");
            Assert.IsFalse(msg.ToDocument()[string.Format("pages/page[@id=\"{0}\"]", id)].IsEmpty, "Tag with specified ID does not exist! {id}");

            // GET:site/tags/{=tag_value}
            msg = p.At("site", "tags", string.Format("={0}", XUri.Encode(guid.ToString()))).Get();
            Assert.IsTrue(msg.Status == DreamStatus.Ok, "GET request failed {=tag_value}");
            Assert.IsTrue(msg.ToDocument()["@value"].AsText == guid.ToString(), "Tag value does not match generated string! {=tag_value}");
            Assert.IsFalse(msg.ToDocument()[string.Format("pages/page[@id=\"{0}\"]", id)].IsEmpty, "Tag with specified ID does not exist! {=tag_value}");

            PageUtils.DeletePageByID(p, id, true);
        }
示例#17
0
        public void NewPropertyWithEtagNegative()
        {
            Plug         p    = Utils.BuildPlugForAdmin();
            string       id   = null;
            string       path = null;
            DreamMessage msg  = PageUtils.CreateRandomPage(p, out id, out path);


            XDoc   doc          = new XDoc("properties");
            string contentShort = "Some content";

            doc.Start("property").Attr("name", "prop_short").Attr("etag", "some-unexpected-etag")
            .Start("contents").Attr("type", MimeType.TEXT.ToString())
            .Value(contentShort)
            .End()
            .End();

            msg = p.At("pages", id, "properties").PutAsync(DreamMessage.Ok(doc)).Wait();
            Assert.AreEqual(DreamStatus.MultiStatus, msg.Status, "put batch property returned 200 status but expected MultiStatus");

            Assert.AreEqual("409", msg.ToDocument()["/properties/property[@name='prop_short']/status/@code"].AsText);
            msg = p.At("pages", id, "properties").WithHeader("Slug", XUri.Encode("foo")).WithHeader(DreamHeaders.ETAG, "some-etag").PostAsync(DreamMessage.Ok(MimeType.TEXT, "blah")).Wait();
            Assert.AreEqual(DreamStatus.Conflict, msg.Status, "put batch property returned 200 status but expected : " + msg.ToString());
        }
示例#18
0
        public void MultiplePropertiesInPage()
        {
            //Save multiple properties in a page
            //Retrieve them

            Plug         p        = Utils.BuildPlugForAdmin();
            string       id       = null;
            string       path     = null;
            int          NUMPROPS = 5;
            DreamMessage msg      = PageUtils.CreateRandomPage(p, out id, out path);

            for (int i = 1; i <= NUMPROPS; i++)
            {
                string propname = string.Format("testprop_{0}", i);
                XDoc   content  = new XDoc("proptest");
                content.Start("name").Value(propname).End();

                msg = p.At("pages", id, "properties").WithHeader("Slug", XUri.Encode(propname)).PostAsync(DreamMessage.Ok(content)).Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "put property returned non 200 status: " + msg.ToString());

                msg = p.At("pages", id, "properties", propname, "info").GetAsync().Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property returned non 200 status: " + msg.ToString());
                Assert.AreEqual(MimeType.XML.ToString(), MimeType.New(msg.ToDocument()["/property[@name='" + propname + "']/contents/@type"].AsText).ToString(), "Content types dont match");

                msg = p.At("pages", id, "properties", propname).GetAsync().Wait();
                Assert.AreEqual(DreamStatus.Ok, msg.Status, "get property content returned non 200 status: " + msg.ToString());
                Assert.AreEqual(content.ToPrettyString(), msg.ToDocument().ToPrettyString(), "Contents don't match!");

                //revisions not yet supported.
                //Assert.AreEqual((msg.ToDocument()["/property[@name= '" + propname + "']/revisions/@count"].AsInt ?? 0), 1);
            }

            msg = p.At("pages", id, "properties").GetAsync(DreamMessage.Ok()).Wait();
            Assert.AreEqual(DreamStatus.Ok, msg.Status, "get properties returned non 200 status: " + msg.ToString());
            Assert.AreEqual(msg.ToDocument()["/properties/@count"].AsInt, NUMPROPS, "Wrong property count!");
        }
 public static string UriEncode(
     [DekiScriptParam("text to encode")] string text
     )
 {
     return(XUri.Encode(text));
 }
示例#20
0
 public string AnchorEncode(
     [DekiExtParam("section anchor name")] string section
     )
 {
     return(XUri.Encode(section.Trim().Replace(' ', '_')).ReplaceAll("%3A", ":", "%", "."));
 }
示例#21
0
        //--- Methods ---

        private XDoc PerformQuery(XUri dataservice, string resource, string expand, string filter, string orderby, int?skip, int?top, bool fetchSchema, out XDoc schema)
        {
            Plug p = _adoNetPlug;

            if (dataservice != null)
            {
                p = Plug.New(dataservice);
            }
            else if (p == null)
            {
                throw new ArgumentException("Missing field", "dataservice");
            }

            if (fetchSchema)
            {
                schema = FetchSchema(p);
            }
            else
            {
                schema = null;
            }

            if (!string.IsNullOrEmpty(resource))
            {
                //HACKHACKHACK: +'s aren't treated the same way as '%20' when uri is decoded on the server side
                string s = XUri.Encode(resource).Replace("+", "%20");
                p = p.At(s);
            }

            if (!string.IsNullOrEmpty(expand))
            {
                p = p.With("$expand", expand);
            }
            if (!string.IsNullOrEmpty(filter))
            {
                p = p.With("$filter", filter);
            }

            if (!string.IsNullOrEmpty(orderby))
            {
                p = p.With("$orderby", orderby);
            }

            if (skip != null)
            {
                p = p.With("$skip", skip.Value);
            }

            if (top != null)
            {
                p = p.With("$top", top.Value);
            }

            XDoc   ret = null;
            string key = p.ToString();

            lock (_cache) {
                _cache.TryGetValue(key, out ret);
            }

            if (ret == null)
            {
                ret = p.Get().ToDocument();

                // add result to cache and start a clean-up timer
                lock (_cache) {
                    _cache[key] = ret;
                }

                TaskTimer.New(TimeSpan.FromSeconds(CACHE_TTL), RemoveCachedEntry, key, TaskEnv.None);
            }
            return(ret);
        }
        public static UserBE BuildUserFromAuthService(ServiceBE serviceInfo, UserBE knownUser, string usernameToBuild, bool bypassAuthentication, string authusername, string password, out List <GroupBE> externalGroups)
        {
            externalGroups = null;
            if (serviceInfo == null || string.IsNullOrEmpty(usernameToBuild))
            {
                return(null);
            }

            //Dont perform external lookup for disabled users
            if (knownUser != null && !knownUser.UserActive)
            {
                return(knownUser);
            }

            var errMsg = DekiResources.UNABLE_TO_AUTH_WITH_SERVICE(serviceInfo.Type, serviceInfo.SID, serviceInfo.Uri);

            if (knownUser != null && !string.IsNullOrEmpty(knownUser.ExternalName))
            {
                usernameToBuild = knownUser.ExternalName;
            }

            UserBE       ret      = null;
            DreamMessage response = null;

            if (serviceInfo.Uri == null)
            {
                throw new ExternalServiceNotStartedFatalException(serviceInfo.Type, serviceInfo.SID);
            }
            try {
                Plug dekiExternalAuthPlug;

                //bypassAuthentication is used when you only need user details but not to necessarily authenticate
                if (bypassAuthentication)
                {
                    //An external auth service's GET: user/{username} does not necessarily require authentication to lookup users but it may. It's up to the service
                    //to decide if anon requests are allowed.
                    dekiExternalAuthPlug = Plug.New(serviceInfo.Uri).At(USER_INFO).At(XUri.Encode(usernameToBuild));
                }
                else
                {
                    //Credentials are always needed for GET: authenticate. The user details of the auth'd user is returned with same format as GET: user/{username}
                    dekiExternalAuthPlug = Plug.New(serviceInfo.Uri).At(AUTHENTICATE_PATH);
                }

                //Always include credentials with the request if they're supplied
                if (!string.IsNullOrEmpty(authusername))
                {
                    dekiExternalAuthPlug = dekiExternalAuthPlug.WithCredentials(authusername, password ?? string.Empty);
                }

                response = dekiExternalAuthPlug.GetAsync().Wait();
            } catch (Exception x) {
                throw new ExternalServiceResponseException(errMsg, DreamMessage.InternalError(x));
            }

            if (response.IsSuccessful)
            {
                XDoc userXml = response.ToDocument();

                if (userXml == null || userXml.IsEmpty)
                {
                    throw new ExternalAuthResponseFatalException();
                }

                string nameFromAuthProvider = userXml["@name"].Contents;
                if (!nameFromAuthProvider.EqualsInvariantIgnoreCase(usernameToBuild))
                {
                    throw new ExternalServiceUnexpecteUsernameFatalException(userXml["@name"].AsText, usernameToBuild);
                }
                ret       = knownUser ?? new UserBE();
                ret.Email = string.IsNullOrEmpty(userXml["email"].AsText) ? (ret.Email ?? string.Empty) : userXml["email"].AsText;

                //Build the realname (exposed as 'fullname' in user xml) by saving it as '{firstname} {lastname}'
                string externalFirstName = userXml["firstname"].AsText ?? string.Empty;
                string externalLastName  = userXml["lastname"].AsText ?? string.Empty;
                string separator         = externalLastName.Length > 0 && externalFirstName.Length > 0 ? ", " : string.Empty;

                // NOTE (maxm): Fullname sync is disabled for now. Refer to bug 7855
#if !DISABLE_REAL_NAME_SYNCHRONIZATION
                ret.RealName = string.Format("{0}{1}{2}", externalLastName, separator, externalFirstName);
#endif

                ret.ServiceId = serviceInfo.Id;
                ret.Touched   = DateTime.UtcNow;

                ret.ExternalName = string.IsNullOrEmpty(ret.ExternalName) ? nameFromAuthProvider : ret.ExternalName;
                ret.Name         = string.IsNullOrEmpty(ret.Name) ? nameFromAuthProvider : ret.Name;

                //For new users, the name must be normalized and unique
                if (ret.ID == 0)
                {
                    string nameFromExternalName = string.Empty;

                    //Allow using a displayname from an external provider only for new accounts
                    if (!userXml["@displayname"].IsEmpty)
                    {
                        nameFromExternalName = userXml["@displayname"].AsText;
                    }
                    else
                    {
                        nameFromExternalName = ret.ExternalName;
                    }

                    ret.Name = UserBL.NormalizeExternalNameToWikiUsername(nameFromExternalName);
                }

                //Build group objects out of the user's group membership list
                externalGroups = new List <GroupBE>();
                IList <GroupBE> userGroups = DbUtils.CurrentSession.Groups_GetByUser(ret.ID);

                //Preserve local groups for existing users
                if (ret.ID != 0 && userGroups != null)
                {
                    foreach (GroupBE g in userGroups)
                    {
                        if (ServiceBL.IsLocalAuthService(g.ServiceId))
                        {
                            externalGroups.Add(g);
                        }
                    }
                }

                foreach (XDoc group in userXml["groups/group"])
                {
                    GroupBE g = new GroupBE();
                    g.Name      = group["@name"].AsText;
                    g.ServiceId = serviceInfo.Id;
                    if (!string.IsNullOrEmpty(g.Name))
                    {
                        externalGroups.Add(g);
                    }
                }
            }
            else
            {
                switch (response.Status)
                {
                case DreamStatus.Unauthorized:
                    if (bypassAuthentication)
                    {
                        DekiContext.Current.Instance.Log.Warn(string.Format("Attempted to lookup user info on auth provider '{0}' but failed since it required credentials", serviceInfo.Id));
                    }

                    throw new ExternalServiceAuthenticationDeniedException(DekiWikiService.AUTHREALM, serviceInfo.Description);

                default:
                    throw new ExternalServiceResponseException(errMsg, response);
                }
            }

            return(ret);
        }
        public static GroupBE BuildGroupFromAuthService(ServiceBE serviceInfo, GroupBE knownGroup, string groupNameToBuild, string authusername, string password)
        {
            if (serviceInfo == null || string.IsNullOrEmpty(groupNameToBuild))
            {
                return(null);
            }

            GroupBE      ret      = null;
            DreamMessage response = null;

            if (serviceInfo.Uri == null)
            {
                throw new ExternalServiceNotStartedFatalException(serviceInfo.Type, serviceInfo.SID);
            }
            var errMsg = DekiResources.GROUP_DETAILS_LOOKUP_FAILED(groupNameToBuild);

            try {
                Plug dekiExternalAuthPlug = Plug.New(serviceInfo.Uri).At(GROUP_INFO).At(XUri.Encode(groupNameToBuild));

                //Always include credentials with the request if they're supplied
                if (!string.IsNullOrEmpty(authusername))
                {
                    dekiExternalAuthPlug = dekiExternalAuthPlug.WithCredentials(authusername, password ?? string.Empty);
                }

                response = dekiExternalAuthPlug.GetAsync().Wait();
            } catch (Exception x) {
                throw new ExternalServiceResponseException(errMsg, DreamMessage.InternalError(x));
            }

            if (response.IsSuccessful)
            {
                XDoc groupXml = response.ToDocument();
                if (groupXml.HasName("group") && groupXml["@name"].Contents.EqualsInvariant(groupNameToBuild))
                {
                    if (knownGroup == null)
                    {
                        ret = new GroupBE();
                    }
                    else
                    {
                        ret = knownGroup;
                    }

                    ret.Name      = string.IsNullOrEmpty(ret.Name) ? groupNameToBuild : ret.Name;
                    ret.ServiceId = serviceInfo.Id;
                }

                //TODO (MaxM): Consider looking up existing wiki users and associating them here.
            }
            else
            {
                switch (response.Status)
                {
                case DreamStatus.Unauthorized:
                    throw new ExternalServiceAuthenticationDeniedException(DekiWikiService.AUTHREALM, serviceInfo.Description);

                case DreamStatus.InternalError:
                case DreamStatus.Forbidden:
                default:
                    throw new ExternalServiceResponseException(errMsg, response);
                }
            }

            return(ret);
        }