Esempio n. 1
0
 protected Dictionary <string, string> GetPostValues(Stream stream)
 {
     using (var buf = new MemoryStream())
     {
         stream.CopyTo(buf);
         return(DomToHtml.DecodeUrlEncodedFormData(buf.ToArray(), Util.Utf8NoBom));
     }
 }
Esempio n. 2
0
        protected virtual void HandleRequest(HttpListenerContext context)
        {
            Match match;
            var   path       = context.Request.Url.AbsolutePath;
            var   method     = context.Request.HttpMethod;
            var   authCookie = context.Request.Cookies["VBCBBotAuth"];

            if (path == "/login")
            {
                if (method == "POST")
                {
                    var loginValues = GetPostValues(context.Request.InputStream);
                    if (loginValues.ContainsKey("username") && loginValues.ContainsKey("password"))
                    {
                        if (loginValues["username"] == _interface.Config.Username && loginValues["password"] == _interface.Config.Password)
                        {
                            ActUponSuccessfulLogin(context);
                            return;
                        }
                    }

                    // unset or wrong username/password; fall through and output form again
                }
                else if (method != "GET")
                {
                    Send404(context.Response);
                }
                var vals = NewPageHash();
                var ret  = LoadTemplate("login").Render(vals);
                SendOkHtml(context.Response, ret);
                return;
            }
            else if (path.StartsWith("/devicelogin/"))
            {
                // (don't mind about HTTP method here)

                var deviceAccessCode = path.Substring(("/devicelogin/").Length);
                if (_interface.Config.DeviceAccessCodes.Contains(deviceAccessCode))
                {
                    ActUponSuccessfulLogin(context);
                    return;
                }

                // redirect to login page
                context.Response.Redirect(new Uri(context.Request.Url, "/login").ToString());
                context.Response.Close();
                return;
            }
            else if (path.StartsWith("/static/"))
            {
                var filePath = path.Substring(("/static/").Length);
                if (!AllowedStaticPathFormat.IsMatch(filePath))
                {
                    Send404(context.Response);
                    return;
                }
                var fullPath = Path.Combine(_staticPath, filePath);
                if (!File.Exists(Path.Combine(_staticPath, filePath)))
                {
                    Send404(context.Response);
                    return;
                }

                using (var mule = new MemoryStream())
                {
                    using (var inFile = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        inFile.CopyTo(mule);
                    }

                    mule.Seek(0, SeekOrigin.Begin);

                    context.Response.ContentLength64   = mule.Length;
                    context.Response.StatusCode        = 200;
                    context.Response.StatusDescription = "OK";
                    mule.CopyTo(context.Response.OutputStream);
                }
                context.Response.Close();
                return;
            }
            // everything else requires authentication
            else if (!_authGuid.HasValue || authCookie == null || authCookie.Expired || authCookie.Value != _authGuid.Value.ToString("D"))
            {
                // redirect to login page
                context.Response.Redirect(new Uri(context.Request.Url, "/login").ToString());
                context.Response.Close();
                return;
            }
            else if (path == "/logout")
            {
                // (don't mind about HTTP method here)

                // log everyone else out too
                _authGuid = null;

                // clear the cookie
                authCookie.Expires = new DateTime(1970, 1, 1);
                context.Response.SetCookie(authCookie);
                context.Response.Redirect(new Uri(context.Request.Url, "/login").ToString());
                context.Response.Close();
                return;
            }
            else if (path == "/" && method == "GET")
            {
                // if pausing is active, unpause the connector for the given time span
                if (_interface.Config.PauseConnectorOnInactivityMinutes > 0)
                {
                    _interface.CBConnector.UnpauseUntil(DateTime.Now.AddMinutes(_interface.Config.PauseConnectorOnInactivityMinutes));
                }

                // assemble the quick-messages
                var quickMessageString = new StringBuilder("<span class=\"quickmessagelist\">");
                foreach (var quickMessage in _interface.Config.QuickMessages)
                {
                    quickMessageString.AppendFormat(
                        " <button type=\"button\" onclick=\"sendQuick('{0}')\">{1}</button>",
                        DomToHtml.HtmlEscape(DomToHtml.JsEscapeString(quickMessage)),
                        DomToHtml.HtmlEscape(quickMessage)
                        );
                }
                quickMessageString.Append("</span>");

                var vars = NewPageHash();
                vars["quickMessages"] = quickMessageString.ToString();
                var ret = LoadTemplate("messages").Render(vars);
                SendOkHtml(context.Response, ret);
                return;
            }
            else if (path == "/smilies" && method == "GET")
            {
                var smileyString = new StringBuilder("<span class=\"smileylist\">");
                smileyString.Append("<button type=\"button\" onclick=\"hideSmilies()\">Hide!</button>");

                var smileyCodesToUrls = new SortedDictionary <string, string>(_interface.CBConnector.SmileyCodesToURLs);
                foreach (var smileyCodeAndUrl in smileyCodesToUrls)
                {
                    smileyString.Append(' ');
                    smileyString.Append("<span class=\"smiley\">");
                    smileyString.AppendFormat(
                        "<a class=\"jsclick\" onclick=\"smileyClicked('{0}')\">",
                        DomToHtml.HtmlEscape(
                            DomToHtml.JsEscapeString(smileyCodeAndUrl.Key, escapeQuotes: false, escapeApostrophes: true),
                            escapeQuotes: true,
                            escapeApostrophes: false
                            )
                        );
                    smileyString.AppendFormat(
                        "<img class=\"smiley picksmiley\" src=\"{0}\" title=\"{1}\"/>",
                        DomToHtml.HtmlEscape(new Uri(_interface.CBConnector.ForumConfig.Url, smileyCodeAndUrl.Value)),
                        DomToHtml.HtmlEscape(smileyCodeAndUrl.Key)
                        );
                    smileyString.Append("</a>");
                    smileyString.Append("</span>");
                }
                smileyString.Append("</span>");

                SendOkHtml(context.Response, smileyString.ToString());
                return;
            }
            else if (path == "/messages" && method == "GET")
            {
                var tpl            = LoadTemplate("post");
                var messageStrings = new List <string>();
                lock (_interface.MessageList)
                {
                    foreach (var message in _interface.MessageList)
                    {
                        var senderInfoUrl  = new Uri(_interface.CBConnector.ForumConfig.Url, "member.php?u=" + message.UserID.ToString());
                        var senderName     = DomToHtml.Convert(message.UserNameDom, _interface.CBConnector.ForumConfig.Url);
                        var body           = DomToHtml.Convert(message.BodyDom, _interface.CBConnector.ForumConfig.Url);
                        var myselfOrOthers = "others";
                        if (message.UserName == _interface.CBConnector.ForumConfig.Username)
                        {
                            // it's me
                            senderName     = string.Format("<span class=\"myself\">{0}</span>", senderName);
                            myselfOrOthers = "myself";
                        }
                        var msgHash = new Hash
                        {
                            { "time", message.Timestamp.ToString("yyyy-MM-dd HH:mm") },
                            { "messageID", message.ID.ToString() },
                            { "senderInfoURL", senderInfoUrl.ToString() },
                            { "senderNameHTML", senderName },
                            { "body", body },
                            { "myselfOrOthersClass", myselfOrOthers }
                        };
                        messageStrings.Add(tpl.Render(msgHash));
                    }
                }

                string allMessagesString = string.Join("\n", messageStrings);
                SendOkHtml(context.Response, allMessagesString);
                return;
            }
            else if ((match = EditMessageRegex.Match(path)).Success)
            {
                long messageID;
                if (!long.TryParse(match.Groups[1].Value, out messageID))
                {
                    Send404(context.Response, "Message ID out of range.");
                    return;
                }

                if (method == "GET")
                {
                    ChatboxMessage messageToEdit;
                    lock (_interface.MessageList)
                    {
                        var nodeToEdit = _interface.MessageList.Find(m => m.ID == messageID);
                        messageToEdit = (nodeToEdit == null) ? null : nodeToEdit.Value;
                    }

                    if (messageToEdit == null)
                    {
                        Send404(context.Response, "Message not found.");
                        return;
                    }

                    var currentBody = messageToEdit.BodyBBCode;
                    var vars        = NewPageHash();
                    vars["messageID"]   = messageID.ToString();
                    vars["messageBody"] = currentBody;
                    var ret = LoadTemplate("editmessage").Render(vars);
                    SendOkHtml(context.Response, ret);
                    return;
                }
                else if (method == "POST")
                {
                    var postValues = GetPostValues(context.Request.InputStream);
                    if (!postValues.ContainsKey("newbody"))
                    {
                        SendOkPlainText(context.Response, "You must supply a new body to edit in.");
                        return;
                    }

                    // send
                    _interface.CBConnector.EditMessage(messageID, postValues["newbody"], customSmileys: true);

                    // redirect back to list
                    context.Response.Redirect(new Uri(context.Request.Url, "/").ToString());
                    context.Response.Close();
                    return;
                }
            }
            else if (path == "/post" && method == "POST")
            {
                var postValues = GetPostValues(context.Request.InputStream);
                if (!postValues.ContainsKey("message") || string.IsNullOrWhiteSpace(postValues["message"]))
                {
                    SendOkPlainText(context.Response, "You must supply a message to send.");
                    return;
                }

                // send
                _interface.CBConnector.SendMessage(postValues["message"], customSmileys: true);

                // redirect back to list
                context.Response.Redirect(new Uri(context.Request.Url, "/").ToString());
                context.Response.Close();
                return;
            }

            Send404(context.Response);
            return;
        }