nmailserver-commits Mailing List for NMail (Page 7)
Brought to you by:
dframpton-oss,
tmyroadctfig
You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(13) |
Jun
(14) |
Jul
(8) |
Aug
|
Sep
|
Oct
(8) |
Nov
(22) |
Dec
(9) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(21) |
Feb
(31) |
Mar
(24) |
Apr
(8) |
May
(23) |
Jun
(40) |
Jul
(14) |
Aug
(5) |
Sep
(7) |
Oct
(10) |
Nov
|
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <tmy...@us...> - 2007-02-06 11:59:58
|
Revision: 137
http://svn.sourceforge.net/nmailserver/?rev=137&view=rev
Author: tmyroadctfig
Date: 2007-02-06 03:59:57 -0800 (Tue, 06 Feb 2007)
Log Message:
-----------
Added some changes so remoting actually works now :-|
Modified Paths:
--------------
NMail/trunk/NMail.Administration.Web/Global.asax
NMail/trunk/NMail.Administration.Web/web.config
Modified: NMail/trunk/NMail.Administration.Web/Global.asax
===================================================================
--- NMail/trunk/NMail.Administration.Web/Global.asax 2007-02-05 11:27:37 UTC (rev 136)
+++ NMail/trunk/NMail.Administration.Web/Global.asax 2007-02-06 11:59:57 UTC (rev 137)
@@ -4,9 +4,8 @@
void Application_Start(object sender, EventArgs e)
{
- Hashtable properties = new Hashtable();
- properties.Add("secure", true);
- System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Tcp.TcpClientChannel(properties, null), false);
+ string configPath = Server.MapPath("web.config");
+ System.Runtime.Remoting.RemotingConfiguration.Configure(configPath);
}
void Application_End(object sender, EventArgs e)
Modified: NMail/trunk/NMail.Administration.Web/web.config
===================================================================
--- NMail/trunk/NMail.Administration.Web/web.config 2007-02-05 11:27:37 UTC (rev 136)
+++ NMail/trunk/NMail.Administration.Web/web.config 2007-02-06 11:59:57 UTC (rev 137)
@@ -52,6 +52,7 @@
</customErrors>
-->
</system.web>
+
<!-- Allow access to the themes without authentication so the login page is nice. -->
<location path="App_Themes">
<system.web>
@@ -70,13 +71,20 @@
</location>
<system.runtime.remoting>
- <application>
- <client>
- <wellknown
- type="NMail.Server.RemoteAdministration, NMail.Server"
- url="tcp://localhost:7877/RemoteAdministration.rem"
+ <application>
+ <client>
+ <wellknown
+ type="NMail.Server.RemoteAdministration, NMail.Server"
+ url="tcp://localhost:7877/RemoteAdministration.rem"
/>
- </client>
- </application>
- </system.runtime.remoting>
+ </client>
+ <channels>
+ <channel ref="tcp" secure="true">
+ <clientProviders>
+ <formatter ref="binary" />
+ </clientProviders>
+ </channel>
+ </channels>
+ </application>
+ </system.runtime.remoting>
</configuration>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:27:37
|
Revision: 136
http://svn.sourceforge.net/nmailserver/?rev=136&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:27:37 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Updated web.config to allow images and themes to unauthenticated users. Updated to use web.config remoting URL.
Modified Paths:
--------------
NMail/trunk/NMail.Administration.Web/Login.aspx.cs
NMail/trunk/NMail.Administration.Web/web.config
Modified: NMail/trunk/NMail.Administration.Web/Login.aspx.cs
===================================================================
--- NMail/trunk/NMail.Administration.Web/Login.aspx.cs 2007-02-05 11:25:48 UTC (rev 135)
+++ NMail/trunk/NMail.Administration.Web/Login.aspx.cs 2007-02-05 11:27:37 UTC (rev 136)
@@ -29,8 +29,8 @@
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
System.Web.UI.WebControls.Login login = (System.Web.UI.WebControls.Login)this.LoginView.FindControl("Login");
-
- RemoteAdministration ra = (RemoteAdministration)Activator.GetObject(typeof(RemoteAdministration), "tcp://localhost:7877/RemoteAdministration.rem");
+
+ RemoteAdministration ra = new RemoteAdministration();
IAuthenticationToken authToken = ra.NMailServer.AuthenticationProvider.Authenticate(login.UserName, login.Password);
if (authToken != null)
Modified: NMail/trunk/NMail.Administration.Web/web.config
===================================================================
--- NMail/trunk/NMail.Administration.Web/web.config 2007-02-05 11:25:48 UTC (rev 135)
+++ NMail/trunk/NMail.Administration.Web/web.config 2007-02-05 11:27:37 UTC (rev 136)
@@ -52,8 +52,24 @@
</customErrors>
-->
</system.web>
+ <!-- Allow access to the themes without authentication so the login page is nice. -->
+ <location path="App_Themes">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+ <!-- Allow access to the images without authentication so the login page is nice. -->
+ <location path="Images">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
- <!--<system.runtime.remoting>
+ <system.runtime.remoting>
<application>
<client>
<wellknown
@@ -62,5 +78,5 @@
/>
</client>
</application>
- </system.runtime.remoting>-->
+ </system.runtime.remoting>
</configuration>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:25:56
|
Revision: 135
http://svn.sourceforge.net/nmailserver/?rev=135&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:25:48 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Fixed a defect in MIME parsing.
Modified Paths:
--------------
NMail/trunk/NMail/Helper/MimeHelper.cs
Modified: NMail/trunk/NMail/Helper/MimeHelper.cs
===================================================================
--- NMail/trunk/NMail/Helper/MimeHelper.cs 2007-02-05 11:24:38 UTC (rev 134)
+++ NMail/trunk/NMail/Helper/MimeHelper.cs 2007-02-05 11:25:48 UTC (rev 135)
@@ -218,7 +218,7 @@
type = contentType;
} else {
- type = contentType.Substring(0, parameterStart - 1);
+ type = contentType.Substring(0, parameterStart);
string parameterList = contentType.Substring(parameterStart + 1);
// Parse out parameters
@@ -226,14 +226,14 @@
for (int i = 0; i < parameterTokens.Length; i++) {
if (parameterTokens[i].IndexOf('=') != -1) {
string[] parameterParts = parameterTokens[i].Split("=".ToCharArray(), 2);
- parameters.Add(parameterParts[0], parameterParts[1]);
+ parameters.Add(parameterParts[0].Trim(), parameterParts[1].Trim());
}
}
}
// Chop at the slash
string[] tokens = type.Split("/".ToCharArray(), 2);
-
+
if (tokens.Length < 2) {
subType = "plain";
return MimeContentType.Text;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:25:56
|
Revision: 134
http://svn.sourceforge.net/nmailserver/?rev=134&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:24:38 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Added WebAccess and RemoteAccessService to the NAnt build.
Modified Paths:
--------------
NMail/trunk/Installer/NMail-Installer.wxs
NMail/trunk/Installer/NMail-installer.build
NMail/trunk/NMail/NMail.build
NMail/trunk/NMail.SetupWizard/NMail.SetupWizard.build
NMail/trunk/NMail.build
Modified: NMail/trunk/Installer/NMail-Installer.wxs
===================================================================
--- NMail/trunk/Installer/NMail-Installer.wxs 2007-02-05 11:21:48 UTC (rev 133)
+++ NMail/trunk/Installer/NMail-Installer.wxs 2007-02-05 11:24:38 UTC (rev 134)
@@ -82,7 +82,7 @@
<!--
==
- == Webpage
+ == Administration Webpage
==
-->
Modified: NMail/trunk/Installer/NMail-installer.build
===================================================================
--- NMail/trunk/Installer/NMail-installer.build 2007-02-05 11:21:48 UTC (rev 133)
+++ NMail/trunk/Installer/NMail-installer.build 2007-02-05 11:24:38 UTC (rev 134)
@@ -66,6 +66,18 @@
<include name="NMail.Administration.Web.Compiled/**" />
</fileset>
</copy>
+ <!-- Copy NMail remote access service website -->
+ <copy todir="${build.dir}">
+ <fileset basedir="../">
+ <include name="NMail.RemoteAccessService.Compiled/**" />
+ </fileset>
+ </copy>
+ <!-- Copy NMail WebAccess website -->
+ <copy todir="${build.dir}">
+ <fileset basedir="../">
+ <include name="NMail.WebAccess.Compiled/**" />
+ </fileset>
+ </copy>
<!-- Make a date stamp to include in the filename -->
<tstamp property="build.date" pattern="yyyy-MM-dd" verbose="true" />
Modified: NMail/trunk/NMail/NMail.build
===================================================================
--- NMail/trunk/NMail/NMail.build 2007-02-05 11:21:48 UTC (rev 133)
+++ NMail/trunk/NMail/NMail.build 2007-02-05 11:24:38 UTC (rev 134)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<project name="nant" default="build">
<!-- default configuration -->
- <property name="project.config" value="Release" />
+ <property name="project.config" value="Debug" />
<property name="current.build.defines" value="" />
<target name="Debug" description="Perform a 'debug' build">
Modified: NMail/trunk/NMail.SetupWizard/NMail.SetupWizard.build
===================================================================
--- NMail/trunk/NMail.SetupWizard/NMail.SetupWizard.build 2007-02-05 11:21:48 UTC (rev 133)
+++ NMail/trunk/NMail.SetupWizard/NMail.SetupWizard.build 2007-02-05 11:24:38 UTC (rev 134)
@@ -43,7 +43,10 @@
<include name="NMail.SmtpClient.dll"/>
<include name="NMail.SmtpService.dll"/>
<include name="NMail.SpoolData.MySql.dll"/>
+ <include name="NMail.LocalStoreData.MySql.dll"/>
+ <include name="NMail.LocalStore.dll"/>
<include name="NMail.SpoolFilter.dll"/>
+ <include name="NMail.ImapService.dll" />
<include name="NMail.SpoolService.dll"/>
</fileset>
</copy>
@@ -61,6 +64,9 @@
<include name="NMail.SmtpClient.dll"/>
<include name="NMail.SmtpService.dll"/>
<include name="NMail.SpoolData.MySql.dll"/>
+ <include name="NMail.LocalStoreData.MySql.dll"/>
+ <include name="NMail.LocalStore.dll"/>
+ <include name="NMail.ImapService.dll" />
<include name="NMail.SpoolFilter.dll"/>
<include name="NMail.SpoolService.dll"/>
</references>
Modified: NMail/trunk/NMail.build
===================================================================
--- NMail/trunk/NMail.build 2007-02-05 11:21:48 UTC (rev 133)
+++ NMail/trunk/NMail.build 2007-02-05 11:24:38 UTC (rev 134)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<project name="nant" default="all">
<!-- default configuration -->
- <property name="project.config" value="Release" />
+ <property name="project.config" value="Debug" />
<property name="current.build.defines" value="" />
<target name="all" decription="Builds all assemblies and the installer." depends="build-Installer" />
@@ -259,7 +259,63 @@
</exec>
</target>
- <target name="build-Installer" depends="assemblies, build-NMail.Administration.Web" description="Builds the NMail Server installer.">
+ <target name="build-NMail.RemoteAccessService" depends="init-build,build-NMail,build-NMail.Server" description="Builds the NMail remote access web site.">
+ <mkdir dir="NMail.RemoteAccessService.Compiled" />
+
+ <!-- build NMail.RemoteAccess web site-->
+ <exec program="aspnet_compiler" verbose="true">
+ <arg value="-v" />
+ <arg value="/NMailRemoteAccessService" />
+ <arg value="-p" />
+ <arg>
+ <path>
+ <pathelement file="NMail.RemoteAccessService" />
+ </path>
+ </arg>
+ <arg value="-u" />
+ <arg value="-f" />
+ <arg>
+ <path>
+ <pathelement file="NMail.RemoteAccessService.Compiled" />
+ </path>
+ </arg>
+ <arg value="-errorstack" />
+ <arg value="-fixednames" />
+ </exec>
+ </target>
+
+ <target name="build-NMail.WebAccess" depends="init-build,build-NMail,build-NMail.Server" description="Builds the NMail WebAccess web site.">
+ <mkdir dir="NMail.WebAccess.Compiled" />
+
+ <!-- build NMail.RemoteAccess web site-->
+ <exec program="aspnet_compiler" verbose="true">
+ <arg value="-v" />
+ <arg value="/NMailWebAccess" />
+ <arg value="-p" />
+ <arg>
+ <path>
+ <pathelement file="NMail.WebAccess" />
+ </path>
+ </arg>
+ <arg value="-u" />
+ <arg value="-f" />
+ <arg>
+ <path>
+ <pathelement file="NMail.WebAccess.Compiled" />
+ </path>
+ </arg>
+ <arg value="-errorstack" />
+ <arg value="-fixednames" />
+ </exec>
+ </target>
+
+ <target name="build-Installer"
+ depends="assemblies,
+ build-NMail.Administration.Web,
+ build-NMail.RemoteAccessService,
+ build-NMail.WebAccess"
+ description="Builds the NMail Server installer.">
+
<!-- build NMail.installer -->
<nant buildfile="Installer/NMail-installer.build" target="package" />
</target>
@@ -283,6 +339,8 @@
<nant buildfile="NMail.SetupWizard/NMail.SetupWizard.build" target="clean" />
<nant buildfile="NMail.Administration.Console/NMail.Administration.Console.build" target="clean" />
<delete dir="NMail.Administration.Web.Compiled" />
+ <delete dir="NMail.RemoteAccessService.Compiled" />
+ <delete dir="NMail.WebAccess.Compiled" />
</target>
<target name="cleanall" depends="" description="Cleans the projects">
@@ -304,6 +362,8 @@
<nant buildfile="NMail.Server.Service/NMail.Server.Service.build" target="cleanall" />
<nant buildfile="NMail.Administration.Console/NMail.Administration.Console.build" target="cleanall" />
<delete dir="NMail.Administration.Web.Compiled" />
+ <delete dir="NMail.RemoteAccessService.Compiled" />
+ <delete dir="NMail.WebAccess.Compiled" />
</target>
<target name="codestats" description="Generates code stats for NMail.">
@@ -314,6 +374,13 @@
<include name="**\*.cs" />
</fileset>
</count>
+ <count label="ASP.net">
+ <fileset>
+ <include name="**\*.aspx" />
+ <include name="**\*.ascx" />
+ <include name="**\*.asmx" />
+ </fileset>
+ </count>
</counts>
</codestats>
</target>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:21:48
|
Revision: 133
http://svn.sourceforge.net/nmailserver/?rev=133&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:21:48 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Some minor changes.
Modified Paths:
--------------
NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs
NMail/trunk/NMail.WebAccess/ErrorHandler.aspx
NMail/trunk/NMail.WebAccess/Global.asax
NMail/trunk/NMail.WebAccess/Login.aspx
NMail/trunk/NMail.WebAccess/Login.aspx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
Modified: NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs 2007-02-05 11:21:48 UTC (rev 133)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
Modified: NMail/trunk/NMail.WebAccess/ErrorHandler.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/ErrorHandler.aspx 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/ErrorHandler.aspx 2007-02-05 11:21:48 UTC (rev 133)
@@ -21,7 +21,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
- <title>NMail Web Access - Error</title>
+ <title>NMail WebAccess - Error</title>
</head>
<body>
<form id="form1" runat="server">
Modified: NMail/trunk/NMail.WebAccess/Global.asax
===================================================================
--- NMail/trunk/NMail.WebAccess/Global.asax 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/Global.asax 2007-02-05 11:21:48 UTC (rev 133)
@@ -1,3 +1,20 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Application Language="C#" %>
<%@ Import Namespace="System.Web.Configuration" %>
@@ -5,6 +22,8 @@
void Application_Start(object sender, EventArgs e)
{
+ // We need the NMail configuration to get the local store delimeter
+ // This is not ideal
Configuration c = WebConfigurationManager.OpenWebConfiguration("/NMail.WebAccess");
NMail.Configuration.NMailConfigFile.Current = c;
}
@@ -12,19 +31,16 @@
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
-
}
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
-
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
-
}
void Session_End(object sender, EventArgs e)
@@ -33,7 +49,6 @@
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
-
}
</script>
Modified: NMail/trunk/NMail.WebAccess/Login.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/Login.aspx 2007-02-05 11:21:48 UTC (rev 133)
@@ -21,7 +21,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
- <title>NMail Login</title>
+ <title>NMail WebAccess Login</title>
</head>
<body class="LoginBody">
<form id="form1" runat="server">
Modified: NMail/trunk/NMail.WebAccess/Login.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx.cs 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/Login.aspx.cs 2007-02-05 11:21:48 UTC (rev 133)
@@ -33,8 +33,6 @@
/// </summary>
public partial class Login : System.Web.UI.Page
{
- protected void Page_Load(object sender, EventArgs e) { }
-
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
System.Web.UI.WebControls.Login login = (System.Web.UI.WebControls.Login)this.LoginView.FindControl("Login");
@@ -49,9 +47,5 @@
Session["RAS"] = ras;
e.Authenticated = true;
}
- else
- {
- // TODO: an error message
- }
}
}
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-02-05 11:19:45 UTC (rev 132)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-02-05 11:21:48 UTC (rev 133)
@@ -29,7 +29,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
- <title>Mail</title>
+ <title>NMail WebAccess Mail</title>
</head>
<body>
<form id="form1" runat="server">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:19:47
|
Revision: 132
http://svn.sourceforge.net/nmailserver/?rev=132&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:19:45 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Added some unit tests.
Modified Paths:
--------------
NMail/trunk/NMail.UnitTests/NMail.UnitTests.csproj
Added Paths:
-----------
NMail/trunk/NMail.UnitTests/Helper/
NMail/trunk/NMail.UnitTests/Helper/MimeHelperTests.cs
Property Changed:
----------------
NMail/trunk/
Property changes on: NMail/trunk
___________________________________________________________________
Name: svn:ignore
- NMail.suo
NMail.Administration.Web.suo
NMail.Administration.Web.Compiled
+ NMail.suo
NMail.Administration.Web.suo
NMail.Administration.Web.Compiled
NMail.WebAccess.Compiled
NMail.RemoteAccessService.Compiled
Added: NMail/trunk/NMail.UnitTests/Helper/MimeHelperTests.cs
===================================================================
--- NMail/trunk/NMail.UnitTests/Helper/MimeHelperTests.cs (rev 0)
+++ NMail/trunk/NMail.UnitTests/Helper/MimeHelperTests.cs 2007-02-05 11:19:45 UTC (rev 132)
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using NUnit.Framework;
+
+using NMail.DataTypes;
+using NMail.Helper;
+
+namespace NMail.Helper {
+ /// <summary>
+ /// Unit tests for the MIME helper.
+ /// </summary>
+ [TestFixture]
+ public class MimeHelperTests {
+
+ #region Content Type Parsing
+
+ public const string ContentType1 = "multipart/mixed;\r\n boundary=\"----_=_NextPart_001_01C723C4.37D53E7D\"";
+
+ public const string ContentType2 = "multipart/related;\r\n type=\"multipart/alternative\";\r\n boundary=\"----_=_NextPart_002_01C723C4.37D53E7D\"";
+
+ public const string ContentType3 = "text/html";
+
+ [Test]
+ public void ContentTypeParsing() {
+ Dictionary<string, string> parameters;
+ string subType;
+ MimeContentType contentType;
+
+ contentType = MimeHelper.GetContentType(ContentType1, out subType, out parameters);
+ Assert.AreEqual(contentType, MimeContentType.Multipart, "ContentType1");
+ Assert.AreEqual("mixed", subType, "ContentType1");
+ Assert.IsTrue(parameters.Count == 1, "ContentType1: parameter count=1");
+ Assert.IsTrue(parameters["boundary"].Equals("----_=_NextPart_001_01C723C4.37D53E7D"), "ContentType1: boundary");
+
+ contentType = MimeHelper.GetContentType(ContentType2, out subType, out parameters);
+ Assert.AreEqual(contentType, MimeContentType.Multipart, "ContentType2");
+ Assert.AreEqual("related", subType, "ContentType2");
+ Assert.IsTrue(parameters.Count == 2, "ContentType2: parameter count=2");
+ Assert.IsTrue(parameters["type"].Equals("multipart/alternative"), "ContentType2: type");
+ Assert.IsTrue(parameters["boundary"].Equals("----_=_NextPart_002_01C723C4.37D53E7D"), "ContentType2: boundary");
+
+ contentType = MimeHelper.GetContentType(ContentType3, out subType, out parameters);
+ Assert.AreEqual(contentType, MimeContentType.Text, "ContentType3");
+ Assert.AreEqual("html", subType, "ContentType3");
+ Assert.IsTrue(parameters.Count == 0, "ContentType3: parameter count=0");
+ }
+ #endregion
+
+ #region Get Attachment Name
+
+ public const string AttachmentName1 = "Content-Type: image/jpeg;\r\n name=\"image001.jpg\"";
+
+ public const string AttachmentName2 = "Content-Type: image/jpeg";
+
+ [Test]
+ public void GetAttachmentName() {
+ string name;
+ MessageHeaders headers;
+
+ headers = new MessageHeaders(new ByteString(AttachmentName1, Encoding.ASCII));
+ name = MimeHelper.GetAttachmentName(headers);
+ Assert.AreEqual("image001.jpg", name, "AttachmentName1");
+
+ headers = new MessageHeaders(new ByteString(AttachmentName2, Encoding.ASCII));
+ name = MimeHelper.GetAttachmentName(headers);
+ Assert.AreEqual(null, name, "AttachmentName2 is null");
+ }
+ #endregion
+ }
+}
Modified: NMail/trunk/NMail.UnitTests/NMail.UnitTests.csproj
===================================================================
--- NMail/trunk/NMail.UnitTests/NMail.UnitTests.csproj 2007-02-05 11:15:44 UTC (rev 131)
+++ NMail/trunk/NMail.UnitTests/NMail.UnitTests.csproj 2007-02-05 11:19:45 UTC (rev 132)
@@ -44,6 +44,7 @@
<Compile Include="DNSCacheTests.cs" />
<Compile Include="DomainTests.cs" />
<Compile Include="EmailAddressTests.cs" />
+ <Compile Include="Helper\MimeHelperTests.cs" />
<Compile Include="HostTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SmtpServiceTests.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-05 11:15:47
|
Revision: 131
http://svn.sourceforge.net/nmailserver/?rev=131&view=rev
Author: tmyroadctfig
Date: 2007-02-05 03:15:44 -0800 (Mon, 05 Feb 2007)
Log Message:
-----------
Deleted old files.
Removed Paths:
-------------
NMail/trunk/NMail.LocalStore/Configuration/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-04 09:01:40
|
Revision: 130
http://svn.sourceforge.net/nmailserver/?rev=130&view=rev
Author: tmyroadctfig
Date: 2007-02-04 01:01:37 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Added some remote access details.
Modified Paths:
--------------
NMail/trunk/doc/NMail Developer's Guide.doc
Modified: NMail/trunk/doc/NMail Developer's Guide.doc
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-03 15:46:10
|
Revision: 129
http://svn.sourceforge.net/nmailserver/?rev=129&view=rev
Author: tmyroadctfig
Date: 2007-02-03 07:45:28 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Further work on WebAccess. Added some GPL and LGPL icons.
Modified Paths:
--------------
NMail/trunk/NMail/DataTypes/BodyStructure.cs
NMail/trunk/NMail/Helper/MimeHelper.cs
NMail/trunk/NMail/Helper/StringTokenizer.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs
NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx
NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Default.aspx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
NMail/trunk/NMail.WebAccess/Mail.aspx.cs
NMail/trunk/NMail.WebAccess/Web.config
Added Paths:
-----------
NMail/trunk/NMail.Server/Configuration/
NMail/trunk/NMail.Server/Configuration/ServerConfiguration.cs
NMail/trunk/NMail.WebAccess/App_Code/AttachmentDataSource.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx.cs
NMail/trunk/NMail.WebAccess/Images/Crystal/
NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/
NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/
NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic.png
NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic2.png
NMail/trunk/NMail.WebAccess/Images/Crystal/copyright
NMail/trunk/NMail.WebAccess/Images/CrystalClear/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/16x16/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/16x16/filesystems/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/16x16/filesystems/folder_grey.png
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/actions/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/actions/exit.png
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/apps/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/apps/cal.png
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/filesystems/
NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/filesystems/folder_grey.png
NMail/trunk/NMail.WebAccess/Images/CrystalClear/lgpl.txt
NMail/trunk/NMail.WebAccess/Images/Skins/Default/EmptyZone.png
Modified: NMail/trunk/NMail/DataTypes/BodyStructure.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/BodyStructure.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail/DataTypes/BodyStructure.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -49,6 +49,7 @@
}
public BodyStructure(MessageHeaders headers) {
+ this.headers = headers;
}
private MessageHeaders headers;
Modified: NMail/trunk/NMail/Helper/MimeHelper.cs
===================================================================
--- NMail/trunk/NMail/Helper/MimeHelper.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail/Helper/MimeHelper.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -17,6 +17,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
@@ -171,7 +172,8 @@
/// <returns>The parsed content type.</returns>
public static MimeContentType GetContentType(MessageHeaders headers) {
string temp;
- return GetContentType(headers[ContentTypeHeader], out temp);
+ Dictionary<string, string> temp2;
+ return GetContentType(headers[ContentTypeHeader], out temp, out temp2);
}
/// <summary>
@@ -180,9 +182,10 @@
/// </summary>
/// <param name="headers">The headers to get the content type from.</param>
/// <param name="subType">The detected sub-type.</param>
+ /// <param name="parameters">A list of parameters for the content type.</param>
/// <returns>The parsed content type.</returns>
- public static MimeContentType GetContentType(MessageHeaders headers, out string subType) {
- return GetContentType(headers[ContentTypeHeader], out subType);
+ public static MimeContentType GetContentType(MessageHeaders headers, out string subType, out Dictionary<string, string> parameters) {
+ return GetContentType(headers[ContentTypeHeader], out subType, out parameters);
}
/// <summary>
@@ -194,17 +197,40 @@
/// </remarks>
/// <param name="contentType">The header line to parse.</param>
/// <param name="subType">The detected sub-type.</param>
+ /// <param name="parameters">A list of parameters for the content type.</param>
/// <returns>The parsed content type.</returns>
- public static MimeContentType GetContentType(string contentType, out string subType) {
-
+ public static MimeContentType GetContentType(string contentType, out string subType, out Dictionary<string, string> parameters) {
+ parameters = new Dictionary<string, string>();
+
if (contentType == null) {
subType = "plain";
return MimeContentType.Text;
} else {
+ string type = null;
+
// Remove leading quotes
- string type = contentType.Replace("\"", string.Empty).Trim();
-
+ contentType = contentType.Replace("\"", string.Empty).Trim();
+
+ // Check for any parameters
+ int parameterStart = contentType.IndexOf(';');
+ if (parameterStart == -1) {
+ type = contentType;
+
+ } else {
+ type = contentType.Substring(0, parameterStart - 1);
+ string parameterList = contentType.Substring(parameterStart + 1);
+
+ // Parse out parameters
+ string[] parameterTokens = StringTokenizer.GetQuotedTokens(parameterList, ";".ToCharArray(), false);
+ for (int i = 0; i < parameterTokens.Length; i++) {
+ if (parameterTokens[i].IndexOf('=') != -1) {
+ string[] parameterParts = parameterTokens[i].Split("=".ToCharArray(), 2);
+ parameters.Add(parameterParts[0], parameterParts[1]);
+ }
+ }
+ }
+
// Chop at the slash
string[] tokens = type.Split("/".ToCharArray(), 2);
@@ -245,6 +271,29 @@
}
#endregion
+ #region Get Attachment Name
+ /// <summary>
+ /// Gets the name of an attachment.
+ /// </summary>
+ /// <param name="headers">The headers for the mime part to get the name for.</param>
+ /// <returns>The name or null if non is found.</returns>
+ public static string GetAttachmentName(MessageHeaders headers) {
+ string subType;
+ Dictionary<string, string> parameters;
+
+ GetContentType(headers, out subType, out parameters);
+
+ if (parameters.ContainsKey("name")) {
+ return parameters["name"];
+
+ } else if (parameters.ContainsKey("filename")) {
+ return parameters["filename"];
+ }
+
+ return null;
+ }
+ #endregion
+
#region GetBoundary
/// <summary>
/// Extracts the MIME boundary string from the given header.
Modified: NMail/trunk/NMail/Helper/StringTokenizer.cs
===================================================================
--- NMail/trunk/NMail/Helper/StringTokenizer.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail/Helper/StringTokenizer.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -63,6 +63,20 @@
/// </example>
/// <param name="data">The data to tokenise.</param>
/// <param name="delimiters">The delimiter to tokenise on.</param>
+ /// <param name="removeQuotes">Should quotes be removed from the extracted tokens.</param>
+ /// <returns>The array of tokens.</returns>
+ public static string[] GetQuotedTokens(string data, char[] delimiters, bool removeQuotes) {
+ return GetQuotedTokens(data, delimiters, Int32.MaxValue, removeQuotes);
+ }
+
+ /// <summary>
+ /// Gets a list of tokens respecting quotes.
+ /// </summary>
+ /// <example>
+ /// 'This "is a" string' would split into the following tokens: 'This' 'is a' 'string'.
+ /// </example>
+ /// <param name="data">The data to tokenise.</param>
+ /// <param name="delimiters">The delimiter to tokenise on.</param>
/// <param name="maximumTokens">The maximum number of tokens to return.</param>
/// <param name="removeQuotes">Should quotes be removed from the extracted tokens.</param>
/// <returns>The array of tokens.</returns>
Modified: NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -33,7 +33,7 @@
private List<BodyStructureSerializer> parts = new List<BodyStructureSerializer>();
public List<BodyStructureSerializer> Parts {
- get { return parts = new List<BodyStructureSerializer>(); }
+ get { return this.parts; }
}
}
}
Added: NMail/trunk/NMail.Server/Configuration/ServerConfiguration.cs
===================================================================
--- NMail/trunk/NMail.Server/Configuration/ServerConfiguration.cs (rev 0)
+++ NMail/trunk/NMail.Server/Configuration/ServerConfiguration.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Xml;
+using System.Configuration;
+using System.Net;
+
+using NMail.Configuration;
+using NMail.DataTypes;
+
+namespace NMail.Server.Configuration {
+ /// <summary>
+ /// Provides configuration settings for the NMail server implementation.
+ /// </summary>
+ public class ServerConfiguration : ConfigurationSection {
+ /// <summary>
+ /// Adds a server configuration section to the current config file.
+ /// </summary>
+ public static void AddToConfigFile() {
+ if (NMailConfigFile.Current.Sections["NMail.Server"] == null) {
+ NMailConfigFile.Current.Sections.Add("NMail.Server", new ServerConfiguration());
+ }
+ }
+
+ /// <summary>
+ /// Remove the config section from the config file.
+ /// </summary>
+ public static void RemoveFromConfigFile() {
+ if (NMailConfigFile.Current.Sections["NMail.Server"] != null) {
+ NMailConfigFile.Current.Sections.Remove("NMail.Server");
+ }
+ }
+
+ /// <summary>
+ /// Returns true if a server configuration section exists in the current
+ /// configuration.
+ /// </summary>
+ public static bool ConfigurationPresent {
+ get {
+ return (NMailConfigFile.Current.Sections["NMail.Server"] != null);
+ }
+ }
+
+ /// <summary>
+ /// The current configuration in use.
+ /// </summary>
+ public static ServerConfiguration Current {
+ get {
+ ServerConfiguration current;
+ current = (ServerConfiguration) NMailConfigFile.Current.GetSection("NMail.Server");
+
+ if (current == null) {
+ throw new ConfigurationErrorsException("NMail server configuration is missing");
+ }
+ return current;
+ }
+ }
+
+ /// <summary>
+ /// The list of users authorized to connect to the remote administration
+ /// remoting interface.
+ /// </summary>
+ [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))]
+ [ConfigurationProperty("RemoteAdminAuthorizedUsers")]
+ public CommaDelimitedStringCollection RemoteAdminAuthorizedUsers {
+ get {
+ return (CommaDelimitedStringCollection) this["RemoteAdminAuthorizedUsers"];
+ }
+ set {
+ this["RemoteAdminAuthorizedUsers"] = value;
+ }
+ }
+
+ /// <summary>
+ /// The list of interfaces authorized to connect to the remote administration
+ /// remoting interface.
+ /// </summary>
+ [ConfigurationProperty("RemoteAdminClients", IsDefaultCollection = false)]
+ [ConfigurationCollection(typeof(WildcardHostConfigurationElement), AddItemName = "Client",
+ ClearItemsName = "ClearClients", RemoveItemName = "RemoveClient")]
+ public WildcardHostElementCollection RemoteAdminClients {
+ get {
+ return (WildcardHostElementCollection) this["RemoteAdminClients"];
+ }
+ }
+ }
+}
Added: NMail/trunk/NMail.WebAccess/App_Code/AttachmentDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/AttachmentDataSource.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/AttachmentDataSource.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections.Generic;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.DataTypes;
+using NMail.Helper;
+
+namespace NMail.WebAccess
+{
+ /// <summary>
+ /// A data source for message attachments.
+ /// </summary>
+ public static class AttachmentDataSource
+ {
+ public static List<AttachmentDetails> GetAttachmentDetails(Message message)
+ {
+ List<AttachmentDetails> result = new List<AttachmentDetails>();
+
+ if (message.MultipartBody)
+ {
+ for (int i = 0; i < message.MimeParts.Count; i++)
+ {
+ result.Add(new AttachmentDetails(message.MimeParts[i], i + 1));
+ }
+ }
+
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Details for an attachment.
+ /// </summary>
+ public class AttachmentDetails
+ {
+ public AttachmentDetails(IMessageBodyPart mimePart, int partNumber)
+ {
+ this.partNumber = partNumber;
+
+ // Get the name of the attachment
+ this.name = MimeHelper.GetAttachmentName(mimePart.Headers);
+ if (name == null)
+ {
+ name = string.Format("Untitled: {0}", partNumber);
+ }
+
+ this.size = mimePart.BodyData.Length;
+
+ // Get the content type
+ Dictionary<string, string> parameters;
+ this.contentType = MimeHelper.GetContentType(mimePart.Headers, out this.contentSubType, out parameters);
+ }
+
+ private int partNumber;
+
+ /// <summary>
+ /// The part number for this attachment.
+ /// </summary>
+ public int PartNumber
+ {
+ get { return partNumber; }
+ set { partNumber = value; }
+ }
+
+ private string name;
+
+ /// <summary>
+ /// The filename for this attachment.
+ /// </summary>
+ public string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ private int size;
+
+ /// <summary>
+ /// The size of the attachment in bytes.
+ /// </summary>
+ public int Size
+ {
+ get { return size; }
+ set { size = value; }
+ }
+
+ private MimeContentType contentType;
+
+ /// <summary>
+ /// The content type for the attachment.
+ /// </summary>
+ public MimeContentType ContentType
+ {
+ get { return contentType; }
+ set { contentType = value; }
+ }
+
+ private string contentSubType;
+
+ /// <summary>
+ /// The content sub-type for the attachment.
+ /// </summary>
+ public string ContentSubType
+ {
+ get { return contentSubType; }
+ set { contentSubType = value; }
+ }
+ }
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/App_Code/LinkButtonListItem.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -17,8 +17,19 @@
this.clickHandler = clickHandler;
}
+ public LinkButtonListItem(string text, string itemStyleClass, string imageSkinId, EventHandler clickHandler)
+ {
+ this.text = text;
+ this.itemStyleClass = itemStyleClass;
+ this.imageSkinId = imageSkinId;
+ this.clickHandler = clickHandler;
+ }
+
private string text;
+ /// <summary>
+ /// The text of the link.
+ /// </summary>
public string Text
{
get
@@ -29,15 +40,30 @@
private string itemStyleClass;
+ /// <summary>
+ /// The style for the link button.
+ /// </summary>
public string ItemStyleClass
{
get { return itemStyleClass; }
set { itemStyleClass = value; }
}
-
+ private string imageSkinId;
+
+ /// <summary>
+ /// The Skin Id for the image.
+ /// </summary>
+ public string ImageSkinId
+ {
+ get { return imageSkinId; }
+ }
+
private EventHandler clickHandler;
+ /// <summary>
+ /// The handler executed when the link is clicked on.
+ /// </summary>
public EventHandler ClickHandler
{
get
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-02-03 15:45:28 UTC (rev 129)
@@ -8,8 +8,14 @@
a
{
color: #1e2e21;
+ text-decoration: none;
}
+a:hover
+{
+ text-decoration: underline;
+}
+
.LoginBody
{
font-family: Sans-Serif;
@@ -33,10 +39,9 @@
.ViewButton
{
- text-align: center;
background-color: #B8DECF;
height: 30px;
- vertical-align: middle;
+ vertical-align: text-bottom;
padding-left: 0.5em;
padding-right: 0.5em;
margin: 2px 2px 2px 2px;
@@ -60,6 +65,7 @@
{
width: 100%;
background-color: White;
+ overflow: auto;
}
.MailListSelectedItem
@@ -89,6 +95,11 @@
font-size: large;
}
+.WebPartTitleVerb
+{
+ font-size: medium;
+}
+
.WebPart
{
background-color: White;
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-02-03 15:45:28 UTC (rev 129)
@@ -15,4 +15,13 @@
*
--%>
+<%@ Register Src="~/Controls/Mail/SubscribedFolderList.ascx" TagName="SubscribedFolderList" TagPrefix="uc2" %>
+
+
<asp:Image runat="server" SkinId="LoginBanner" ImageUrl="~/Images/Skins/Default/LoginBanner.jpg" />
+
+<asp:Image runat="server" SkinId="MailButtonImage" ImageUrl="~/Images/Crystal/22x22/actions/mail_generic.png" />
+<asp:Image runat="server" SkinId="CalendarButtonImage" ImageUrl="~/Images/CrystalClear/22x22/apps/cal.png" />
+<asp:Image runat="server" SkinId="LogoutButtonImage" ImageUrl="~/Images/CrystalClear/22x22/actions/exit.png" />
+
+<uc2:SubscribedFolderList runat="server" SkinID="FolderList" TitleIconImageUrl="~/Images/CrystalClear/22x22/filesystems/folder_grey.png" FolderImageUrl="~/Images/CrystalClear/16x16/filesystems/folder_grey.png" />
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx 2007-02-03 15:45:28 UTC (rev 129)
@@ -20,7 +20,7 @@
<asp:Repeater ID="Repeater" runat="server">
<ItemTemplate>
<div class='<%# Eval("ItemStyleClass") %>'>
- <asp:LinkButton runat="server" ID="LinkButton" Text='<%# Eval("Text") %>' />
+ <asp:LinkButton runat="server" ID="LinkButton" />
</div>
</ItemTemplate>
</asp:Repeater>
Modified: NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -49,6 +49,19 @@
// Link this task's button with its click handler
LinkButton button = (LinkButton)control;
button.Click += item.ClickHandler;
+
+ // Add an image if available
+ if (item.ImageSkinId != null)
+ {
+ Image image = new Image();
+ image.SkinID = item.ImageSkinId;
+ button.Controls.Add(image);
+ }
+
+ // Add the text
+ Literal text = new Literal();
+ text.Text = item.Text;
+ button.Controls.Add(text);
}
}
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,18 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Attachment.aspx.cs" Inherits="Controls_Mail_Attachment" %>
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/Attachment.aspx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Text;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.DataTypes;
+using NMail.Helper;
+
+/// <summary>
+/// The code for the mail attachment form.
+/// </summary>
+public partial class Controls_Mail_Attachment : System.Web.UI.Page
+{
+ private int partNumber = -1;
+
+ /// <summary>
+ /// The MIME part to download.
+ /// </summary>
+ public int PartNumber
+ {
+ get { return partNumber; }
+ }
+
+ private int messageId = -1;
+
+ /// <summary>
+ /// The message Id displayed in the page.
+ /// </summary>
+ public int MessageId
+ {
+ get { return messageId; }
+ }
+
+ private int folderId = -1;
+
+ /// <summary>
+ /// The folder the message is in.
+ /// </summary>
+ public int FolderId
+ {
+ get { return folderId; }
+ }
+
+ /// <summary>
+ /// Extracts the message and folder Ids and part number from the query string.
+ /// </summary>
+ protected void ExtractQueryStringParams()
+ {
+ foreach (string key in Request.QueryString.AllKeys)
+ {
+ if (key.Trim().ToLower() == "messageid")
+ {
+ this.messageId = Int32.Parse(Request.QueryString[key]);
+ }
+ else if (key.Trim().ToLower() == "folderid")
+ {
+ this.folderId = Int32.Parse(Request.QueryString[key]);
+ }
+ else if (key.Trim().ToLower() == "partNumber")
+ {
+ this.partNumber = Int32.Parse(Request.QueryString[key]);
+ }
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ ExtractQueryStringParams();
+
+ // Ensure there is a valid folder Id
+ if (this.folderId == -1)
+ {
+ throw new ArgumentException("No folder selected.");
+ return;
+ }
+
+ // Ensure there is a valid message Id
+ if (this.messageId == -1)
+ {
+ throw new ArgumentException("No message selected.");
+ return;
+ }
+
+ // Ensure there is a valid part number
+ if (this.partNumber == -1)
+ {
+ throw new ArgumentException("No MIME part selected.");
+ return;
+ }
+
+ // Get our session variables
+ string authToken = (string)Session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)Session["RAS"];
+
+ // Get the part to send
+ string base64Body = ras.GetMessageMimePart(authToken, this.partNumber, this.messageId, this.folderId);
+ ByteString bodyData = new ByteString(Convert.FromBase64String(base64Body), Encoding.UTF8);
+ SimpleBodyPart body = MessageHelper.ParseMessage(bodyData);
+
+ // Send the part to the client
+ Response.ContentType = body.Headers["Content-type"];
+ Response.Write(body.BodyData.ToString());
+ }
+}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx 2007-02-03 15:45:28 UTC (rev 129)
@@ -28,7 +28,7 @@
<div>
<h1>Error</h1>
An error has occurred trying to view your message or download an attachment.
- Click <a onclick="refresh()">here</a> to try again.
+ Click <a onclick="window.location.reload(false)">here</a> to try again.
</div>
</form>
</body>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -19,9 +19,11 @@
using System.Data;
using System.Configuration;
using System.Collections;
+using System.ComponentModel;
using System.Web;
using System.Web.Security;
using System.Web.UI;
+using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
@@ -31,6 +33,8 @@
/// <summary>
/// The code for the mail list control.
/// </summary>
+[Designer(typeof(ControlDesigner))]
+[Themeable(true)]
public partial class Controls_Mail_MailList : System.Web.UI.UserControl, IWebPart
{
protected void Page_Init(object sender, EventArgs e)
@@ -159,7 +163,7 @@
{
get
{
- return (this.folderName == null) ? " " : this.folderName;
+ return (this.folderName == null) ? "No folder selected" : this.folderName;
}
set
{
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-02-03 15:45:28 UTC (rev 129)
@@ -33,9 +33,11 @@
<!-- The attachments -->
<asp:Repeater ID="AttachmentsRepeater" runat="server">
<ItemTemplate>
- <!-- Name -->
- <!-- Size -->
- <!-- Type -->
+ <asp:LinkButton ID="AttachmentDownloadButton" runat="server">
+ <asp:Image ID="AttachmentImage" runat="server" />
+ <asp:Label ID="AttachmentNameLbl" runat="server" />
+ <asp:Label ID="SizeLbl" runat="server" />
+ </asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
</div>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -19,6 +19,7 @@
using System.Data;
using System.Configuration;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web;
@@ -38,7 +39,7 @@
/// </summary>
public partial class Controls_Mail_MessageBody : System.Web.UI.Page
{
- private int messageId;
+ private int messageId = -1;
/// <summary>
/// The message Id displayed in the page.
@@ -48,7 +49,7 @@
get { return messageId; }
}
- private int folderId;
+ private int folderId = -1;
/// <summary>
/// The folder the message is in.
@@ -56,6 +57,16 @@
public int FolderId
{
get { return folderId; }
+ }
+
+ private Message message;
+
+ /// <summary>
+ /// The message displayed in this form.
+ /// </summary>
+ public Message Message
+ {
+ get { return message; }
}
/// <summary>
@@ -99,8 +110,9 @@
// Search for the best part
for (int i = 0; i < bodyStructure.Count; i++)
{
+ Dictionary<string, string> parameters;
string subType;
- MimeContentType contentType = MimeHelper.GetContentType(bodyStructure[i].Headers, out subType);
+ MimeContentType contentType = MimeHelper.GetContentType(bodyStructure[i].Headers, out subType, out parameters);
if (contentType == MimeContentType.Text)
{
@@ -118,10 +130,10 @@
}
}
- protected void Page_Load(object sender, EventArgs e)
- {
+ protected void Page_Init(object sender, EventArgs e)
+ {
ExtractQueryStringParams();
-
+
// Ensure there is a valid folder Id
if (this.folderId == -1)
{
@@ -139,8 +151,8 @@
}
// Get our session variables
- string authToken = (string) Session["AuthToken"];
- RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService) Session["RAS"];
+ string authToken = (string)Session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)Session["RAS"];
// Get the body structure
BodyStructureSerializer bs = ras.GetMessageStructure(authToken, messageId, folderId);
@@ -150,20 +162,52 @@
int bodyPartNumber;
bool htmlBody;
FindMimePartToDisplay(bodyStructure, out bodyPartNumber, out htmlBody);
-
+
// Get the part to display
string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, folderId);
ByteString bodyData = new ByteString(Convert.FromBase64String(base64Body), Encoding.UTF8);
- SimpleBodyPart body = MessageHelper.ParseMessage(bodyData);
+ this.message = new Message(bodyData);
// Ensure all nasty stuff is escaped
if (htmlBody)
{
- this.MessageBody.Text = HtmlEscaper.EscapeScriptsAndImages(body.Data.ToString());
+ this.MessageBody.Text = HtmlEscaper.EscapeScriptsAndImages(this.message.Data.ToString());
}
else
{
- this.MessageBody.Text = HtmlEscaper.EscapeAll(body.Data.ToString());
+ this.MessageBody.Text = HtmlEscaper.EscapeAll(this.message.Data.ToString());
}
- }
+
+ this.AttachmentsRepeater.ItemDataBound += new RepeaterItemEventHandler(AttachmentsRepeater_ItemDataBound);
+ }
+
+ protected void Page_PreRender(object sender, EventArgs e)
+ {
+ // Setup and bind to the data source
+ ObjectDataSource attachmentDataSource = new ObjectDataSource("NMail.WebAccess.AttachmentDataSource", "GetAttachmentDetails");
+ attachmentDataSource.Selecting += new ObjectDataSourceSelectingEventHandler(attachmentDataSource_Selecting);
+
+ this.AttachmentsRepeater.DataSource = attachmentDataSource;
+ this.AttachmentsRepeater.DataBind();
+ }
+
+ void attachmentDataSource_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
+ {
+ e.InputParameters.Add("message", this.message);
+ }
+
+ void AttachmentsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
+ {
+ LinkButton downloadButton = (LinkButton) e.Item.FindControl("AttachmentDownloadButton");
+ Image image = (Image) e.Item.FindControl("AttachmentImage");
+ Label name = (Label) e.Item.FindControl("AttachmentNameLbl");
+ Label size = (Label) e.Item.FindControl("SizeLbl");
+ AttachmentDetails item = (AttachmentDetails)e.Item.DataItem;
+
+ if (downloadButton != null && image != null && name != null && size != null && item != null)
+ {
+ name.Text = item.Name;
+ size.Text = string.Format("{0} bytes", item.Size);
+ }
+ }
}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -142,7 +142,7 @@
get { return null; }
}
- private string title = " ";
+ private string title = "No message selected";
public string Title
{
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -19,10 +19,12 @@
using System.Data;
using System.Configuration;
using System.Collections;
+using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
+using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
@@ -32,7 +34,9 @@
/// <summary>
/// The code for the subscribed folder list control.
/// </summary>
-public partial class Controls_Mail_SubscribedFolderList : System.Web.UI.UserControl
+[Designer(typeof(ControlDesigner))]
+[Themeable(true)]
+public partial class Controls_Mail_SubscribedFolderList : System.Web.UI.UserControl, IWebPart
{
protected void Page_Init(object sender, EventArgs e)
{
@@ -71,6 +75,7 @@
result.Append("<span class='");
+ // Add the folder style name
if (f.UnreadMessages > 0)
{
result.Append("SubscribedFolderUnread");
@@ -81,6 +86,12 @@
}
result.Append("'>");
+ // Add the folder image if present
+ if (this.folderImageUrl != null)
+ {
+ result.Append(string.Format("<img style='border: 0px' src='{0}' /> ", ResolveUrl(this.folderImageUrl)));
+ }
+
result.Append(f.FullFolderName);
if (f.UnreadMessages > 0) {
@@ -103,6 +114,17 @@
}
}
+ private string folderImageUrl;
+
+ /// <summary>
+ /// The URL of the image to show next to the folders.
+ /// </summary>
+ public string FolderImageUrl
+ {
+ get { return folderImageUrl; }
+ set { folderImageUrl = value; }
+ }
+
private event EventHandler selectedFolderIdChanged;
/// <summary>
@@ -119,4 +141,80 @@
this.selectedFolderIdChanged -= value;
}
}
+
+ #region IWebPart Members
+
+ private string catalogIconImageUrl;
+
+ public string CatalogIconImageUrl
+ {
+ get
+ {
+ return this.catalogIconImageUrl;
+ }
+ set
+ {
+ this.catalogIconImageUrl = value;
+ }
+ }
+
+ private string description = "Displays the list of subscribed folders.";
+
+ public string Description
+ {
+ get
+ {
+ return this.description;
+ }
+ set
+ {
+ this.description = value;
+ }
+ }
+
+ public string Subtitle
+ {
+ get { return null; }
+ }
+
+ public string Title
+ {
+ get
+ {
+ return string.Format("{0}'s Folders", HttpContext.Current.User.Identity.Name);
+ }
+ set
+ {
+ throw new NotSupportedException("Can't set the title manually for the subscribed folder list.");
+ }
+ }
+
+ private string titleIconImageUrl;
+
+ public string TitleIconImageUrl
+ {
+ get
+ {
+ return this.titleIconImageUrl;
+ }
+ set
+ {
+ this.titleIconImageUrl = value;
+ }
+ }
+
+ private string titleUrl;
+
+ public string TitleUrl
+ {
+ get
+ {
+ return this.titleUrl;
+ }
+ set
+ {
+ this.titleUrl = value;
+ }
+ }
+ #endregion
}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Default.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Default.aspx.cs 2007-02-03 08:36:53 UTC (rev 128)
+++ NMail/trunk/NMail.WebAccess/Default.aspx.cs 2007-02-03 15:45:28 UTC (rev 129)
@@ -19,8 +19,9 @@
// Setup the view list
List<LinkButtonListItem> viewItems = new List<LinkButtonListItem>();
- viewItems.Add(new LinkButtonListItem("Mail", "ViewButton", new EventHandler(ShowMailView_Clicked)));
- viewItems.Add(new LinkButtonListItem("Calendar", "ViewButton", new EventHandler(ShowCalendarView_Clicked)));
+ viewItems.Add(new LinkButtonListItem(" Mail", "ViewButton", "MailButtonImage", new EventHandler(ShowMailView_Clicked)));
+ viewItems.Add(new LinkButtonListItem(" Calendar", "ViewButton", "CalendarButtonImage", new EventHandler(ShowCalendarView_Clicked)));
+ viewItems.Add(new LinkButtonListItem(" Logout", "ViewButton", "LogoutButtonImage", new EventHandler(Logout_Clicked)));
this.ViewList.SetListItems(viewItems);
}
@@ -33,4 +34,11 @@
protected void ShowCalendarView_Clicked(object sender, EventArgs ea)
{
}
+
+ protected void Logout_Clicked(object sender, EventArgs ea)
+ {
+ Session.Abandon();
+ FormsAuthentication.SignOut();
+ FormsAuthentication.RedirectToLoginPage();
+ }
}
Added: NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic2.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/Crystal/22x22/actions/mail_generic2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/Crystal/copyright
===================================================================
--- NMail/trunk/NMail.WebAccess/Images/Crystal/copyright (rev 0)
+++ NMail/trunk/NMail.WebAccess/Images/Crystal/copyright 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,30 @@
+This package was debianized by Morten Hustveit <mo...@if...> on
+Sun, 2 Jun 2002 21:37:04 +0200.
+
+It was downloaded from:
+ftp://ftp.everaldo.com/crystal/crystal_beta.tar.gz
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+On Debian systems, the complete text of the GNU General Public
+License can be found in `/usr/share/common-licenses/GPL'.
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1 or
+ any later version published by the Free Software Foundation; with no
+ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+ Texts. A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
Added: NMail/trunk/NMail.WebAccess/Images/CrystalClear/16x16/filesystems/folder_grey.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/CrystalClear/16x16/filesystems/folder_grey.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/actions/exit.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/actions/exit.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/apps/cal.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/apps/cal.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/filesystems/folder_grey.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/CrystalClear/22x22/filesystems/folder_grey.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/CrystalClear/lgpl.txt
===================================================================
--- NMail/trunk/NMail.WebAccess/Images/CrystalClear/lgpl.txt (rev 0)
+++ NMail/trunk/NMail.WebAccess/Images/CrystalClear/lgpl.txt 2007-02-03 15:45:28 UTC (rev 129)
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operatin...
[truncated message content] |
|
From: <tmy...@us...> - 2007-02-03 08:37:07
|
Revision: 128
http://svn.sourceforge.net/nmailserver/?rev=128&view=rev
Author: tmyroadctfig
Date: 2007-02-03 00:36:53 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Added authorization checks to the remote administration interface.
Modified Paths:
--------------
NMail/trunk/NMail.Server/NMail.Server.csproj
NMail/trunk/NMail.Server/RemoteAdminAuthorisation.cs
NMail/trunk/NMail.Server.Console/NMail.config
NMail/trunk/NMail.Server.Console/NMailConsoleServer.cs
Modified: NMail/trunk/NMail.Server/NMail.Server.csproj
===================================================================
--- NMail/trunk/NMail.Server/NMail.Server.csproj 2007-02-02 10:47:18 UTC (rev 127)
+++ NMail/trunk/NMail.Server/NMail.Server.csproj 2007-02-03 08:36:53 UTC (rev 128)
@@ -105,6 +105,7 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Configuration\ServerConfiguration.cs" />
<Compile Include="NMailServer.cs">
<SubType>Code</SubType>
</Compile>
Modified: NMail/trunk/NMail.Server/RemoteAdminAuthorisation.cs
===================================================================
--- NMail/trunk/NMail.Server/RemoteAdminAuthorisation.cs 2007-02-02 10:47:18 UTC (rev 127)
+++ NMail/trunk/NMail.Server/RemoteAdminAuthorisation.cs 2007-02-03 08:36:53 UTC (rev 128)
@@ -1,23 +1,98 @@
using System;
using System.Collections.Generic;
+using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Security.Principal;
using System.Runtime.Remoting.Channels;
using System.Text;
+using log4net;
+
+using NMail.Configuration;
+using NMail.Server.Configuration;
+
namespace NMail.Server {
+ /// <summary>
+ /// A class used to check authorisation of remote administration clients.
+ /// </summary>
public class RemoteAdminAuthorisation : IAuthorizeRemotingConnection {
+ /// <summary>
+ /// Logging support for this class.
+ /// </summary>
+ private static ILog log = LogManager.GetLogger(typeof(RemoteAdminAuthorisation));
+
#region IAuthorizeRemotingConnection Members
+ /// <summary>
+ /// Gets a Boolean value that indicates whether the network address of
+ /// the client is authorized to connect on the current channel.
+ /// </summary>
+ /// <param name="endPoint">
+ /// The EndPoint that identifies the network address of the client.
+ /// </param>
+ /// <returns>
+ /// True if the network address of the client is authorized; otherwise, false.
+ /// </returns>
+ public bool IsConnectingEndPointAuthorized(EndPoint endPoint) {
+ // We only support IP clients
+ if (endPoint.AddressFamily != AddressFamily.InterNetwork &&
+ endPoint.AddressFamily != AddressFamily.InterNetworkV6) {
- public bool IsConnectingEndPointAuthorized(EndPoint endPoint) {
- // TODO: check for a valid address here
- return true;
+ log.Debug(string.Format("Connection attempt from non-IP client. {0}", endPoint.AddressFamily));
+ return false;
+ }
+
+ WildcardHostElementCollection remoteAdminClients = ServerConfiguration.Current.RemoteAdminClients;
+ IPAddress clientAddress = ((IPEndPoint) endPoint).Address;
+
+ // If no clients are specified only local host clients are allowed
+ if (remoteAdminClients == null || remoteAdminClients.Count == 0) {
+ log.Info(string.Format("Connection from (only accept from localhost): {0}", clientAddress));
+ return (clientAddress.Equals(IPAddress.Loopback) || clientAddress.Equals(IPAddress.IPv6Loopback));
+ }
+
+ // Check the list of allowed clients
+ for (int i = 0; i < remoteAdminClients.Count; i++) {
+ if (remoteAdminClients[i].MatchWildcardHost.MatchesSubnet(clientAddress)) {
+ log.Info(string.Format("Connection from: {0}", clientAddress));
+ return true;
+ }
+ }
+
+ log.Info(string.Format("Failed connection from: {0}", clientAddress));
+ return false;
}
+ /// <summary>
+ /// Gets a Boolean value that indicates whether the user identity of the client
+ /// is authorized to connect on the current channel.
+ /// </summary>
+ /// <param name="identity">
+ /// The IIdentity that represents the user identity of the client.
+ /// </param>
+ /// <returns>
+ /// True if the user identity of the client is authorized; otherwise, false.
+ /// </returns>
public bool IsConnectingIdentityAuthorized(IIdentity identity) {
- // TODO: check for a valid username here
- return identity.IsAuthenticated;
+ string connectingUser = identity.Name.Trim().ToLower();
+ CommaDelimitedStringCollection remoteAdminUsers = ServerConfiguration.Current.RemoteAdminAuthorizedUsers;
+
+ if (remoteAdminUsers == null) {
+ log.Info(string.Format("Failed connection from user (not accepting connections): {0}", connectingUser));
+ return false;
+ }
+
+ // Check if the user is in the list of allowed users
+ for (int i = 0; i < remoteAdminUsers.Count; i++) {
+ if (connectingUser.Equals(remoteAdminUsers[i].Trim().ToLower())) {
+ // They also have to be authenticated
+ log.Info(string.Format("Connection from: '{0}' Authenticated: {1}", connectingUser, identity.IsAuthenticated));
+ return identity.IsAuthenticated;
+ }
+ }
+
+ log.Info(string.Format("Failed connection from user: {0}", connectingUser));
+ return false;
}
#endregion
}
Modified: NMail/trunk/NMail.Server.Console/NMail.config
===================================================================
--- NMail/trunk/NMail.Server.Console/NMail.config 2007-02-02 10:47:18 UTC (rev 127)
+++ NMail/trunk/NMail.Server.Console/NMail.config 2007-02-03 08:36:53 UTC (rev 128)
@@ -2,6 +2,7 @@
<configuration>
<configSections>
<section name="NMail" type="NMail.Configuration.NMailConfiguration, NMail" />
+ <section name="NMail.Server" type="NMail.Server.Configuration.ServerConfiguration, NMail.Server" />
<section name="NMail.SmtpService" type="NMail.SmtpService.Configuration.SmtpServiceConfiguration, NMail.SmtpService" />
<section name="NMail.DnsClient" type="NMail.DnsClient.Configuration.DnsClientConfiguration, NMail.DnsClient" />
<section name="NMail.ImapService" type="NMail.ImapService.Configuration.ImapServiceConfiguration, NMail.ImapService" />
@@ -34,6 +35,15 @@
</NamedServices>
</NMail>
+ <NMail.Server
+ RemoteAdminAuthorizedUsers="niknak\luke">
+
+ <RemoteAdminClients>
+ <Client Match="127.0.0.1/32" />
+ <Client Match="192.168.5.0/24" />
+ </RemoteAdminClients>
+ </NMail.Server>
+
<NMail.MessageRouter
VisibleHost="localhost"
WarningTemplate="Warning.txt"
Modified: NMail/trunk/NMail.Server.Console/NMailConsoleServer.cs
===================================================================
--- NMail/trunk/NMail.Server.Console/NMailConsoleServer.cs 2007-02-02 10:47:18 UTC (rev 127)
+++ NMail/trunk/NMail.Server.Console/NMailConsoleServer.cs 2007-02-03 08:36:53 UTC (rev 128)
@@ -28,6 +28,9 @@
/// Provides a console server implementation for NMail.
/// </summary>
class NMailConsoleServer {
+ /// <summary>
+ /// Logging support for this class.
+ /// </summary>
private static ILog log = LogManager.GetLogger(typeof(NMailConsoleServer));
/// <summary>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-02 10:47:19
|
Revision: 127
http://svn.sourceforge.net/nmailserver/?rev=127&view=rev
Author: tmyroadctfig
Date: 2007-02-02 02:47:18 -0800 (Fri, 02 Feb 2007)
Log Message:
-----------
Added some RFCs.
Added Paths:
-----------
NMail/trunk/doc/RFC/Calendar/
NMail/trunk/doc/RFC/Calendar/rfc2445_iCalendar.txt
NMail/trunk/doc/RFC/Calendar/rfc4324_CAP.txt
NMail/trunk/doc/RFC/MIME/rfc2048_mime_part4.txt
Added: NMail/trunk/doc/RFC/Calendar/rfc2445_iCalendar.txt
===================================================================
--- NMail/trunk/doc/RFC/Calendar/rfc2445_iCalendar.txt (rev 0)
+++ NMail/trunk/doc/RFC/Calendar/rfc2445_iCalendar.txt 2007-02-02 10:47:18 UTC (rev 127)
@@ -0,0 +1,8291 @@
+
+
+
+
+
+
+Network Working Group F. Dawson
+Request for Comments: 2445 Lotus
+Category: Standards Track D. Stenerson
+ Microsoft
+ November 1998
+
+
+ Internet Calendaring and Scheduling Core Object Specification
+ (iCalendar)
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1998). All Rights Reserved.
+
+Abstract
+
+ There is a clear need to provide and deploy interoperable calendaring
+ and scheduling services for the Internet. Current group scheduling
+ and Personal Information Management (PIM) products are being extended
+ for use across the Internet, today, in proprietary ways. This memo
+ has been defined to provide the definition of a common format for
+ openly exchanging calendaring and scheduling information across the
+ Internet.
+
+ This memo is formatted as a registration for a MIME media type per
+ [RFC 2048]. However, the format in this memo is equally applicable
+ for use outside of a MIME message content type.
+
+ The proposed media type value is 'text/calendar'. This string would
+ label a media type containing calendaring and scheduling information
+ encoded as text characters formatted in a manner outlined below.
+
+ This MIME media type provides a standard content type for capturing
+ calendar event, to-do and journal entry information. It also can be
+ used to convey free/busy time information. The content type is
+ suitable as a MIME message entity that can be transferred over MIME
+ based email systems, using HTTP or some other Internet transport. In
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 1]
+
+RFC 2445 iCalendar November 1998
+
+
+ addition, the content type is useful as an object for interactions
+ between desktop applications using the operating system clipboard,
+ drag/drop or file systems capabilities.
+
+ This memo is based on the earlier work of the vCalendar specification
+ for the exchange of personal calendaring and scheduling information.
+ In order to avoid confusion with this referenced work, this memo is
+ to be known as the iCalendar specification.
+
+ This memo defines the format for specifying iCalendar object methods.
+ An iCalendar object method is a set of usage constraints for the
+ iCalendar object. For example, these methods might define scheduling
+ messages that request an event be scheduled, reply to an event
+ request, send a cancellation notice for an event, modify or replace
+ the definition of an event, provide a counter proposal for an
+ original event request, delegate an event request to another
+ individual, request free or busy time, reply to a free or busy time
+ request, or provide similar scheduling messages for a to-do or
+ journal entry calendar component. The iCalendar Transport-indendent
+ Interoperability Protocol (iTIP) defined in [ITIP] is one such
+ scheduling protocol.
+
+Table of Contents
+
+ 1 Introduction.....................................................5
+ 2 Basic Grammar and Conventions....................................6
+ 2.1 Formatting Conventions .......................................7
+ 2.2 Related Memos ................................................8
+ 2.3 International Considerations .................................8
+ 3 Registration Information.........................................8
+ 3.1 Content Type .................................................8
+ 3.2 Parameters ...................................................9
+ 3.3 Content Header Fields .......................................10
+ 3.4 Encoding Considerations .....................................10
+ 3.5 Security Considerations .....................................10
+ 3.6 Interoperability Considerations .............................11
+ 3.7 Applications Which Use This Media Type ......................11
+ 3.8 Additional Information ......................................11
+ 3.9 Magic Numbers ...............................................11
+ 3.10 File Extensions ............................................11
+ 3.11 Contact for Further Information: ...........................12
+ 3.12 Intended Usage .............................................12
+ 3.13 Authors/Change Controllers .................................12
+ 4 iCalendar Object Specification..................................13
+ 4.1 Content Lines ...............................................13
+ 4.1.1 List and Field Separators ................................16
+ 4.1.2 Multiple Values ..........................................16
+ 4.1.3 Binary Content ...........................................16
+
+
+
+Dawson & Stenerson Standards Track [Page 2]
+
+RFC 2445 iCalendar November 1998
+
+
+ 4.1.4 Character Set ............................................17
+ 4.2 Property Parameters .........................................17
+ 4.2.1 Alternate Text Representation ............................18
+ 4.2.2 Common Name ..............................................19
+ 4.2.3 Calendar User Type .......................................20
+ 4.2.4 Delegators ...............................................20
+ 4.2.5 Delegatees ...............................................21
+ 4.2.6 Directory Entry Reference ................................21
+ 4.2.7 Inline Encoding ..........................................22
+ 4.2.8 Format Type ..............................................23
+ 4.2.9 Free/Busy Time Type ......................................23
+ 4.2.10 Language ................................................24
+ 4.2.11 Group or List Membership ................................25
+ 4.2.12 Participation Status ....................................25
+ 4.2.13 Recurrence Identifier Range .............................27
+ 4.2.14 Alarm Trigger Relationship ..............................27
+ 4.2.15 Relationship Type .......................................28
+ 4.2.16 Participation Role ......................................29
+ 4.2.17 RSVP Expectation ........................................29
+ 4.2.18 Sent By .................................................30
+ 4.2.19 Time Zone Identifier ....................................30
+ 4.2.20 Value Data Types ........................................32
+ 4.3 Property Value Data Types ...................................32
+ 4.3.1 Binary ...................................................33
+ 4.3.2 Boolean ..................................................33
+ 4.3.3 Calendar User Address ....................................34
+ 4.3.4 Date .....................................................34
+ 4.3.5 Date-Time ................................................35
+ 4.3.6 Duration .................................................37
+ 4.3.7 Float ....................................................38
+ 4.3.8 Integer ..................................................38
+ 4.3.9 Period of Time ...........................................39
+ 4.3.10 Recurrence Rule .........................................40
+ 4.3.11 Text ....................................................45
+ 4.3.12 Time ....................................................47
+ 4.3.13 URI .....................................................49
+ 4.3.14 UTC Offset ..............................................49
+ 4.4 iCalendar Object ............................................50
+ 4.5 Property ....................................................51
+ 4.6 Calendar Components .........................................51
+ 4.6.1 Event Component ..........................................52
+ 4.6.2 To-do Component ..........................................55
+ 4.6.3 Journal Component ........................................56
+ 4.6.4 Free/Busy Component ......................................58
+ 4.6.5 Time Zone Component ......................................60
+ 4.6.6 Alarm Component ..........................................67
+ 4.7 Calendar Properties .........................................73
+ 4.7.1 Calendar Scale ...........................................73
+
+
+
+Dawson & Stenerson Standards Track [Page 3]
+
+RFC 2445 iCalendar November 1998
+
+
+ 4.7.2 Method ...................................................74
+ 4.7.3 Product Identifier .......................................75
+ 4.7.4 Version ..................................................76
+ 4.8 Component Properties ........................................77
+ 4.8.1 Descriptive Component Properties .........................77
+ 4.8.1.1 Attachment ...........................................77
+ 4.8.1.2 Categories ...........................................78
+ 4.8.1.3 Classification .......................................79
+ 4.8.1.4 Comment ..............................................80
+ 4.8.1.5 Description ..........................................81
+ 4.8.1.6 Geographic Position ..................................82
+ 4.8.1.7 Location .............................................84
+ 4.8.1.8 Percent Complete .....................................85
+ 4.8.1.9 Priority .............................................85
+ 4.8.1.10 Resources ...........................................87
+ 4.8.1.11 Status ..............................................88
+ 4.8.1.12 Summary .............................................89
+ 4.8.2 Date and Time Component Properties .......................90
+ 4.8.2.1 Date/Time Completed ..................................90
+ 4.8.2.2 Date/Time End ........................................91
+ 4.8.2.3 Date/Time Due ........................................92
+ 4.8.2.4 Date/Time Start ......................................93
+ 4.8.2.5 Duration .............................................94
+ 4.8.2.6 Free/Busy Time .......................................95
+ 4.8.2.7 Time Transparency ....................................96
+ 4.8.3 Time Zone Component Properties ...........................97
+ 4.8.3.1 Time Zone Identifier .................................97
+ 4.8.3.2 Time Zone Name .......................................98
+ 4.8.3.3 Time Zone Offset From ................................99
+ 4.8.3.4 Time Zone Offset To .................................100
+ 4.8.3.5 Time Zone URL .......................................101
+ 4.8.4 Relationship Component Properties .......................102
+ 4.8.4.1 Attendee ............................................102
+ 4.8.4.2 Contact .............................................104
+ 4.8.4.3 Organizer ...........................................106
+ 4.8.4.4 Recurrence ID .......................................107
+ 4.8.4.5 Related To ..........................................109
+ 4.8.4.6 Uniform Resource Locator ............................110
+ 4.8.4.7 Unique Identifier ...................................111
+ 4.8.5 Recurrence Component Properties .........................112
+ 4.8.5.1 Exception Date/Times ................................112
+ 4.8.5.2 Exception Rule ......................................114
+ 4.8.5.3 Recurrence Date/Times ...............................115
+ 4.8.5.4 Recurrence Rule .....................................117
+ 4.8.6 Alarm Component Properties ..............................126
+ 4.8.6.1 Action ..............................................126
+ 4.8.6.2 Repeat Count ........................................126
+ 4.8.6.3 Trigger .............................................127
+
+
+
+Dawson & Stenerson Standards Track [Page 4]
+
+RFC 2445 iCalendar November 1998
+
+
+ 4.8.7 Change Management Component Properties ..................129
+ 4.8.7.1 Date/Time Created ...................................129
+ 4.8.7.2 Date/Time Stamp .....................................130
+ 4.8.7.3 Last Modified .......................................131
+ 4.8.7.4 Sequence Number .....................................131
+ 4.8.8 Miscellaneous Component Properties ......................133
+ 4.8.8.1 Non-standard Properties .............................133
+ 4.8.8.2 Request Status ......................................134
+ 5 iCalendar Object Examples......................................136
+ 6 Recommended Practices..........................................140
+ 7 Registration of Content Type Elements..........................141
+ 7.1 Registration of New and Modified iCalendar Object Methods ..141
+ 7.2 Registration of New Properties .............................141
+ 7.2.1 Define the property .....................................142
+ 7.2.2 Post the Property definition ............................143
+ 7.2.3 Allow a comment period ..................................143
+ 7.2.4 Submit the property for approval ........................143
+ 7.3 Property Change Control ....................................143
+ 8 References.....................................................144
+ 9 Acknowledgments................................................145
+ 10 Authors' and Chairs' Addresses................................146
+ 11 Full Copyright Statement......................................148
+
+1 Introduction
+
+ The use of calendaring and scheduling has grown considerably in the
+ last decade. Enterprise and inter-enterprise business has become
+ dependent on rapid scheduling of events and actions using this
+ information technology. However, the longer term growth of
+ calendaring and scheduling, is currently limited by the lack of
+ Internet standards for the message content types that are central to
+ these knowledgeware applications. This memo is intended to progress
+ the level of interoperability possible between dissimilar calendaring
+ and scheduling applications. This memo defines a MIME content type
+ for exchanging electronic calendaring and scheduling information. The
+ Internet Calendaring and Scheduling Core Object Specification, or
+ iCalendar, allows for the capture and exchange of information
+ normally stored within a calendaring and scheduling application; such
+ as a Personal Information Manager (PIM) or a Group Scheduling
+ product.
+
+ The iCalendar format is suitable as an exchange format between
+ applications or systems. The format is defined in terms of a MIME
+ content type. This will enable the object to be exchanged using
+ several transports, including but not limited to SMTP, HTTP, a file
+ system, desktop interactive protocols such as the use of a memory-
+ based clipboard or drag/drop interactions, point-to-point
+ asynchronous communication, wired-network transport, or some form of
+
+
+
+Dawson & Stenerson Standards Track [Page 5]
+
+RFC 2445 iCalendar November 1998
+
+
+ unwired transport such as infrared might also be used.
+
+ The memo also provides for the definition of iCalendar object methods
+ that will map this content type to a set of messages for supporting
+ calendaring and scheduling operations such as requesting, replying
+ to, modifying, and canceling meetings or appointments, to-dos and
+ journal entries. The iCalendar object methods can be used to define
+ other calendaring and scheduling operations such a requesting for and
+ replying with free/busy time data. Such a scheduling protocol is
+ defined in the iCalendar Transport-independent Interoperability
+ Protocol (iTIP) defined in [ITIP].
+
+ The memo also includes a formal grammar for the content type based on
+ the Internet ABNF defined in [RFC 2234]. This ABNF is required for
+ the implementation of parsers and to serve as the definitive
+ reference when ambiguities or questions arise in interpreting the
+ descriptive prose definition of the memo.
+
+2 Basic Grammar and Conventions
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and
+ "OPTIONAL" in this document are to be interoperated as described in
+ [RFC 2119].
+
+ This memo makes use of both a descriptive prose and a more formal
+ notation for defining the calendaring and scheduling format.
+
+ The notation used in this memo is the ABNF notation of [RFC 2234].
+ Readers intending on implementing this format defined in this memo
+ should be familiar with this notation in order to properly interpret
+ the specifications of this memo.
+
+ All numeric and hexadecimal values used in this memo are given in
+ decimal notation.
+
+ All names of properties, property parameters, enumerated property
+ values and property parameter values are case-insensitive. However,
+ all other property values are case-sensitive, unless otherwise
+ stated.
+
+ Note: All indented editorial notes, such as this one, are
+ intended to provide the reader with additional information. The
+ information is not essential to the building of an
+ implementation conformant with this memo. The information is
+ provided to highlight a particular feature or characteristic of
+ the memo.
+
+
+
+
+Dawson & Stenerson Standards Track [Page 6]
+
+RFC 2445 iCalendar November 1998
+
+
+ The format for the iCalendar object is based on the syntax of the
+ [RFC 2425] content type. While the iCalendar object is not a profile
+ of the [RFC 2425] content type, it does reuse a number of the
+ elements from the [RFC 2425] specification.
+
+2.1 Formatting Conventions
+
+ The mechanisms defined in this memo are defined in prose. Many of the
+ terms used to describe these have common usage that is different than
+ the standards usage of this memo. In order to reference within this
+ memo elements of the calendaring and scheduling model, core object
+ (this memo) or interoperability protocol [ITIP] some formatting
+ conventions have been used. Calendaring and scheduling roles are
+ referred to in quoted-strings of text with the first character of
+ each word in upper case. For example, "Organizer" refers to a role of
+ a "Calendar User" within the scheduling protocol defined by [ITIP].
+ Calendar components defined by this memo are referred to with
+ capitalized, quoted-strings of text. All calendar components start
+ with the letter "V". For example, "VEVENT" refers to the event
+ calendar component, "VTODO" refers to the to-do calendar component
+ and "VJOURNAL" refers to the daily journal calendar component.
+ Scheduling methods defined by [ITIP] are referred to with
+ capitalized, quoted-strings of text. For example, "REQUEST" refers to
+ the method for requesting a scheduling calendar component be created
+ or modified, "REPLY" refers to the method a recipient of a request
+ uses to update their status with the "Organizer" of the calendar
+ component.
+
+ The properties defined by this memo are referred to with capitalized,
+ quoted-strings of text, followed by the word "property". For example,
+ "ATTENDEE" property refers to the iCalendar property used to convey
+ the calendar address of a calendar user. Property parameters defined
+ by this memo are referred to with lowercase, quoted-strings of text,
+ followed by the word "parameter". For example, "value" parameter
+ refers to the iCalendar property parameter used to override the
+ default data type for a property value. Enumerated values defined by
+ this memo are referred to with capitalized text, either alone or
+ followed by the word "value". For example, the "MINUTELY" value can
+ be used with the "FREQ" component of the "RECUR" data type to specify
+ repeating components based on an interval of one minute or more.
+
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 7]
+
+RFC 2445 iCalendar November 1998
+
+
+2.2 Related Memos
+
+ Implementers will need to be familiar with several other memos that,
+ along with this memo, form a framework for Internet calendaring and
+ scheduling standards. This memo, [ICAL], specifies a core
+ specification of objects, data types, properties and property
+ parameters.
+
+ [ITIP] - specifies an interoperability protocol for scheduling
+ between different implementations;
+
+ [IMIP] specifies an Internet email binding for [ITIP].
+
+ This memo does not attempt to repeat the specification of concepts or
+ definitions from these other memos. Where possible, references are
+ made to the memo that provides for the specification of these
+ concepts or definitions.
+
+2.3 International Considerations
+
+ In the rest of this document, descriptions of characters are of the
+ form "character name (codepoint)", where "codepoint" is from the US-
+ ASCII character set. The "character name" is the authoritative
+ description; (codepoint) is a reference to that character in US-ASCII
+ or US-ASCII compatible sets (for example the ISO-8859-x family, UTF-
+ 8, ISO-2022-xx, KOI8-R). If a non-US-ASCII compatible character set
+ is used, appropriate code-point from that character set MUST be
+ chosen instead. Use of non-US-ASCII-compatible character sets is NOT
+ recommended.
+
+3 Registration Information
+
+ The Calendaring and Scheduling Core Object Specification is intended
+ for use as a MIME content type. However, the implementation of the
+ memo is in no way limited solely as a MIME content type.
+
+3.1 Content Type
+
+ The following text is intended to register this memo as the MIME
+ content type "text/calendar".
+
+ To: iet...@un...
+
+ Subject: Registration of MIME content type text/calendar.
+
+ MIME media type name: text
+
+ MIME subtype name: calendar
+
+
+
+Dawson & Stenerson Standards Track [Page 8]
+
+RFC 2445 iCalendar November 1998
+
+
+3.2 Parameters
+
+ Required parameters: none
+
+ Optional parameters: charset, method, component and optinfo
+
+ The "charset" parameter is defined in [RFC 2046] for other body
+ parts. It is used to identify the default character set used within
+ the body part.
+
+ The "method" parameter is used to convey the iCalendar object method
+ or transaction semantics for the calendaring and scheduling
+ information. It also is an identifier for the restricted set of
+ properties and values that the iCalendar object consists of. The
+ parameter is to be used as a guide for applications interpreting the
+ information contained within the body part. It SHOULD NOT be used to
+ exclude or require particular pieces of information unless the
+ identified method definition specifically calls for this behavior.
+ Unless specifically forbidden by a particular method definition, a
+ text/calendar content type can contain any set of properties
+ permitted by the Calendaring and Scheduling Core Object
+ Specification. The "method" parameter MUST be the same value as that
+ specified in the "METHOD" component property in the iCalendar object.
+ If one is present, the other MUST also be present.
+
+ The value for the "method" parameter is defined as follows:
+
+ method = 1*(ALPHA / DIGIT / "-")
+ ; IANA registered iCalendar object method
+
+ The "component" parameter conveys the type of iCalendar calendar
+ component within the body part. If the iCalendar object contains more
+ than one calendar component type, then multiple component parameters
+ MUST be specified.
+
+ The value for the "component" parameter is defined as follows:
+
+ component = ("VEVENT" / "VTODO" / "VJOURNAL" / "VFREEBUSY"
+ / "VTIMEZONE" / x-name / iana-token)
+
+ The "optinfo" parameter conveys optional information about the
+ iCalendar object within the body part. This parameter can only
+ specify semantics already specified by the iCalendar object and that
+ can be otherwise determined by parsing the body part. In addition,
+ the optional information specified by this parameter MUST be
+ consistent with that information specified by the iCalendar object.
+ For example, it can be used to convey the "Attendee" response status
+ to a meeting request. The parameter value consists of a string value.
+
+
+
+Dawson & Stenerson Standards Track [Page 9]
+
+RFC 2445 iCalendar November 1998
+
+
+ The parameter can be specified multiple times.
+
+ This parameter MAY only specify semantics already specified by the
+ iCalendar object and that can be otherwise determined by parsing the
+ body part.
+
+ The value for the "optinfo" parameter is defined as follows:
+
+ optinfo = infovalue / qinfovalue
+
+ infovalue = iana-token / x-name
+
+ qinfovalue = DQUOTE (infovalue) DQUOTE
+
+3.3 Content Header Fields
+
+ Optional content header fields: Any header fields defined by [RFC
+ 2045].
+
+3.4 Encoding Considerations
+
+ This MIME content type can contain 8bit characters, so the use of
+ quoted-printable or BASE64 MIME content-transfer-encodings might be
+ necessary when iCalendar objects are transferred across protocols
+ restricted to the 7bit repertoire. Note that a text valued property
+ in the content entity can also have content encoding of special
+ characters using a BACKSLASH character (US-ASCII decimal 92)
+ escapement technique. This means that content values can end up
+ encoded twice.
+
+3.5 Security Considerations
+
+ SPOOFING - - In this memo, the "Organizer" is the only person
+ authorized to make changes to an existing "VEVENT", "VTODO",
+ "VJOURNAL" calendar component and redistribute the updates to the
+ "Attendees". An iCalendar object that maliciously changes or cancels
+ an existing "VEVENT", "VTODO" or "VJOURNAL" or "VFREEBUSY" calendar
+ component might be constructed by someone other than the "Organizer"
+ and sent to the "Attendees". In addition in this memo, other than the
+ "Organizer", an "Attendee" of a "VEVENT", "VTODO", "VJOURNAL"
+ calendar component is the only other person authorized to update any
+ parameter associated with their "ATTENDEE" property and send it to
+ the "Organizer". An iCalendar object that maliciously changes the
+ "ATTENDEE" parameters can be constructed by someone other than the
+ real "Attendee" and sent to the "Organizer".
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 10]
+
+RFC 2445 iCalendar November 1998
+
+
+ PROCEDURAL ALARMS - - An iCalendar object can be created that
+ contains a "VEVENT" and "VTODO" calendar component with "VALARM"
+ calendar components. The "VALARM" calendar component can be of type
+ PROCEDURE and can have an attachment containing some sort of
+ executable program. Implementations that incorporate these types of
+ alarms are subject to any virus or malicious attack that might occur
+ as a result of executing the attachment.
+
+ ATTACHMENTS - - An iCalendar object can include references to Uniform
+ Resource Locators that can be programmed resources.
+
+ Implementers and users of this memo should be aware of the network
+ security implications of accepting and parsing such information. In
+ addition, the security considerations observed by implementations of
+ electronic mail systems should be followed for this memo.
+
+3.6 Interoperability Considerations
+
+ This MIME content type is intended to define a common format for
+ conveying calendaring and scheduling information between different
+ systems. It is heavily based on the earlier [VCAL] industry
+ specification.
+
+3.7 Applications Which Use This Media Type
+
+ This content-type is designed for widespread use by Internet
+ calendaring and scheduling applications. In addition, applications in
+ the workflow and document management area might find this content-
+ type applicable. The [ITIP] and [IMIP] Internet protocols directly
+ use this content-type also. Future work on an Internet calendar
+ access protocol will utilize this content-type too.
+
+3.8 Additional Information
+
+ This memo defines this content-type.
+
+3.9 Magic Numbers
+
+ None.
+
+3.10 File Extensions
+
+ The file extension of "ics" is to be used to designate a file
+ containing (an arbitrary set of) calendaring and scheduling
+ information consistent with this MIME content type.
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 11]
+
+RFC 2445 iCalendar November 1998
+
+
+ The file extension of "ifb" is to be used to designate a file
+ containing free or busy time information consistent with this MIME
+ content type.
+
+ Macintosh file type codes: The file type code of "iCal" is to be used
+ in Apple MacIntosh operating system environments to designate a file
+ containing calendaring and scheduling information consistent with
+ this MIME media type.
+
+ The file type code of "iFBf" is to be used in Apple MacIntosh
+ operating system environments to designate a file containing free or
+ busy time information consistent with this MIME media type.
+
+3.11 Contact for Further Information:
+
+ Frank Dawson
+ 6544 Battleford Drive
+ Raleigh, NC 27613-3502
+ 919-676-9515 (Telephone)
+ 919-676-9564 (Data/Facsimile)
+ Fra...@Lo... (Internet Mail)
+
+ Derik Stenerson
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ 425-936-5522 (Telephone)
+ 425-936-7329 (Facsimile)
+ de...@mi... (Internet Mail)
+
+3.12 Intended Usage
+
+ COMMON
+
+3.13 Authors/Change Controllers
+
+ Frank Dawson
+ 6544 Battleford Drive
+ Raleigh, NC 27613-3502
+ 919-676-9515 (Telephone)
+ 919-676-9564 (Data/Facsimile)
+ Fra...@Lo... (Internet Mail)
+
+ Derik Stenerson
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ 425-936-5522 (Telephone)
+ 425-936-7329 (Facsimile)
+ de...@mi... (Internet Mail)
+
+
+
+Dawson & Stenerson Standards Track [Page 12]
+
+RFC 2445 iCalendar November 1998
+
+
+4 iCalendar Object Specification
+
+ The following sections define the details of a Calendaring and
+ Scheduling Core Object Specification. This information is intended to
+ be an integral part of the MIME content type registration. In
+ addition, this information can be used independent of such content
+ registration. In particular, this memo has direct applicability for
+ use as a calendaring and scheduling exchange format in file-, memory-
+ or network-based transport mechanisms.
+
+4.1 Content Lines
+
+ The iCalendar object is organized into individual lines of text,
+ called content lines. Content lines are delimited by a line break,
+ which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII
+ decimal 10).
+
+ Lines of text SHOULD NOT be longer than 75 octets, excluding the line
+ break. Long content lines SHOULD be split into a multiple line
+ representations using a line "folding" technique. That is, a long
+ line can be split between any two characters by inserting a CRLF
+ immediately followed by a single linear white space character (i.e.,
+ SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence
+ of CRLF followed immediately by a single linear white space character
+ is ignored (i.e., removed) when processing the content type.
+
+ For example the line:
+
+ DESCRIPTION:This is a long description that exists on a long line.
+
+ Can be represented as:
+
+ DESCRIPTION:This is a lo
+ ng description
+ that exists on a long line.
+
+ The process of moving from this folded multiple line representation
+ to its single line representation is called "unfolding". Unfolding is
+ accomplished by removing the CRLF character and the linear white
+ space character that immediately follows.
+
+ When parsing a content line, folded lines MUST first be unfolded
+ according to the unfolding procedure described above. When generating
+ a content line, lines longer than 75 octets SHOULD be folded
+ according to the folding procedure described above.
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 13]
+
+RFC 2445 iCalendar November 1998
+
+
+ The content information associated with an iCalendar object is
+ formatted using a syntax similar to that defined by [RFC 2425]. That
+ is, the content information consists of CRLF-separated content lines.
+
+ The following notation defines the lines of content in an iCalendar
+ object:
+
+ contentline = name *(";" param ) ":" value CRLF
+ ; This ABNF is just a general definition for an initial parsing
+ ; of the content line into its property name, parameter list,
+ ; and value string
+
+ ; When parsing a content line, folded lines MUST first
+ ; be unfolded according to the unfolding procedure
+ ; described above. When generating a content line, lines
+ ; longer than 75 octets SHOULD be folded according to
+ ; the folding procedure described above.
+
+ name = x-name / iana-token
+
+ iana-token = 1*(ALPHA / DIGIT / "-")
+ ; iCalendar identifier registered with IANA
+
+ x-name = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")
+ ; Reservered for experimental use. Not intended for use in
+ ; released products.
+
+ vendorid = 3*(ALPHA / DIGIT) ;Vendor identification
+
+ param = param-name "=" param-value
+ *("," param-value)
+ ; Each property defines the specific ABNF for the parameters
+ ; allowed on the property. Refer to specific properties for
+ ; precise parameter ABNF.
+
+ param-name = iana-token / x-token
+
+ param-value = paramtext / quoted-string
+
+ paramtext = *SAFE-CHAR
+
+ value = *VALUE-CHAR
+
+ quoted-string = DQUOTE *QSAFE-CHAR DQUOTE
+
+ NON-US-ASCII = %x80-F8
+ ; Use restricted by charset parameter
+ ; on outer MIME object (UTF-8 preferred)
+
+
+
+Dawson & Stenerson Standards Track [Page 14]
+
+RFC 2445 iCalendar November 1998
+
+
+ QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
+ ; Any character except CTLs and DQUOTE
+
+ SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E
+ / NON-US-ASCII
+ ; Any character except CTLs, DQUOTE, ";", ":", ","
+
+ VALUE-CHAR = WSP / %x21-7E / NON-US-ASCII
+ ; Any textual character
+
+ CR = %x0D
+ ; carriage return
+
+ LF = %x0A
+ ; line feed
+
+ CRLF = CR LF
+ ; Internet standard newline
+
+ CTL = %x00-08 / %x0A-1F / %x7F
+ ; Controls
+
+ ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
+
+ DIGIT = %x30-39
+ ; 0-9
+
+ DQUOTE = %x22
+ ; Quotation Mark
+
+ WSP = SPACE / HTAB
+
+ SPACE = %x20
+
+ HTAB = %x09
+
+ The property value component of a content line has a format that is
+ property specific. Refer to the section describing each property for
+ a definition of this format.
+
+ All names of properties, property parameters, enumerated property
+ values and property parameter values are case-insensitive. However,
+ all other property values are case-sensitive, unless otherwise
+ stated.
+
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 15]
+
+RFC 2445 iCalendar November 1998
+
+
+4.1.1 List and Field Separators
+
+ Some properties and parameters allow a list of values. Values in a
+ list of values MUST be separated by a COMMA character (US-ASCII
+ decimal 44). There is no significance to the order of values in a
+ list. For those parameter values (such as those that specify URI
+ values) that are specified in quoted-strings, the individual quoted-
+ strings are separated by a COMMA character (US-ASCII decimal 44).
+
+ Some property values are defined in terms of multiple parts. These
+ structured property values MUST have their value parts separated by a
+ SEMICOLON character (US-ASCII decimal 59).
+
+ Some properties allow a list of parameters. Each property parameter
+ in a list of property parameters MUST be separated by a SEMICOLON
+ character (US-ASCII decimal 59).
+
+ Property parameters with values containing a COLON, a SEMICOLON or a
+ COMMA character MUST be placed in quoted text.
+
+ For example, in the following properties a SEMICOLON is used to
+ separate property parameters from each other, and a COMMA is used to
+ separate property values in a value list.
+
+ ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:MAILTO:
+ js...@ho...
+
+ RDATE;VALUE=DATE:19970304,19970504,19970704,19970904
+
+4.1.2 Multiple Values
+
+ Some properties defined in the iCalendar object can have multiple
+ values. The general rule for encoding multi-valued items is to simply
+ create a new content line for each value, including the property
+ name. However, it should be noted that some properties support
+ encoding multiple values in a single property by separating the
+ values with a COMMA character (US-ASCII decimal 44). Individual
+ property definitions should be consulted for determining whether a
+ specific property allows multiple values and in which of these two
+ forms.
+
+4.1.3 Binary Content
+
+ Binary content information in an iCalendar object SHOULD be
+ referenced using a URI within a property value. That is the binary
+ content information SHOULD be placed in an external MIME entity that
+ can be referenced by a URI from within the iCalendar object. In
+ applications where this is not feasible, binary content information
+
+
+
+Dawson & Stenerson Standards Track [Page 16]
+
+RFC 2445 iCalendar November 1998
+
+
+ can be included within an iCalendar object, but only after first
+ encoding it into text using the "BASE64" encoding method defined in
+ [RFC 2045]. Inline binary contact SHOULD only be used in applications
+ whose special circumstances demand that an iCalendar object be
+ expressed as a single entity. A property containing inline binary
+ content information MUST specify the "ENCODING" property parameter.
+ Binary content information placed external to the iCalendar object
+ MUST be referenced by a uniform resource identifier (URI).
+
+ The following example specifies an "ATTACH" property that references
+ an attachment external to the iCalendar object with a URI reference:
+
+ ATTACH:http://xyz.com/public/quarterly-report.doc
+
+ The following example specifies an "ATTACH" property with inline
+ binary encoded content information:
+
+ ATTACH;FMTTYPE=image/basic;ENCODING=BASE64;VALUE=BINARY:
+ MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1U
+ EBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIE
+ <...remainder of "BASE64" encoded binary data...>
+
+4.1.4 Character Set
+
+ There is not a property parameter to declare the character set used
+ in a property value. The default character set for an iCalendar
+ object is UTF-8 as defined in [RFC 2279].
+
+ The "charset" Content-Type parameter can be used in MIME transports
+ to specify any other IANA registered character set.
+
+4.2 Property Parameters
+
+ A property can have attributes associated with it. These "property
+ parameters" contain meta-information about the property or the
+ property value. Property parameters are provided to specify such
+ information as the location of an alternate text representation for a
+ property value, the language of a text property value, the data type
+ of the property value and other attributes.
+
+ Property parameter values that contain the COLON (US-ASCII decimal
+ 58), SEMICOLON (US-ASCII decimal 59) or COMMA (US-ASCII decimal 44)
+ character separators MUST be specified as quoted-string text values.
+ Property parameter values MUST NOT contain the DOUBLE-QUOTE (US-ASCII
+ decimal 22) character. The DOUBLE-QUOTE (US-ASCII decimal 22)
+ character is used as a delimiter for parameter values that contain
+ restricted characters or URI text. For example:
+
+
+
+
+Dawson & Stenerson Standards Track [Page 17]
+
+RFC 2445 iCalendar November 1998
+
+
+ DESCRIPTION;ALTREP="http://www.wiz.org":The Fall'98 Wild Wizards
+ Conference - - Las Vegas, NV, USA
+
+ Property parameter values that are not in quoted strings are case
+ insensitive.
+
+ The general property parameters defined by this memo are defined by
+ the following notation:
+
+ parameter = altrepparam ; Alternate text representation
+ / cnparam ; Common name
+ / cutypeparam ; Calendar user type
+ / delfromparam ; Delegator
+ / deltoparam ; Delegatee
+ / dirparam ; Directory entry
+ / encodingparam ; Inline encoding
+ / fmttypeparam ; Format type
+ / fbtypeparam ; Free/busy time type
+ / languageparam ; Language for text
+ / memberparam ; Group or list membership
+ / partstatparam ; Participation status
+ / rangeparam ; Recurrence identifier range
+ / trigrelparam ; Alarm trigger relationship
+ / reltypeparam ; Relationship type
+ / roleparam ; Participation role
+ / rsvpparam ; RSVP expectation
+ / sentbyparam ; Sent by
+ / tzidparam ; Reference to time zone object
+ / valuetypeparam ; Property value data type
+ / ianaparam
+ ; Some other IANA registered iCalendar parameter.
+ / xparam
+ ; A non-standard, experimental parameter.
+
+ ianaparam = iana-token "=" param-value *("," param-value)
+
+ xparam =x-name "=" param-value *("," param-value)
+
+4.2.1 Alternate Text Representation
+
+ Parameter Name: ALTREP
+
+ Purpose: To specify an alternate text representation for the property
+ value.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+
+
+
+Dawson & Stenerson Standards Track [Page 18]
+
+RFC 2445 iCalendar November 1998
+
+
+ altrepparam = "ALTREP" "=" DQUOTE uri DQUOTE
+
+ Description: The parameter specifies a URI that points to an
+ alternate representation for a textual property value. A property
+ specifying this parameter MUST also include a value that reflects the
+ default representation of the text value. The individual URI
+ parameter values MUST each be specified in a quoted-string.
+
+ Example:
+
+ DESCRIPTION;ALTREP="CID:<par...@ho...>":Project
+ XYZ Review Meeting will include the following agenda items: (a)
+ Market Overview, (b) Finances, (c) Project Management
+
+ The "ALTREP" property parameter value might point to a "text/html"
+ content portion.
+
+ Content-Type:text/html
+ Content-Id:<par...@ho...>
+
+ <html><body>
+ <p><b>Project XYZ Review Meeting</b> will include the following
+ agenda items:<ol><li>Market
+ Overview</li><li>Finances</li><li>Project Management</li></ol></p>
+ </body></html>
+
+4.2.2 Common Name
+
+ Parameter Name: CN
+
+ Purpose: To specify the common name to be associated with the
+ calendar user specified by the property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ cnparam = "CN" "=" param-value
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. The parameter specifies the common name to be
+ associated with the calendar user specified by the property. The
+ parameter value is text. The parameter value can be used for display
+ text to be associated with the calendar address specified by the
+ property.
+
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 19]
+
+RFC 2445 iCalendar November 1998
+
+
+ Example:
+
+ ORGANIZER;CN="John Smith":MAILTO:js...@ho...
+
+4.2.3 Calendar User Type
+
+ Parameter Name: CUTYPE
+
+ Purpose: To specify the type of calendar user specified by the
+ property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ cutypeparam = "CUTYPE" "="
+ ("INDIVIDUAL" ; An individual
+ / "GROUP" ; A group of individuals
+ / "RESOURCE" ; A physical resource
+ / "ROOM" ; A room resource
+ / "UNKNOWN" ; Otherwise not known
+ / x-name ; Experimental type
+ / iana-token) ; Other IANA registered
+ ; type
+ ; Default is INDIVIDUAL
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. The parameter identifies the type of calendar
+ user specified by the property. If not specified on a property that
+ allows this parameter, the default is INDIVIDUAL.
+
+ Example:
+
+ ATTENDEE;CUTYPE=GROUP:MAILTO:iet...@im...
+
+4.2.4 Delegators
+
+ Parameter Name: DELEGATED-FROM
+
+ Purpose: To specify the calendar users that have delegated their
+ participation to the calendar user specified by the property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ delfromparam = "DELEGATED-FROM" "=" DQUOTE cal-address DQUOTE
+ *("," DQUOTE cal-address DQUOTE)
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 20]
+
+RFC 2445 iCalendar November 1998
+
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. This parameter can be specified on a property
+ that has a value type of calendar address. This parameter specifies
+ those calendar uses that have delegated their participation in a
+ group scheduled event or to-do to the calendar user specified by the
+ property. The value MUST be a MAILTO URI as defined in [RFC 1738].
+ The individual calendar address parameter values MUST each be
+ specified in a quoted-string.
+
+ Example:
+
+ ATTENDEE;DELEGATED-FROM="MAILTO:js...@ho...":MAILTO:
+ jd...@ho...
+
+4.2.5 Delegatees
+
+ Parameter Name: DELEGATED-TO
+
+ Purpose: To specify the calendar users to whom the calendar user
+ specified by the property has delegated participation.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ deltoparam = "DELEGATED-TO" "=" DQUOTE cal-address DQUOTE
+ *("," DQUOTE cal-address DQUOTE)
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. This parameter specifies those calendar users
+ whom have been delegated participation in a group scheduled event or
+ to-do by the calendar user specified by the property. The value MUST
+ be a MAILTO URI as defined in [RFC 1738]. The individual calendar
+ address parameter values MUST each be specified in a quoted-string.
+
+ Example:
+
+ ATTENDEE;DELEGATED-TO="MAILTO:jd...@ho...","MAILTO:jqpublic@
+ host.com":MAILTO:js...@ho...
+
+4.2.6 Directory Entry Reference
+
+ Parameter Name: DIR
+
+ Purpose: To specify reference to a directory entry associated with
+ the calendar user specified by the property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+
+
+Dawson & Stenerson Standards Track [Page 21]
+
+RFC 2445 iCalendar November 1998
+
+
+ dirparam = "DIR" "=" DQUOTE uri DQUOTE
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. The parameter specifies a reference to the
+ directory entry associated with the calendar user specified by the
+ property. The parameter value is a URI. The individual URI parameter
+ values MUST each be specified in a quoted-string.
+
+ Example:
+
+ ORGANIZER;DIR="ldap://host.com:6666/o=eDABC%20Industries,c=3DUS??
+ (cn=3DBJim%20Dolittle)":MAILTO:ji...@ho...
+
+4.2.7 Inline Encoding
+
+ Parameter Name: ENCODING
+
+ Purpose: To specify an alternate inline encoding for the property
+ value.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ encodingparam = "ENCODING" "="
+ ("8BIT"
+ ; "8bit" text encoding is defined in [RFC 2045]
+ / "BASE64"
+ ; "BASE64" binary encoding format is defined in [RFC 2045]
+ / iana-token
+ ; Some other IANA registered iCalendar encoding type
+ / x-name)
+ ; A non-standard, experimental encoding type
+
+ Description: The property parameter identifies the inline encoding
+ used in a property value. The default encoding is "8BIT",
+ corresponding to a property value consisting of text. The "BASE64"
+ encoding type corresponds to a property value encoded using the
+ "BASE64" encoding defined in [RFC 2045].
+
+ If the value type parameter is ";VALUE=BINARY", then the inline
+ encoding parameter MUST be specified with the value
+ ";ENCODING=BASE64".
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 22]
+
+RFC 2445 iCalendar November 1998
+
+
+ Example:
+
+ ATTACH;FMTYPE=IMAGE/JPEG;ENCODING=BASE64;VALUE=BINARY:MIICajC
+ CAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDA
+ qBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRw
+ <...remainder of "BASE64" encoded binary data...>
+
+4.2.8 Format Type
+
+ Parameter Name: FMTTYPE
+
+ Purpose: To specify the content type of a referenced object.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ fmttypeparam = "FMTTYPE" "=" iana-token
+ ; A IANA registered content type
+ / x-name
+ ; A non-standard content type
+
+ Description: This parameter can be specified on properties that are
+ used to reference an object. The parameter specifies the content type
+ of the referenced object. For example, on the "ATTACH" property, a
+ FTP type URI value does not, by itself, necessarily convey the type
+ of content associated with the resource. The parameter value MUST be
+ the TEXT for either an IANA registered content type or a non-standard
+ content type.
+
+ Example:
+
+ ATTACH;FMTTYPE=application/binary:ftp://domain.com/pub/docs/
+ agenda.doc
+
+4.2.9 Free/Busy Time Type
+
+ Parameter Name: FBTYPE
+
+ Purpose: To specify the free or busy time type.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ fbtypeparam = "FBTYPE" "=" ("FREE" / "BUSY"
+ / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE"
+ / x-name
+ ; Some experimental iCalendar data type.
+ / iana-token)
+
+
+
+Dawson & Stenerson Standards Track [Page 23]
+
+RFC 2445 iCalendar November 1998
+
+
+ ; Some other IANA registered iCalendar data type.
+
+ Description: The parameter specifies the free or busy time type. The
+ value FREE indicates that the time interval is free for scheduling.
+ The value BUSY indicates that the time interval is busy because one
+ or more events have been scheduled for that interval. The value
+ BUSY-UNAVAILABLE indicates that the time interval is busy and that
+ the interval can not be scheduled. The value BUSY-TENTATIVE indicates
+ that the time interval is busy because one or more events have been
+ tentatively scheduled for that interval. If not specified on a
+ property that allows this parameter, the default is BUSY.
+
+ Example: The following is an example of this parameter on a FREEBUSY
+ property.
+
+ FREEBUSY;FBTYPE=BUSY:19980415T133000Z/19980415T170000Z
+
+4.2.10 Language
+
+ Parameter Name: LANGUAGE
+
+ Purpose: To specify the language for text values in a property or
+ property parameter.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ languageparam = "LANGUAGE" "=" language
+
+ language = <Text identifying a language, as defined in [RFC 1766]>
+
+ Description: This parameter can be specified on properties with a
+ text value type. The parameter identifies the language of the text in
+ the property or property parameter value. The value of the "language"
+ property parameter is that defined in [RFC 1766].
+
+ For transport in a MIME entity, the Content-Language header field can
+ be used to set the default language for the entire body part.
+ Otherwise, no default language is assumed.
+
+ Example:
+
+ SUMMARY;LANGUAGE=us-EN:Company Holiday Party
+
+ LOCATION;LANGUAGE=en:Germany
+ LOCATION;LANGUAGE=no:Tyskland
+
+
+
+
+
+Dawson & Stenerson Standards Track [Page 24]
+
+RFC 2445 iCalendar November 1998
+
+
+ The following example makes use of the Quoted-Printable encoding in
+ order to represent non-ASCII characters.
+
+ LOCATION;LANGUAGE=da:K=F8benhavn
+ LOCATION;LANGUAGE=en:Copenhagen
+
+4.2.11 Group or List Membership
+
+ Parameter Name: MEMBER
+
+ Purpose: To specify the group or list membership of the calendar user
+ specified by the property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ memberparam = "MEMBER" "=" DQUOTE cal-address DQUOTE
+ *("," DQUOTE cal-address DQUOTE)
+
+ Description: This parameter can be specified on properties with a
+ CAL-ADDRESS value type. The parameter identifies the groups or list
+ membership for the calendar user specified by the property. The
+ parameter value either a single calendar address in a quoted-string
+ or a COMMA character (US-ASCII decimal 44) list of calendar
+ addresses, each in a quoted-string. The individual calendar address
+ parameter values MUST each be specified in a quoted-string.
+
+ Example:
+
+ ATTENDEE;MEMBER="MAILTO:iet...@im...":MAILTO:js...@ho...
+
+ ATTENDEE;MEMBER="MAILTO:pro...@ho...","MAILTO:projectB@host.
+ com":MAILTO:ja...@ho...
+
+4.2.12 Participation Status
+
+ Parameter Name: PARTSTAT
+
+ Purpose: To specify the participation status for the calendar user
+ specified by the property.
+
+ Format Definition: The property parameter is defined by the following
+ notation:
+
+ partstatparam = "PARTSTAT" "="
+ ("NEEDS-ACTION" ; Event needs action
+ / "ACCEPTED" ; Event accepted
+ / "DECLINED" ; Event declined
+
+
+
+Dawson & Stenerson Standards Track [Page 25]
+
+RFC 2445 iCalendar November 1998
+
+
+ / "TENTATIVE" ; Event tentatively
+ ; accepted
+ / "DELEGATED" ; Event delegated
+ / x-name ; Experimental status
+ / iana-token) ; Other IANA registered
+ ; status
+ ; These are the participation statuses for a "VEVENT". Default is
+ ; NEEDS-ACTION
+ partstatparam /= "PARTSTAT" "="
+ ("NEEDS-ACTION" ; To-do needs action
+ / "ACCEPTED" ; To-do accepted
+ / "DECLINED" ; To-do declined
+ / "TENTATIVE" ; To-do tentatively
+ ; accepted
+ / "DELEGATED" ; To-do delegated
+ / "COMPLETED" ; To-do completed.
+ ; COMPLETED property has
+ ;date/time completed.
+ / "IN-PROCESS" ; To-do in process of
+ ; being completed
+ / x-name ; Experimental status
+ / iana-token) ; Other IANA registered
+ ; status
+ ; These are the participation statuses for a "VTODO". Default is
+ ; NEEDS-ACTION
+
+ partstatparam /= "PARTSTAT" "="
+ ("NEEDS-ACTION" ; Journal needs action
+ / "ACCEPTED" ; Journal accepted
+ / "DECLINED" ; Journal declined
+ / x-name ; Experimental status
+ / iana-token) ; Other IANA registered
+ ; status
+ ; These are the participation statuses for a "VJO...
[truncated message content] |
|
From: <tmy...@us...> - 2007-02-02 09:20:37
|
Revision: 126
http://svn.sourceforge.net/nmailserver/?rev=126&view=rev
Author: tmyroadctfig
Date: 2007-02-02 01:20:36 -0800 (Fri, 02 Feb 2007)
Log Message:
-----------
Some minor changes and added licenses to some files.
Modified Paths:
--------------
NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs
NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx
NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Login.aspx
NMail/trunk/NMail.WebAccess/Login.aspx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
NMail/trunk/NMail.WebAccess/Mail.aspx.cs
Added Paths:
-----------
NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx
NMail/trunk/NMail.WebAccess/ErrorHandler.aspx
NMail/trunk/NMail.WebAccess/ErrorHandler.aspx.cs
Modified: NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -14,8 +31,16 @@
namespace NMail.WebAccess
{
+ /// <summary>
+ /// A helper class for converting data types, etc.
+ /// </summary>
public static class Helper
{
+ /// <summary>
+ /// Gets the body structure from a serialized version.
+ /// </summary>
+ /// <param name="serializedBody">The version to de-serialize.</param>
+ /// <returns>The body structure.</returns>
public static BodyStructure GetBodyStructure(BodyStructureSerializer serializedBody)
{
ByteString headerData = new ByteString(Convert.FromBase64String(serializedBody.Headers.Headers), Encoding.ASCII);
@@ -30,6 +55,11 @@
return result;
}
+ /// <summary>
+ /// Gets the message envelope from a serialized version.
+ /// </summary>
+ /// <param name="es">The version to de-serialize.</param>
+ /// <returns>The envelope.</returns>
public static Envelope GetEnvelope(EnvelopeSerializer es)
{
Envelope result = new Envelope(es.From, es.Date, es.Subject);
@@ -45,6 +75,12 @@
return result;
}
+ /// <summary>
+ /// Attempts to parse the given string as a date and reformat it in
+ /// a more uniform way.
+ /// </summary>
+ /// <param name="s">The string containing the date.</param>
+ /// <returns>The reformatted string where possible otherwise the original.</returns>
public static string GetDate(string s) {
DateTime dateTime;
Modified: NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -15,27 +32,45 @@
/// </summary>
public static class HtmlEscaper
{
+ /// <summary>
+ /// Escapes all html "<", ">" and "&"s.
+ /// </summary>
+ /// <param name="o">The data to escape.</param>
+ /// <returns>The escaped string.</returns>
public static string EscapeAll(object o)
{
return EscapeAll(o.ToString());
}
+ /// <summary>
+ /// Escapes all html "<", ">" and "&"s.
+ /// </summary>
+ /// <param name="html">The data to escape.</param>
+ /// <returns>The escaped string.</returns>
public static string EscapeAll(string html)
{
- string result = html.Replace("<", "<");
+ string result = html.Replace("&", "&");
+ result = result.Replace("<", "<");
result = result.Replace(">", ">");
return result;
}
+ /// <summary>
+ /// Attempts to escape nasty contents from a html document.
+ /// </summary>
+ /// <param name="html">The html data to escape.</param>
+ /// <returns>The escaped data</returns>
public static string EscapeScriptsAndImages(string html)
{
string result = html.Replace("<img", "<img");
result = result.Replace("<script", "<script");
+ result = result.Replace("<object", "<object");
+ // TODO: this should very possibly be a whitelist
// TODO: other nasty tags
// TODO: css proxy
-
+
return result;
}
}
Modified: NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -13,8 +30,16 @@
namespace NMail.WebAccess
{
+ /// <summary>
+ /// A data source for the mail list.
+ /// </summary>
public static class MailListDataSource
{
+ /// <summary>
+ /// Gets the message envelopes for a folder.
+ /// </summary>
+ /// <param name="folderId">The Id of the folder to get the envelopes in.</param>
+ /// <returns>The envelopes and their message Id.</returns>
public static KeyValuePairOfInt32EnvelopeSerializer[] GetMessageEnvelopes(int folderId)
{
try
@@ -24,7 +49,6 @@
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
return ras.GetAllMessageEnvelopes(authToken, folderId);
-
}
catch (Exception)
{
Modified: NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -21,6 +38,7 @@
{
base.PrepareControlHierarchy();
+ // Add a click handler to each row
for (int i = 0; i < this.Rows.Count; i++)
{
string argument = "rowClicked:" + i;
@@ -30,6 +48,7 @@
protected override void RaisePostBackEvent(string eventArgument)
{
+ // Only override "rowClicked" post-backs
if (eventArgument.StartsWith("rowClicked:"))
{
eventArgument = eventArgument.Remove(0, 11);
Modified: NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
using System;
using System.Data;
@@ -16,22 +32,21 @@
namespace NMail.WebAccess
{
+ /// <summary>
+ /// A data source for the subscribed folders.
+ /// </summary>
public static class SubscribedFolderDataSource
{
+ /// <summary>
+ /// Gets a list of subscribed folders.
+ /// </summary>
+ /// <returns>The list of folders.</returns>
public static List<StoreFolder> GetSubscribedFolders()
{
IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);
string authToken = (string)session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
- if (ras == null || authToken == null)
- {
- session.Abandon();
- FormsAuthentication.SignOut();
- FormsAuthentication.RedirectToLoginPage();
- return null;
- }
-
StoreFolderSerializer[] serializedFolders = ras.GetAllSubscribedFolders(authToken);
List<StoreFolder> result = new List<StoreFolder>();
List<int> folderIds = new List<int>();
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,19 +1,18 @@
<%--
-Default skin template. The following skins are provided as examples only.
-
-1. Named control skin. The SkinId should be uniquely defined because
- duplicate SkinId's per control type are not allowed in the same theme.
-
-<asp:GridView runat="server" SkinId="gridviewSkin" BackColor="White" >
- <AlternatingRowStyle BackColor="Blue" />
-</asp:GridView>
-
-2. Default skin. The SkinId is not defined. Only one default
- control skin per control type is allowed in the same theme.
-
-<asp:Image runat="server" ImageUrl="~/images/image1.jpg" />
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
--%>
<asp:Image runat="server" SkinId="LoginBanner" ImageUrl="~/Images/Skins/Default/LoginBanner.jpg" />
-
-<%-- <asp:GridView runat="server" SkinId="MailList" Width="100%" /> --%>
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,4 +1,22 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="LinkButtonList.ascx.cs" Inherits="Controls_LinkButtonList" %>
+
<asp:Repeater ID="Repeater" runat="server">
<ItemTemplate>
<div class='<%# Eval("ItemStyleClass") %>'>
Modified: NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/LinkButtonList.ascx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -10,6 +27,9 @@
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
+/// <summary>
+/// The code for the link-button list
+/// </summary>
public partial class Controls_LinkButtonList : System.Web.UI.UserControl
{
protected override void OnInit(EventArgs e)
@@ -32,6 +52,10 @@
}
}
+ /// <summary>
+ /// Sets the list of items to display in this control.
+ /// </summary>
+ /// <param name="items">The items to display.</param>
public void SetListItems(List<LinkButtonListItem> items)
{
RepeaterItemCollection dataSource = new RepeaterItemCollection(new ArrayList(items));
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailError.aspx 2007-02-02 09:20:36 UTC (rev 126)
@@ -0,0 +1,35 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
+<%@ Page Language="C#" AutoEventWireup="true" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>Mail Error</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ <h1>Error</h1>
+ An error has occurred trying to view your message or download an attachment.
+ Click <a onclick="refresh()">here</a> to try again.
+ </div>
+ </form>
+</body>
+</html>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,6 +1,25 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MailList.ascx.cs" Inherits="Controls_Mail_MailList" %>
<%@ Register Namespace="NMail.WebAccess" TagPrefix="nmwa" %>
+
+<!-- The mail grid view for the mail list -->
<nmwa:RowClickableGridView
SkinID="MailList"
AutoGenerateColumns="false"
@@ -18,18 +37,20 @@
<Columns>
<asp:TemplateField HeaderText="From">
<ItemTemplate>
-<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.From")) %>
-</ItemTemplate>
+ <%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.From")) %>
+ </ItemTemplate>
</asp:TemplateField>
+
<asp:TemplateField HeaderText="Subject">
<ItemTemplate>
-<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.Subject")) %>
-</ItemTemplate>
- </asp:TemplateField>
+ <%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.Subject")) %>
+ </ItemTemplate>
+ </asp:TemplateField>
+
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
-<%# NMail.WebAccess.Helper.GetDate((string) Eval("Value.Date")) %>
-</ItemTemplate>
+ <%# NMail.WebAccess.Helper.GetDate((string) Eval("Value.Date")) %>
+ </ItemTemplate>
</asp:TemplateField>
</Columns>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -11,6 +28,9 @@
using NMail.WebAccess;
+/// <summary>
+/// The code for the mail list control.
+/// </summary>
public partial class Controls_Mail_MailList : System.Web.UI.UserControl, IWebPart
{
protected void Page_Init(object sender, EventArgs e)
@@ -20,6 +40,7 @@
protected void Page_PreRender(object sender, EventArgs e)
{
+ // Setup and bind to the data source
ObjectDataSource mailListDataSource = new ObjectDataSource("NMail.WebAccess.MailListDataSource", "GetMessageEnvelopes");
mailListDataSource.SelectParameters.Add("FolderId", TypeCode.Int32, this.selectedFolderId.ToString());
@@ -31,12 +52,14 @@
{
Hashtable result = new Hashtable();
result.Add("SelectedFolderId", this.selectedFolderId);
+ result.Add("SelectedFolderName", this.folderName);
return result;
}
protected override void LoadControlState(object savedState)
{
this.selectedFolderId = (int)((Hashtable)savedState)["SelectedFolderId"];
+ this.folderName = (string)((Hashtable)savedState)["SelectedFolderName"];
}
private int selectedFolderId;
@@ -50,7 +73,18 @@
set { selectedFolderId = value; }
}
+ private string folderName;
+
/// <summary>
+ /// The name of the currently selected folder.
+ /// </summary>
+ public string FolderName
+ {
+ get { return folderName; }
+ set { folderName = value; }
+ }
+
+ /// <summary>
/// The Id of the currently selected message.
/// </summary>
public int SelectedMessageId
@@ -125,8 +159,7 @@
{
get
{
- string folderName = Session["SelectedFolderName"] as string;
- return (folderName == null) ? " " : folderName;
+ return (this.folderName == null) ? " " : this.folderName;
}
set
{
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,16 +1,36 @@
-<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MessageBody.aspx.cs" Inherits="Controls_Mail_MessageBody" %>
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+<%@ Page Language="C#" ErrorPage="~/Controls/Mail/MailError.aspx" AutoEventWireup="true" CodeFile="MessageBody.aspx.cs" Inherits="Controls_Mail_MessageBody" %>
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
- <title>Untitled Page</title>
+ <title runat="Server">Message</title>
</head>
<body>
<form id="form1" runat="server">
<div class="MessageBody">
+ <!-- The message body -->
<asp:Literal ID="MessageBody" runat="server" />
<br />
+
+ <!-- The attachments -->
<asp:Repeater ID="AttachmentsRepeater" runat="server">
<ItemTemplate>
<!-- Name -->
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -16,10 +33,16 @@
using NMail.WebAccess;
using RemoteAccessService;
+/// <summary>
+/// The code for the message body page.
+/// </summary>
public partial class Controls_Mail_MessageBody : System.Web.UI.Page
{
private int messageId;
+ /// <summary>
+ /// The message Id displayed in the page.
+ /// </summary>
public int MessageId
{
get { return messageId; }
@@ -27,11 +50,17 @@
private int folderId;
+ /// <summary>
+ /// The folder the message is in.
+ /// </summary>
public int FolderId
{
get { return folderId; }
}
+ /// <summary>
+ /// Extracts the message and folder Ids from the query string.
+ /// </summary>
protected void ExtractQueryStringParams()
{
foreach (string key in Request.QueryString.AllKeys)
@@ -47,6 +76,48 @@
}
}
+ /// <summary>
+ /// Examines the body structure to determine which MIME part to display as the
+ /// message body.
+ /// </summary>
+ /// <param name="bodyStructure">The structure of the message.</param>
+ /// <param name="partNumber">The part number to display.</param>
+ /// <param name="html">True if the part is a HTML part.</param>
+ protected void FindMimePartToDisplay(BodyStructure bodyStructure, out int partNumber, out bool html)
+ {
+ if (bodyStructure.Count == 0)
+ {
+ // Simple message body, only one part to the message
+ partNumber = 1;
+ html = false;
+ }
+ else
+ {
+ partNumber = 1;
+ html = false;
+
+ // Search for the best part
+ for (int i = 0; i < bodyStructure.Count; i++)
+ {
+ string subType;
+ MimeContentType contentType = MimeHelper.GetContentType(bodyStructure[i].Headers, out subType);
+
+ if (contentType == MimeContentType.Text)
+ {
+ // We'll take the first text part we find unless something better appears
+ partNumber = i + 1;
+
+ if (subType == "html")
+ {
+ // We'll display the first HTML part we find
+ html = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
protected void Page_Load(object sender, EventArgs e)
{
ExtractQueryStringParams();
@@ -55,6 +126,7 @@
if (this.folderId == -1)
{
this.MessageBody.Text = "No folder selected.";
+ this.Page.Title = this.MessageBody.Text;
return;
}
@@ -62,6 +134,7 @@
if (this.messageId == -1)
{
this.MessageBody.Text = "No message selected.";
+ this.Page.Title = this.MessageBody.Text;
return;
}
@@ -69,44 +142,21 @@
string authToken = (string) Session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService) Session["RAS"];
+ // Get the body structure
BodyStructureSerializer bs = ras.GetMessageStructure(authToken, messageId, folderId);
BodyStructure bodyStructure = Helper.GetBodyStructure(bs);
- int bodyPartNumber = 1;
- bool htmlBody = false;
-
- if (bodyStructure.Count == 0)
- {
- // Simple message body, only one part to the message
- bodyPartNumber = 1;
- }
- else
- {
- // Search for the best part
- for (int i = 0; i < bodyStructure.Count; i++)
- {
- string subType;
- MimeContentType contentType = MimeHelper.GetContentType(bodyStructure[i].Headers, out subType);
-
- if (contentType == MimeContentType.Text)
- {
- // We'll take the first text part we find unless something better appears
- bodyPartNumber = i + 1;
-
- if (subType == "html")
- {
- // We'll display the first HTML part we find
- htmlBody = true;
- break;
- }
- }
- }
- }
-
+ // Find which part to display
+ int bodyPartNumber;
+ bool htmlBody;
+ FindMimePartToDisplay(bodyStructure, out bodyPartNumber, out htmlBody);
+
+ // Get the part to display
string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, folderId);
ByteString bodyData = new ByteString(Convert.FromBase64String(base64Body), Encoding.UTF8);
SimpleBodyPart body = MessageHelper.ParseMessage(bodyData);
+ // Ensure all nasty stuff is escaped
if (htmlBody)
{
this.MessageBody.Text = HtmlEscaper.EscapeScriptsAndImages(body.Data.ToString());
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,5 +1,23 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MessageViewer.ascx.cs" Inherits="Controls_Mail_MessageViewer" %>
+<!-- A panel for the message details -->
<asp:Panel ID="EnvelopePanel" runat="server" Visible="false" Width="100%">
<span class="MessageEnvelope">
From: <asp:Literal ID="From" runat="server" /><br />
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -13,6 +30,9 @@
using NMail.WebAccess;
using RemoteAccessService;
+/// <summary>
+/// The code for the message viewer control.
+/// </summary>
public partial class Controls_Mail_MessageViewer : System.Web.UI.UserControl, IWebPart
{
protected void Page_Init(object sender, EventArgs e)
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SubscribedFolderList.ascx.cs" Inherits="Controls_Mail_SubscribedFolderList" %>
<%@ Register Assembly="MenuPilot" Namespace="MenuPilot.Web.Ui" TagPrefix="mp" %>
@@ -3,4 +20,5 @@
<div class="SubscribedFolderList">
+ <!-- The repeater for the list of folders -->
<asp:Repeater
ID="FolderRepeater"
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -12,6 +29,9 @@
using NMail.WebAccess;
+/// <summary>
+/// The code for the subscribed folder list control.
+/// </summary>
public partial class Controls_Mail_SubscribedFolderList : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e)
@@ -65,8 +85,8 @@
if (f.UnreadMessages > 0) {
result.Append(string.Format(" ({0})", f.UnreadMessages));
- result.Append("</span>");
}
+ result.Append("</span>");
return result.ToString();
}
Added: NMail/trunk/NMail.WebAccess/ErrorHandler.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/ErrorHandler.aspx (rev 0)
+++ NMail/trunk/NMail.WebAccess/ErrorHandler.aspx 2007-02-02 09:20:36 UTC (rev 126)
@@ -0,0 +1,36 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ErrorHandler.aspx.cs" Inherits="ErrorHandler" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>NMail Web Access - Error</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ <h1>Error</h1>
+ An unexpected error has occurred in NMail Web Access.
+ Click <asp:LinkButton ID="Logout" runat="server" OnClick="Logout_Click">here</asp:LinkButton>
+ to logout and return to the login page.
+ </div>
+ </form>
+</body>
+</html>
Added: NMail/trunk/NMail.WebAccess/ErrorHandler.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/ErrorHandler.aspx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/ErrorHandler.aspx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+public partial class ErrorHandler : System.Web.UI.Page
+{
+ protected void Logout_Click(object sender, EventArgs e)
+ {
+ Session.Abandon();
+ FormsAuthentication.SignOut();
+ FormsAuthentication.RedirectToLoginPage();
+ }
+}
Modified: NMail/trunk/NMail.WebAccess/Login.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Login.aspx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -10,19 +27,22 @@
<form id="form1" runat="server">
<div align="center" class="LoginBox">
- <asp:Image ID="LoginBanner" runat="server" SkinID="LoginBanner" />
- <asp:LoginView ID="LoginView" runat="server">
- <LoggedInTemplate>
- You are currently logged in as
- <asp:LoginName ID="LoginName" runat="server" />.<br />
- <asp:LoginStatus ID="LoginStatus" runat="server" />
- </LoggedInTemplate>
- <AnonymousTemplate>
- <asp:Login ID="Login" runat="server" OnAuthenticate="Login_Authenticate" DestinationPageUrl="~/Default.aspx" TitleText="Log in to NMail web access">
- <TitleTextStyle CssClass="LogonTitle" />
- </asp:Login>
- </AnonymousTemplate>
- </asp:LoginView>
+ <asp:Image ID="LoginBanner" runat="server" SkinID="LoginBanner" />
+ <asp:LoginView ID="LoginView" runat="server">
+ <%-- Show the user name and logout prompt --%>
+ <LoggedInTemplate>
+ You are currently logged in as
+ <asp:LoginName ID="LoginName" runat="server" />.<br />
+ <asp:LoginStatus ID="LoginStatus" runat="server" />
+ </LoggedInTemplate>
+
+ <%-- Show the login prompt --%>
+ <AnonymousTemplate>
+ <asp:Login ID="Login" runat="server" OnAuthenticate="Login_Authenticate" DestinationPageUrl="~/Default.aspx" TitleText="Log in to NMail web access">
+ <TitleTextStyle CssClass="LogonTitle" />
+ </asp:Login>
+ </AnonymousTemplate>
+ </asp:LoginView>
</div>
</form>
</body>
Modified: NMail/trunk/NMail.WebAccess/Login.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Login.aspx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -11,6 +28,9 @@
using RemoteAccessService;
+/// <summary>
+/// The code for the login page.
+/// </summary>
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e) { }
@@ -22,6 +42,7 @@
RemoteAccessService.RemoteAccessService ras = new RemoteAccessService.RemoteAccessService();
string authToken = ras.Authenticate(login.UserName, login.Password);
+ // Check the result of the authentication attempt
if (authToken != string.Empty)
{
Session["AuthToken"] = authToken;
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,5 +1,22 @@
-<%@ Page Language="C#" Trace="true" TraceMode="SortByTime" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
+<%--
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+--%>
+<%@ Page Language="C#" ErrorPage="~/ErrorHandler.aspx" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
+
<%@ Register Src="Controls/Mail/MessageViewer.ascx" TagName="MessageViewer" TagPrefix="uc4" %>
<%@ Register Src="Controls/Mail/MailList.ascx" TagName="MailList" TagPrefix="uc3" %>
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx.cs 2007-02-01 10:33:00 UTC (rev 125)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx.cs 2007-02-02 09:20:36 UTC (rev 126)
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
using System;
using System.Data;
using System.Configuration;
@@ -12,6 +29,9 @@
using ASP;
+/// <summary>
+/// The code for the mail viewer form.
+/// </summary>
public partial class Mail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
@@ -24,6 +44,7 @@
viewItems.Add(new LinkButtonListItem("Logout", "ViewButton", new EventHandler(Logout_Clicked)));
this.ViewList.SetListItems(viewItems);
+ // Register for events
this.SubscribedFolderList.SelectedFolderIdChanged += new EventHandler(SubscribedFolderList_SelectedFolderIdChanged);
this.MailList.SelectedMessageChanged += new EventHandler(MailList_SelectedMessageChanged);
}
@@ -42,14 +63,17 @@
{
string folderName = null;
+ // Get the folder name
if (folderId != -1)
{
NMail.DataTypes.LocalStore.StoreFolder folder = NMail.WebAccess.SubscribedFolderDataSource.GetStoreFolder(folderId);
folderName = folder.FullFolderName;
}
+ // Update the controls
this.SubscribedFolderList.SelectedFolderId = folderId;
this.MailList.SelectedFolderId = folderId;
+ this.MailList.SelectedFolderName = folderName;
this.MessageViewer.FolderId = folderId;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-02-01 10:33:04
|
Revision: 125
http://svn.sourceforge.net/nmailserver/?rev=125&view=rev
Author: tmyroadctfig
Date: 2007-02-01 02:33:00 -0800 (Thu, 01 Feb 2007)
Log Message:
-----------
Further work on WebAccess.
Modified Paths:
--------------
NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
NMail/trunk/NMail.RemoteAccessService/App_Code/ServiceState.cs
NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Login.aspx
NMail/trunk/NMail.WebAccess/Mail.aspx
NMail/trunk/NMail.WebAccess/Mail.aspx.cs
NMail/trunk/NMail.WebAccess/Web.config
Modified: NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
===================================================================
--- NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -780,8 +780,9 @@
MySqlCommand cmd = cnn.CreateCommand();
cmd.Transaction = transaction;
- cmd.CommandText = "SELECT FolderMessageId FROM Message WHERE FolderId = ?FolderId AND DeletedFlag = true";
+ cmd.CommandText = "SELECT FolderMessageId FROM Message WHERE FolderId = ?FolderId AND MessageFlags = ?DeletedFlag";
cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?DeletedFlag", (int) StoreMessageFlags.Deleted);
// Get a list of deleted messages
MySqlDataReader reader = cmd.ExecuteReader();
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -34,7 +34,7 @@
{
// TODO: ensure connection is secure
- IAuthenticationToken token = ServiceState.remoteAdmin.NMailServer.AuthenticationProvider.Authenticate(user, password);
+ IAuthenticationToken token = ServiceState.RemoteAdmin.NMailServer.AuthenticationProvider.Authenticate(user, password);
if (token != null)
{
@@ -65,7 +65,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetNominalStoreFolder(token);
+ StoreFolder storeFolder = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetNominalStoreFolder(token);
return new StoreFolderSerializer(storeFolder);
}
@@ -86,7 +86,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
+ StoreFolder storeFolder = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
return new StoreFolderSerializer(storeFolder);
}
@@ -105,7 +105,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderName);
+ StoreFolder storeFolder = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderName);
return new StoreFolderSerializer(storeFolder);
}
@@ -125,7 +125,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- List<StoreFolder> subscribed = new List<StoreFolder>(ServiceState.remoteAdmin.NMailServer.LocalStore.GetSubscribed(token, "*"));
+ List<StoreFolder> subscribed = new List<StoreFolder>(ServiceState.RemoteAdmin.NMailServer.LocalStore.GetSubscribed(token, "*"));
List<StoreFolderSerializer> result = new List<StoreFolderSerializer>();
foreach (StoreFolder folder in subscribed)
@@ -164,40 +164,40 @@
List<int> currentList = new List<int>();
result.Add(currentList);
- StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
+ StoreFolder storeFolder = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
if (storeFolder != null)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCount(token, storeFolder));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCount(token, storeFolder));
if ((messageFlags & StoreMessageFlags.Answered) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Answered));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Answered));
}
if ((messageFlags & StoreMessageFlags.Deleted) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Deleted));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Deleted));
}
if ((messageFlags & StoreMessageFlags.Draft) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Draft));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Draft));
}
if ((messageFlags & StoreMessageFlags.Flagged) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Flagged));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Flagged));
}
if ((messageFlags & StoreMessageFlags.Recent) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Recent));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Recent));
}
if ((messageFlags & StoreMessageFlags.Seen) != 0)
{
- addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Seen));
+ addMessageCount(currentList, ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Seen));
}
}
else
@@ -232,11 +232,11 @@
if (token != null)
{
List<KeyValuePair<int, EnvelopeSerializer>> result = new List<KeyValuePair<int, EnvelopeSerializer>>();
- List<int> messageIds = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageIds(token, folderId);
+ List<int> messageIds = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageIds(token, folderId);
foreach (int messageId in messageIds)
{
- MessageHeaders headers = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
+ MessageHeaders headers = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
Envelope e = new Envelope(headers);
result.Add(new KeyValuePair<int, EnvelopeSerializer>(messageId, new EnvelopeSerializer(e)));
@@ -263,7 +263,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- MessageHeaders headers = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
+ MessageHeaders headers = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
Envelope e = new Envelope(headers);
return new EnvelopeSerializer(e);
}
@@ -286,7 +286,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- BodyStructure bodyStructure = ServiceState.remoteAdmin.NMailServer.LocalStore.GetBodyStructure(token, messageId, folderId);
+ BodyStructure bodyStructure = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetBodyStructure(token, messageId, folderId);
return new BodyStructureSerializer(bodyStructure);
}
@@ -309,7 +309,7 @@
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
- IMessageBodyPart part = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageMimePart(token, messageId, folderId, mimePart);
+ IMessageBodyPart part = ServiceState.RemoteAdmin.NMailServer.LocalStore.GetMessageMimePart(token, messageId, folderId, mimePart);
return Convert.ToBase64String(part.BodyData.Bytes);
}
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/ServiceState.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/ServiceState.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/ServiceState.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -20,12 +20,20 @@
{
public static Dictionary<Guid, IAuthenticationToken> authTokens = new Dictionary<Guid, IAuthenticationToken>();
- public static RemoteAdministration remoteAdmin;
+ private static RemoteAdministration remoteAdmin;
- static ServiceState()
+ public static RemoteAdministration RemoteAdmin
{
- remoteAdmin = (RemoteAdministration)Activator.GetObject(typeof(RemoteAdministration), "tcp://localhost:7877/RemoteAdministration.rem");
- SetupSponsorship(remoteAdmin, TimeSpan.MaxValue);
+ get
+ {
+ if (remoteAdmin == null)
+ {
+ remoteAdmin = (RemoteAdministration)Activator.GetObject(typeof(RemoteAdministration), "tcp://localhost:7877/RemoteAdministration.rem");
+ SetupSponsorship(remoteAdmin, TimeSpan.MaxValue);
+ }
+
+ return remoteAdmin;
+ }
}
static void SetupSponsorship(MarshalByRefObject o, TimeSpan timout)
Modified: NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -44,5 +44,18 @@
return result;
}
+
+ public static string GetDate(string s) {
+ DateTime dateTime;
+
+ if (DateTime.TryParse(s, out dateTime))
+ {
+ return dateTime.ToString("g");
+ }
+ else
+ {
+ return s;
+ }
+ }
}
}
Modified: NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -11,7 +11,7 @@
using RemoteAccessService;
-namespace NMail.WebAcess
+namespace NMail.WebAccess
{
public static class MailListDataSource
{
Modified: NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -59,6 +59,14 @@
string authToken = (string)session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
+ if (ras == null || authToken == null)
+ {
+ session.Abandon();
+ FormsAuthentication.SignOut();
+ FormsAuthentication.RedirectToLoginPage();
+ return null;
+ }
+
return GetStoreFolder(ras.GetStoreFolderByFolderId(authToken, folderId));
}
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-02-01 10:33:00 UTC (rev 125)
@@ -1,9 +1,21 @@
-body
+body
{
font-family: Sans-Serif;
-
+ background-color: White;
+ color: #1e2e21;
}
+a
+{
+ color: #1e2e21;
+}
+
+.LoginBody
+{
+ font-family: Sans-Serif;
+ background-color: White;
+}
+
.LoginBox
{
margin-top: 5em;
@@ -22,11 +34,12 @@
.ViewButton
{
text-align: center;
- background-color: lightblue;
+ background-color: #B8DECF;
height: 30px;
vertical-align: middle;
padding-left: 0.5em;
padding-right: 0.5em;
+ margin: 2px 2px 2px 2px;
}
.SubscribedFolderList
@@ -51,7 +64,7 @@
.MailListSelectedItem
{
- background-color: lightblue;
+ background-color: #B8DECF;
}
.MailListRow {}
@@ -61,3 +74,23 @@
{
background-color: buttonface;
}
+
+.EmptyZone
+{
+ background-image: url('../../Images/Skins/Default/EmptyZone.png');
+ background-repeat: no-repeat;
+ background-position: center center;
+ padding: 0.5em;
+}
+
+.WebPartTitle
+{
+ background-color: #C6EFDF;
+ font-size: large;
+}
+
+.WebPart
+{
+ background-color: White;
+ padding: 0px 0px 0px 0px;
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-02-01 10:33:00 UTC (rev 125)
@@ -13,7 +13,7 @@
CssClass="MailList"
Width="100%"
OnSelectedIndexChanged="MailList_OnSelectedIndexChanged"
- DataSourceID="MailListDataSource" DataKeyNames="Key">
+ DataKeyNames="Key">
<Columns>
<asp:TemplateField HeaderText="From">
@@ -28,7 +28,7 @@
</asp:TemplateField>
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
-<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.Date")) %>
+<%# NMail.WebAccess.Helper.GetDate((string) Eval("Value.Date")) %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
@@ -41,10 +41,3 @@
<HeaderStyle CssClass="MailListHeader" />
<AlternatingRowStyle CssClass="MailListAlternatingRow" />
</nmwa:RowClickableGridView>
-
-<asp:ObjectDataSource ID="MailListDataSource" runat="server" SelectMethod="GetMessageEnvelopes" TypeName="NMail.WebAcess.MailListDataSource" >
- <SelectParameters>
- <asp:SessionParameter DefaultValue="0" Name="folderId" SessionField="SelectedFolderId"
- Type="Int32" />
- </SelectParameters>
-</asp:ObjectDataSource>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -9,20 +9,81 @@
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
+using NMail.WebAccess;
+
public partial class Controls_Mail_MailList : System.Web.UI.UserControl, IWebPart
{
- protected void Page_Load(object sender, EventArgs e) {}
+ protected void Page_Init(object sender, EventArgs e)
+ {
+ Page.RegisterRequiresControlState(this);
+ }
+ protected void Page_PreRender(object sender, EventArgs e)
+ {
+ ObjectDataSource mailListDataSource = new ObjectDataSource("NMail.WebAccess.MailListDataSource", "GetMessageEnvelopes");
+ mailListDataSource.SelectParameters.Add("FolderId", TypeCode.Int32, this.selectedFolderId.ToString());
+
+ this.MailListGridView.DataSource = mailListDataSource;
+ this.MailListGridView.DataBind();
+ }
+
+ protected override object SaveControlState()
+ {
+ Hashtable result = new Hashtable();
+ result.Add("SelectedFolderId", this.selectedFolderId);
+ return result;
+ }
+
+ protected override void LoadControlState(object savedState)
+ {
+ this.selectedFolderId = (int)((Hashtable)savedState)["SelectedFolderId"];
+ }
+
+ private int selectedFolderId;
+
+ /// <summary>
+ /// The Id of the currently selected folder.
+ /// </summary>
+ public int SelectedFolderId
+ {
+ get { return selectedFolderId; }
+ set { selectedFolderId = value; }
+ }
+
+ /// <summary>
+ /// The Id of the currently selected message.
+ /// </summary>
+ public int SelectedMessageId
+ {
+ get
+ {
+ return (int) this.MailListGridView.SelectedValue;
+ }
+ }
+
protected void MailList_OnSelectedIndexChanged(object sender, EventArgs args)
{
- if (this.MailListGridView.SelectedIndex == -1)
+ if (this.selectedMessageChanged != null)
{
- Session.Remove("SelectedMessageId");
+ this.selectedMessageChanged(this, new EventArgs());
}
- else
+ }
+
+ private event EventHandler selectedMessageChanged;
+
+ /// <summary>
+ /// The event triggered when the selected message Id changes.
+ /// </summary>
+ public event EventHandler SelectedMessageChanged
+ {
+ add
{
- Session["SelectedMessageId"] = this.MailListGridView.SelectedValue;
+ this.selectedMessageChanged += value;
}
+ remove
+ {
+ this.selectedMessageChanged -= value;
+ }
}
#region IWebPart Members
@@ -64,7 +125,8 @@
{
get
{
- return Session["SelectedFolderName"] as string;
+ string folderName = Session["SelectedFolderName"] as string;
+ return (folderName == null) ? " " : folderName;
}
set
{
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-02-01 10:33:00 UTC (rev 125)
@@ -10,6 +10,14 @@
<form id="form1" runat="server">
<div class="MessageBody">
<asp:Literal ID="MessageBody" runat="server" />
+ <br />
+ <asp:Repeater ID="AttachmentsRepeater" runat="server">
+ <ItemTemplate>
+ <!-- Name -->
+ <!-- Size -->
+ <!-- Type -->
+ </ItemTemplate>
+ </asp:Repeater>
</div>
</form>
</body>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -2,6 +2,7 @@
using System.Data;
using System.Configuration;
using System.Collections;
+using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.Security;
@@ -17,29 +18,58 @@
public partial class Controls_Mail_MessageBody : System.Web.UI.Page
{
+ private int messageId;
+
+ public int MessageId
+ {
+ get { return messageId; }
+ }
+
+ private int folderId;
+
+ public int FolderId
+ {
+ get { return folderId; }
+ }
+
+ protected void ExtractQueryStringParams()
+ {
+ foreach (string key in Request.QueryString.AllKeys)
+ {
+ if (key.Trim().ToLower() == "messageid")
+ {
+ this.messageId = Int32.Parse(Request.QueryString[key]);
+ }
+ else if (key.Trim().ToLower() == "folderid")
+ {
+ this.folderId = Int32.Parse(Request.QueryString[key]);
+ }
+ }
+ }
+
protected void Page_Load(object sender, EventArgs e)
{
+ ExtractQueryStringParams();
+
// Ensure there is a valid folder Id
- if (Session["SelectedFolderId"] == null)
+ if (this.folderId == -1)
{
this.MessageBody.Text = "No folder selected.";
return;
}
// Ensure there is a valid message Id
- if (Session["SelectedMessageId"] == null)
+ if (this.messageId == -1)
{
this.MessageBody.Text = "No message selected.";
return;
}
// Get our session variables
- int selectedFolderId = (int) Session["SelectedFolderId"];
- int messageId = (int) Session["SelectedMessageId"];
string authToken = (string) Session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService) Session["RAS"];
- BodyStructureSerializer bs = ras.GetMessageStructure(authToken, messageId, selectedFolderId);
+ BodyStructureSerializer bs = ras.GetMessageStructure(authToken, messageId, folderId);
BodyStructure bodyStructure = Helper.GetBodyStructure(bs);
int bodyPartNumber = 1;
@@ -73,7 +103,7 @@
}
}
- string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, selectedFolderId);
+ string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, folderId);
ByteString bodyData = new ByteString(Convert.FromBase64String(base64Body), Encoding.UTF8);
SimpleBodyPart body = MessageHelper.ParseMessage(bodyData);
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-02-01 10:33:00 UTC (rev 125)
@@ -1,9 +1,12 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MessageViewer.ascx.cs" Inherits="Controls_Mail_MessageViewer" %>
<asp:Panel ID="EnvelopePanel" runat="server" Visible="false" Width="100%">
- <span class="MessageSubject">
- <asp:Literal ID="MessageSubject" runat="server" />
+ <span class="MessageEnvelope">
+ From: <asp:Literal ID="From" runat="server" /><br />
+ To: <asp:Literal ID="To" runat="server" /><br />
+ Date: <asp:Literal ID="Date" runat="server" /><br />
</span>
</asp:Panel>
-<iframe src="Controls/Mail/MessageBody.aspx" Width="100%" />
\ No newline at end of file
+<%-- A literal used to insert the iframe containing the message body --%>
+<asp:Literal ID="IFrameLiteral" runat="server" />
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -13,25 +13,155 @@
using NMail.WebAccess;
using RemoteAccessService;
-public partial class Controls_Mail_MessageViewer : System.Web.UI.UserControl
+public partial class Controls_Mail_MessageViewer : System.Web.UI.UserControl, IWebPart
{
- protected void Page_Load(object sender, EventArgs e)
- {
- // Ensure there is a valid folder and message Ids
- if (Session["SelectedFolderId"] != null && Session["SelectedMessageId"] != null)
+ protected void Page_Init(object sender, EventArgs e)
+ {
+ Page.RegisterRequiresControlState(this);
+ }
+
+ protected override object SaveControlState()
+ {
+ Hashtable state = new Hashtable();
+ state["FolderId"] = this.folderId;
+ state["MessageId"] = this.messageId;
+ return state;
+ }
+
+ protected override void LoadControlState(object savedState)
+ {
+ Hashtable state = (Hashtable) savedState;
+ this.folderId = (int) state["FolderId"];
+ this.messageId = (int) state["MessageId"];
+ }
+
+ private int messageId = -1;
+
+ /// <summary>
+ /// The message Id for the message displayed in the viewer.
+ /// </summary>
+ public int MessageId
+ {
+ get { return messageId; }
+ set { messageId = value; }
+ }
+
+ private int folderId = -1;
+
+ /// <summary>
+ /// The folder Id for the folder the message is in.
+ /// </summary>
+ public int FolderId
+ {
+ get { return folderId; }
+ set { folderId = value; }
+ }
+
+ protected void Page_PreRender(object sender, EventArgs e)
+ {
+ if (this.folderId != -1 && this.messageId != -1)
{
- // Get our session variables
- int selectedFolderId = (int)Session["SelectedFolderId"];
- int messageId = (int)Session["SelectedMessageId"];
string authToken = (string)Session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)Session["RAS"];
- EnvelopeSerializer es = ras.GetMessageEnvelope(authToken, messageId, selectedFolderId);
+ // Populate the message envelope panel
+ EnvelopeSerializer es = ras.GetMessageEnvelope(authToken, this.messageId, this.folderId);
Envelope envelope = Helper.GetEnvelope(es);
- this.MessageSubject.Text = envelope.Subject;
+ this.title = envelope.Subject;
+ this.From.Text = envelope.From;
+ this.To.Text = envelope.To;
+ this.Date.Text = Helper.GetDate(envelope.Date);
this.EnvelopePanel.Visible = true;
+
+ // Insert the iframe
+ string url = "Controls/Mail/MessageBody.aspx?messageId={0}&folderId={1}";
+ url = string.Format(url, this.messageId, this.folderId);
+ string iframe = string.Format("<iframe src='{0}' Width='100%' frameborder='no'/>", url);
+ this.IFrameLiteral.Text = iframe;
}
- }
+ else
+ {
+ this.EnvelopePanel.Visible = false;
+ }
+ }
+
+ #region IWebPart Members
+
+ private string catalogIconImageUrl;
+
+ public string CatalogIconImageUrl
+ {
+ get
+ {
+ return this.catalogIconImageUrl;
+ }
+ set
+ {
+ this.catalogIconImageUrl = value;
+ }
+ }
+
+ private string description = "Displays a message.";
+
+ public string Description
+ {
+ get
+ {
+ return this.description;
+ }
+ set
+ {
+ this.description = value;
+ }
+ }
+
+ public string Subtitle
+ {
+ get { return null; }
+ }
+
+ private string title = " ";
+
+ public string Title
+ {
+ get
+ {
+ return this.title;
+ }
+ set
+ {
+ this.title = value;
+ }
+ }
+
+ private string titleIconImageUrl;
+
+ public string TitleIconImageUrl
+ {
+ get
+ {
+ return this.titleIconImageUrl;
+ }
+ set
+ {
+ this.titleIconImageUrl = value;
+ }
+ }
+
+ private string titleUrl;
+
+ public string TitleUrl
+ {
+ get
+ {
+ return this.titleUrl;
+ }
+ set
+ {
+ this.titleUrl = value;
+ }
+ }
+ #endregion
}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -14,11 +14,37 @@
public partial class Controls_Mail_SubscribedFolderList : System.Web.UI.UserControl
{
- protected void Page_Load(object sender, EventArgs e)
- {
+ protected void Page_Init(object sender, EventArgs e)
+ {
+ Page.RegisterRequiresControlState(this);
+ }
- }
+ private int selectedFolderId = -1;
+ /// <summary>
+ /// The Id of the selected folder or -1 if non is selected.
+ /// </summary>
+ public int SelectedFolderId
+ {
+ get { return this.selectedFolderId; }
+ set { this.selectedFolderId = value; }
+ }
+
+ protected override object SaveControlState()
+ {
+ return this.selectedFolderId;
+ }
+
+ protected override void LoadControlState(object savedState)
+ {
+ this.selectedFolderId = (int)savedState;
+ }
+
+ /// <summary>
+ /// Gets the selected folder as a string to display in the folder list.
+ /// </summary>
+ /// <param name="o">The folder object.</param>
+ /// <returns>The string.</returns>
protected string GetFolderString(object o) {
StoreFolder f = (StoreFolder) o;
StringBuilder result = new StringBuilder();
@@ -47,21 +73,30 @@
protected void FolderRepeater_OnItemCommand(object sender, CommandEventArgs args)
{
- int folderId = int.Parse(args.CommandArgument as string);
- NMail.DataTypes.LocalStore.StoreFolder folder = NMail.WebAccess.SubscribedFolderDataSource.GetStoreFolder(folderId);
+ int folderId = -1;
+ int.TryParse(args.CommandArgument as string, out folderId);
- if (Session["SelectedFolderId"] != null)
+ if (folderId != this.selectedFolderId && this.selectedFolderIdChanged != null)
{
- int currentFolderId = (int)Session["SelectedFolderId"];
-
- // If the folder has changed remove the selected message Id
- if (folderId != currentFolderId)
- {
- Session.Remove("SelectedMessageId");
- }
+ this.selectedFolderId = folderId;
+ this.selectedFolderIdChanged(this, new EventArgs());
}
+ }
- Session["SelectedFolderId"] = folderId;
- Session["SelectedFolderName"] = folder.FullFolderName;
- }
+ private event EventHandler selectedFolderIdChanged;
+
+ /// <summary>
+ /// The event triggered when the selected folder Id changes.
+ /// </summary>
+ public event EventHandler SelectedFolderIdChanged
+ {
+ add
+ {
+ this.selectedFolderIdChanged += value;
+ }
+ remove
+ {
+ this.selectedFolderIdChanged -= value;
+ }
+ }
}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Login.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Login.aspx 2007-02-01 10:33:00 UTC (rev 125)
@@ -6,7 +6,7 @@
<head runat="server">
<title>NMail Login</title>
</head>
-<body>
+<body class="LoginBody">
<form id="form1" runat="server">
<div align="center" class="LoginBox">
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-02-01 10:33:00 UTC (rev 125)
@@ -1,4 +1,4 @@
-<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
+<%@ Page Language="C#" Trace="true" TraceMode="SortByTime" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
<%@ Register Src="Controls/Mail/MessageViewer.ascx" TagName="MessageViewer" TagPrefix="uc4" %>
@@ -20,45 +20,32 @@
<table width="100%" border="0">
<tr>
- <td rowspan="3" valign="top">
- <asp:WebPartZone ID="LeftZone" runat="server" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
+ <td valign="top">
+ <asp:WebPartZone ID="LeftZone" runat="server" HeaderText=" " LayoutOrientation="Vertical" BorderStyle="None" EmptyZoneText=" " PartStyle-CssClass="WebPart" PartTitleStyle-CssClass="WebPartTitle">
<CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
<uc2:SubscribedFolderList ID="SubscribedFolderList" runat="server" />
<uc1:LinkButtonList ID="ViewList" runat="server" />
</ZoneTemplate>
+ <EmptyZoneTextStyle CssClass="EmptyZone" />
</asp:WebPartZone>
</td>
<td valign="top">
- <asp:WebPartZone Width="100%" ID="TopZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderStyle="None">
- <CloseVerb Enabled="False" Visible="False" />
- </asp:WebPartZone>
- </td>
- <td rowspan="3" valign="top">
- <asp:WebPartZone ID="RightZone" runat="server" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
- <CloseVerb Enabled="False" Visible="False" />
- <ZoneTemplate>
- </ZoneTemplate>
- </asp:WebPartZone>
- </td>
- </tr>
- <tr>
- <td valign="top">
- <asp:WebPartZone Width="100%" ID="CenterZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
+ <asp:WebPartZone Width="100%" ID="CenterZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderStyle="None" EmptyZoneText=" " PartStyle-CssClass="WebPart" PartTitleStyle-CssClass="WebPartTitle">
<CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
- <uc3:MailList ID="MailList1" runat="server" />
+ <uc3:MailList ID="MailList" runat="server" />
+ <uc4:MessageViewer ID="MessageViewer" runat="server" />
</ZoneTemplate>
+ <EmptyZoneTextStyle CssClass="EmptyZone" />
</asp:WebPartZone>
</td>
- </tr>
- <tr>
- <td valign="top">
- <asp:WebPartZone ID="BottomZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderColor="Transparent" BorderStyle="None" Width="100%">
- <CloseVerb Enabled="false" Visible="false" />
+ <td valign="top">
+ <asp:WebPartZone ID="RightZone" runat="server" HeaderText=" " BorderColor="Transparent" BorderStyle="None" EmptyZoneText=" " PartStyle-CssClass="WebPart" PartTitleStyle-CssClass="WebPartTitle">
+ <CloseVerb Enabled="False" Visible="False" />
<ZoneTemplate>
- <uc4:MessageViewer ID="MessageViewer1" runat="server" />
</ZoneTemplate>
+ <EmptyZoneTextStyle CssClass="EmptyZone" />
</asp:WebPartZone>
</td>
</tr>
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx.cs 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx.cs 2007-02-01 10:33:00 UTC (rev 125)
@@ -21,11 +21,46 @@
// Setup the view list
List<LinkButtonListItem> viewItems = new List<LinkButtonListItem>();
viewItems.Add(new LinkButtonListItem("Calendar", "ViewButton", new EventHandler(ShowCalendarView_Clicked)));
+ viewItems.Add(new LinkButtonListItem("Logout", "ViewButton", new EventHandler(Logout_Clicked)));
+ this.ViewList.SetListItems(viewItems);
- this.ViewList.SetListItems(viewItems);
+ this.SubscribedFolderList.SelectedFolderIdChanged += new EventHandler(SubscribedFolderList_SelectedFolderIdChanged);
+ this.MailList.SelectedMessageChanged += new EventHandler(MailList_SelectedMessageChanged);
}
+ void SubscribedFolderList_SelectedFolderIdChanged(object sender, EventArgs args)
+ {
+ OnSelectedFolderIdChanged(this.SubscribedFolderList.SelectedFolderId);
+ }
+
+ void MailList_SelectedMessageChanged(object sender, EventArgs e)
+ {
+ this.MessageViewer.MessageId = this.MailList.SelectedMessageId;
+ }
+
+ protected void OnSelectedFolderIdChanged(int folderId)
+ {
+ string folderName = null;
+
+ if (folderId != -1)
+ {
+ NMail.DataTypes.LocalStore.StoreFolder folder = NMail.WebAccess.SubscribedFolderDataSource.GetStoreFolder(folderId);
+ folderName = folder.FullFolderName;
+ }
+
+ this.SubscribedFolderList.SelectedFolderId = folderId;
+ this.MailList.SelectedFolderId = folderId;
+ this.MessageViewer.FolderId = folderId;
+ }
+
protected void ShowCalendarView_Clicked(object sender, EventArgs ea)
{
- }
+ }
+
+ protected void Logout_Clicked(object sender, EventArgs ea)
+ {
+ Session.Abandon();
+ FormsAuthentication.SignOut();
+ FormsAuthentication.RedirectToLoginPage();
+ }
}
Modified: NMail/trunk/NMail.WebAccess/Web.config
===================================================================
--- NMail/trunk/NMail.WebAccess/Web.config 2007-01-26 12:46:37 UTC (rev 124)
+++ NMail/trunk/NMail.WebAccess/Web.config 2007-02-01 10:33:00 UTC (rev 125)
@@ -24,7 +24,7 @@
<connectionStrings/>
<system.web>
- <pages theme="Default" enableEventValidation="false" viewStateEncryptionMode="Never"/>
+ <pages theme="Default" viewStateEncryptionMode="Never" enableEventValidation="false"/>
<!--
Set compilation debug="true" to insert debugging
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-26 12:46:48
|
Revision: 124
http://svn.sourceforge.net/nmailserver/?rev=124&view=rev
Author: tmyroadctfig
Date: 2007-01-26 04:46:37 -0800 (Fri, 26 Jan 2007)
Log Message:
-----------
Further work on WebAccess.
Modified Paths:
--------------
NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
NMail/trunk/NMail.WebAccess/Web.config
Removed Paths:
-------------
NMail/trunk/NMail.WebAccess/Images/Skins/Default/ViewBackground.png
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -248,6 +248,29 @@
throw new InvalidOperationException("Authentication token is not valid.");
}
#endregion
+
+ #region GetMessageEnvelope
+ /// <summary>
+ /// Gets the message envelope for a given message Id.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="messageId">The Id of the message to get the envelope for.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
+ /// <returns>The message envelope.</returns>
+ [WebMethod]
+ public EnvelopeSerializer GetMessageEnvelope(string authToken, int messageId, int folderId)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ MessageHeaders headers = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
+ Envelope e = new Envelope(headers);
+ return new EnvelopeSerializer(e);
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+ #endregion
#region GetMessageStructure
/// <summary>
Modified: NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -29,5 +29,20 @@
return result;
}
+
+ public static Envelope GetEnvelope(EnvelopeSerializer es)
+ {
+ Envelope result = new Envelope(es.From, es.Date, es.Subject);
+
+ result.Bcc = es.Bcc;
+ result.Cc = es.Cc;
+ result.InReplyTo = es.InReplyTo;
+ result.MessageId = es.MessageId;
+ result.ReplyTo = es.ReplyTo;
+ result.Sender = es.Sender;
+ result.To = es.To;
+
+ return result;
+ }
}
}
Modified: NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -27,5 +27,16 @@
return result;
}
+
+ public static string EscapeScriptsAndImages(string html)
+ {
+ string result = html.Replace("<img", "<img");
+ result = result.Replace("<script", "<script");
+
+ // TODO: other nasty tags
+ // TODO: css proxy
+
+ return result;
+ }
}
}
Modified: NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -24,6 +24,14 @@
string authToken = (string)session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
+ if (ras == null || authToken == null)
+ {
+ session.Abandon();
+ FormsAuthentication.SignOut();
+ FormsAuthentication.RedirectToLoginPage();
+ return null;
+ }
+
StoreFolderSerializer[] serializedFolders = ras.GetAllSubscribedFolders(authToken);
List<StoreFolder> result = new List<StoreFolder>();
List<int> folderIds = new List<int>();
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-26 12:46:37 UTC (rev 124)
@@ -22,9 +22,7 @@
.ViewButton
{
text-align: center;
- background-image: url('../../Images/Skins/Default/ViewBackground.png');
- background-repeat: repeat-x;
- background-position: left top;
+ background-color: lightblue;
height: 30px;
vertical-align: middle;
padding-left: 0.5em;
@@ -62,4 +60,4 @@
.MailListHeader
{
background-color: buttonface;
-}
\ No newline at end of file
+}
Modified: NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
===================================================================
--- NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-26 12:46:37 UTC (rev 124)
@@ -155,6 +155,22 @@
<s:element minOccurs="0" maxOccurs="1" name="To" type="s:string" />
</s:sequence>
</s:complexType>
+ <s:element name="GetMessageEnvelope">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="messageId" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="folderId" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetMessageEnvelopeResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="Envelope" nillable="true" type="tns:EnvelopeSerializer" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
<s:element name="GetMessageStructure">
<s:complexType>
<s:sequence>
@@ -248,6 +264,12 @@
<wsdl:message name="GetAllMessageEnvelopesSoapOut">
<wsdl:part name="parameters" element="tns:GetAllMessageEnvelopesResponse" />
</wsdl:message>
+ <wsdl:message name="GetMessageEnvelopeSoapIn">
+ <wsdl:part name="parameters" element="tns:GetMessageEnvelope" />
+ </wsdl:message>
+ <wsdl:message name="GetMessageEnvelopeSoapOut">
+ <wsdl:part name="parameters" element="tns:GetMessageEnvelopeResponse" />
+ </wsdl:message>
<wsdl:message name="GetMessageStructureSoapIn">
<wsdl:part name="parameters" element="tns:GetMessageStructure" />
</wsdl:message>
@@ -289,6 +311,10 @@
<wsdl:input message="tns:GetAllMessageEnvelopesSoapIn" />
<wsdl:output message="tns:GetAllMessageEnvelopesSoapOut" />
</wsdl:operation>
+ <wsdl:operation name="GetMessageEnvelope">
+ <wsdl:input message="tns:GetMessageEnvelopeSoapIn" />
+ <wsdl:output message="tns:GetMessageEnvelopeSoapOut" />
+ </wsdl:operation>
<wsdl:operation name="GetMessageStructure">
<wsdl:input message="tns:GetMessageStructureSoapIn" />
<wsdl:output message="tns:GetMessageStructureSoapOut" />
@@ -363,6 +389,15 @@
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetMessageEnvelope">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageEnvelope" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
<wsdl:operation name="GetMessageStructure">
<soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageStructure" style="document" />
<wsdl:input>
@@ -447,6 +482,15 @@
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetMessageEnvelope">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageEnvelope" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
<wsdl:operation name="GetMessageStructure">
<soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageStructure" style="document" />
<wsdl:input>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -19,9 +19,23 @@
{
protected void Page_Load(object sender, EventArgs e)
{
+ // Ensure there is a valid folder Id
+ if (Session["SelectedFolderId"] == null)
+ {
+ this.MessageBody.Text = "No folder selected.";
+ return;
+ }
+
+ // Ensure there is a valid message Id
+ if (Session["SelectedMessageId"] == null)
+ {
+ this.MessageBody.Text = "No message selected.";
+ return;
+ }
+
+ // Get our session variables
int selectedFolderId = (int) Session["SelectedFolderId"];
int messageId = (int) Session["SelectedMessageId"];
-
string authToken = (string) Session["AuthToken"];
RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService) Session["RAS"];
@@ -29,6 +43,7 @@
BodyStructure bodyStructure = Helper.GetBodyStructure(bs);
int bodyPartNumber = 1;
+ bool htmlBody = false;
if (bodyStructure.Count == 0)
{
@@ -51,6 +66,7 @@
if (subType == "html")
{
// We'll display the first HTML part we find
+ htmlBody = true;
break;
}
}
@@ -58,8 +74,16 @@
}
string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, selectedFolderId);
- string bodyData = Encoding.UTF8.GetString(Convert.FromBase64String(base64Body));
+ ByteString bodyData = new ByteString(Convert.FromBase64String(base64Body), Encoding.UTF8);
+ SimpleBodyPart body = MessageHelper.ParseMessage(bodyData);
- this.MessageBody.Text = bodyData;
+ if (htmlBody)
+ {
+ this.MessageBody.Text = HtmlEscaper.EscapeScriptsAndImages(body.Data.ToString());
+ }
+ else
+ {
+ this.MessageBody.Text = HtmlEscaper.EscapeAll(body.Data.ToString());
+ }
}
}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-01-26 12:46:37 UTC (rev 124)
@@ -1,3 +1,9 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MessageViewer.ascx.cs" Inherits="Controls_Mail_MessageViewer" %>
-<iframe src="Controls/Mail/MessageBody.aspx"></iframe>
\ No newline at end of file
+<asp:Panel ID="EnvelopePanel" runat="server" Visible="false" Width="100%">
+ <span class="MessageSubject">
+ <asp:Literal ID="MessageSubject" runat="server" />
+ </span>
+</asp:Panel>
+
+<iframe src="Controls/Mail/MessageBody.aspx" Width="100%" />
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -9,10 +9,29 @@
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
+using NMail.DataTypes;
+using NMail.WebAccess;
+using RemoteAccessService;
+
public partial class Controls_Mail_MessageViewer : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
+ // Ensure there is a valid folder and message Ids
+ if (Session["SelectedFolderId"] != null && Session["SelectedMessageId"] != null)
+ {
+ // Get our session variables
+ int selectedFolderId = (int)Session["SelectedFolderId"];
+ int messageId = (int)Session["SelectedMessageId"];
+ string authToken = (string)Session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)Session["RAS"];
- }
+ EnvelopeSerializer es = ras.GetMessageEnvelope(authToken, messageId, selectedFolderId);
+ Envelope envelope = Helper.GetEnvelope(es);
+
+ this.MessageSubject.Text = envelope.Subject;
+
+ this.EnvelopePanel.Visible = true;
+ }
+ }
}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-26 12:46:37 UTC (rev 124)
@@ -50,6 +50,17 @@
int folderId = int.Parse(args.CommandArgument as string);
NMail.DataTypes.LocalStore.StoreFolder folder = NMail.WebAccess.SubscribedFolderDataSource.GetStoreFolder(folderId);
+ if (Session["SelectedFolderId"] != null)
+ {
+ int currentFolderId = (int)Session["SelectedFolderId"];
+
+ // If the folder has changed remove the selected message Id
+ if (folderId != currentFolderId)
+ {
+ Session.Remove("SelectedMessageId");
+ }
+ }
+
Session["SelectedFolderId"] = folderId;
Session["SelectedFolderName"] = folder.FullFolderName;
}
Deleted: NMail/trunk/NMail.WebAccess/Images/Skins/Default/ViewBackground.png
===================================================================
(Binary files differ)
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-26 12:46:37 UTC (rev 124)
@@ -21,7 +21,7 @@
<table width="100%" border="0">
<tr>
<td rowspan="3" valign="top">
- <asp:WebPartZone ID="LeftZone" runat="server" HeaderText=" ">
+ <asp:WebPartZone ID="LeftZone" runat="server" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
<CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
<uc2:SubscribedFolderList ID="SubscribedFolderList" runat="server" />
@@ -30,13 +30,13 @@
</asp:WebPartZone>
</td>
<td valign="top">
- <asp:WebPartZone Width="100%" ID="TopZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
- <CloseVerb Enabled="false" Visible="false" />
+ <asp:WebPartZone Width="100%" ID="TopZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderStyle="None">
+ <CloseVerb Enabled="False" Visible="False" />
</asp:WebPartZone>
</td>
<td rowspan="3" valign="top">
- <asp:WebPartZone ID="RightZone" runat="server" HeaderText=" ">
- <CloseVerb Enabled="false" Visible="false" />
+ <asp:WebPartZone ID="RightZone" runat="server" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
+ <CloseVerb Enabled="False" Visible="False" />
<ZoneTemplate>
</ZoneTemplate>
</asp:WebPartZone>
@@ -44,7 +44,7 @@
</tr>
<tr>
<td valign="top">
- <asp:WebPartZone Width="100%" ID="CenterZone" runat="server" LayoutOrientation="Vertical" HeaderText=" ">
+ <asp:WebPartZone Width="100%" ID="CenterZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderColor="Transparent" BorderStyle="None">
<CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
<uc3:MailList ID="MailList1" runat="server" />
@@ -54,7 +54,7 @@
</tr>
<tr>
<td valign="top">
- <asp:WebPartZone Width="100%" ID="BottomZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
+ <asp:WebPartZone ID="BottomZone" runat="server" LayoutOrientation="Vertical" HeaderText=" " BorderColor="Transparent" BorderStyle="None" Width="100%">
<CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
<uc4:MessageViewer ID="MessageViewer1" runat="server" />
Modified: NMail/trunk/NMail.WebAccess/Web.config
===================================================================
--- NMail/trunk/NMail.WebAccess/Web.config 2007-01-24 09:02:05 UTC (rev 123)
+++ NMail/trunk/NMail.WebAccess/Web.config 2007-01-26 12:46:37 UTC (rev 124)
@@ -24,7 +24,7 @@
<connectionStrings/>
<system.web>
- <pages theme="Default"/>
+ <pages theme="Default" enableEventValidation="false" viewStateEncryptionMode="Never"/>
<!--
Set compilation debug="true" to insert debugging
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-24 09:02:08
|
Revision: 123
http://svn.sourceforge.net/nmailserver/?rev=123&view=rev
Author: tmyroadctfig
Date: 2007-01-24 01:02:05 -0800 (Wed, 24 Jan 2007)
Log Message:
-----------
Changed some LocalStore methods to use folderId instead of folder. Further work on WebAccess.
Modified Paths:
--------------
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
NMail/trunk/NMail/Helper/MimeHelper.cs
NMail/trunk/NMail/NMail.csproj
NMail/trunk/NMail.ImapService/State/ExamineState.cs
NMail/trunk/NMail.LocalStore/LocalStore.cs
NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj
NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
Added Paths:
-----------
NMail/trunk/NMail/DataTypes/BodyStructure.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/MessageHeadersSerializer.cs
NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
Removed Paths:
-------------
NMail/trunk/NMail/DataTypes/Imap/BodyStructure.cs
Copied: NMail/trunk/NMail/DataTypes/BodyStructure.cs (from rev 112, NMail/trunk/NMail/DataTypes/Imap/BodyStructure.cs)
===================================================================
--- NMail/trunk/NMail/DataTypes/BodyStructure.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/BodyStructure.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2004-2006 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using NMail.Helper;
+
+namespace NMail.DataTypes {
+ /// <summary>
+ /// Represents a the structure of a message body.
+ /// </summary>
+ [Serializable]
+ public class BodyStructure : List<BodyStructure> {
+
+ public BodyStructure(IMessageBodyPart bodyPart) {
+ this.headers = bodyPart.Headers;
+
+ if (bodyPart.MultipartBody) {
+ foreach (IMessageBodyPart part in bodyPart.MimeParts) {
+ this.Add(new BodyStructure(part));
+ }
+ } else {
+ // Count the number of lines in the message body
+ string bodyData = bodyPart.BodyData.ToString();
+ int index = bodyData.IndexOf(Message.Terminator);
+ while (index != -1) {
+ this.bodyLineCount++;
+ index = bodyData.IndexOf(Message.Terminator, index + 1);
+ }
+
+ this.bodyCharacterCount = bodyData.Length;
+ }
+ }
+
+ public BodyStructure(MessageHeaders headers) {
+ }
+
+ private MessageHeaders headers;
+
+ /// <summary>
+ /// The message headers associated with this level of the body structure.
+ /// </summary>
+ public MessageHeaders Headers {
+ get { return headers; }
+ set { headers = value; }
+ }
+
+ private int bodyLineCount;
+
+ /// <summary>
+ /// The number of lines in the message body. Only valid for bodystructures
+ /// without multiple parts.
+ /// </summary>
+ public int BodyLineCount {
+ get { return bodyLineCount; }
+ set { bodyLineCount = value; }
+ }
+
+ private int bodyCharacterCount;
+
+ /// <summary>
+ /// The number of characters in the body. Only valid for bodystructures
+ /// witout multiple parts.
+ /// </summary>
+ public int BodyCharacterCount {
+ get { return bodyCharacterCount; }
+ set { bodyCharacterCount = value; }
+ }
+
+
+ public override string ToString() {
+ if (this.Count > 0) {
+ StringBuilder data = new StringBuilder();
+ data.Append("(");
+
+ foreach (BodyStructure child in this) {
+ data.Append(child.ToString());
+ }
+
+ data.Append("\"MIXED\")");
+ return data.ToString();
+
+ } else {
+ MimeContentTransferEncoding encoding = MimeHelper.GetTransferEncoding(this.headers);
+ MimeContentType contentType = MimeHelper.GetContentType(this.headers);
+ string charset = MimeHelper.GetCharacterSet(this.headers);
+
+ string encodingStr = encoding.ToString().ToUpper();
+ if (encoding == MimeContentTransferEncoding.EightBit) {
+ encodingStr = "8bit";
+ } else if (encoding == MimeContentTransferEncoding.SevenBit) {
+ encodingStr = "7bit";
+ }
+
+ return string.Format("(\"{0}\" \"{1}\" (\"charset\" \"{2}\") {3} {4} \"{5}\" {6} {7} NIL NIL NIL)",
+ contentType.ToString().ToLower(),
+ "plain",
+ charset,
+ "NIL", // body-fld-id
+ "NIL", // body-fld-desc
+ encodingStr,
+ this.bodyCharacterCount,
+ this.bodyLineCount);
+ }
+ }
+ }
+}
Deleted: NMail/trunk/NMail/DataTypes/Imap/BodyStructure.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Imap/BodyStructure.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail/DataTypes/Imap/BodyStructure.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -1,79 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using NMail.Helper;
-
-namespace NMail.DataTypes.Imap {
- public class BodyStructure {
-
- protected IMessageBodyPart bodyPart;
-
- public BodyStructure(IMessageBodyPart bodyPart) {
- this.bodyPart = bodyPart;
- }
-
- public override string ToString() {
- if (this.bodyPart.MultipartBody) {
- StringBuilder data = new StringBuilder();
- data.Append("(");
-
- foreach (IMessageBodyPart part in this.bodyPart.MimeParts) {
- BodyStructure partStructure = new BodyStructure(part);
- data.Append(partStructure.ToString());
- }
-
- data.Append("\"MIXED\")");
- return data.ToString();
-
- } else {
- MimeContentTransferEncoding encoding = MimeHelper.GetTransferEncoding(this.bodyPart.Headers);
- MimeContentType contentType = MimeHelper.GetContentType(this.bodyPart.Headers);
- string charset = MimeHelper.GetCharacterSet(this.bodyPart.Headers);
-
- // Count the number of lines in the message body
- string bodyData = this.bodyPart.BodyData.ToString();
- int lines = 0;
- int index = bodyData.IndexOf(Message.Terminator);
- while (index != -1) {
- lines++;
- index = bodyData.IndexOf(Message.Terminator, index + 1);
- }
-
- string encodingStr = encoding.ToString().ToUpper();
- if (encoding == MimeContentTransferEncoding.EightBit) {
- encodingStr = "8bit";
- } else if (encoding == MimeContentTransferEncoding.SevenBit) {
- encodingStr = "7bit";
- }
-
- return string.Format("(\"{0}\" \"{1}\" (\"charset\" \"{2}\") {3} {4} \"{5}\" {6} {7} NIL NIL NIL)",
- contentType.ToString().ToLower(),
- "plain",
- charset,
- "NIL", // body-fld-id
- "NIL", // body-fld-desc
- encodingStr,
- this.bodyPart.BodyData.Length,
- lines);
- }
- }
- }
-}
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -273,19 +273,28 @@
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <param name="messagePart">The number of the part to get.</param>
/// <returns>The MIME part or null if the part is invalid.</returns>
- IMessageBodyPart GetMessageMimePart(IAuthenticationToken authToken, int messageId, StoreFolder folder, int messagePart);
+ IMessageBodyPart GetMessageMimePart(IAuthenticationToken authToken, int messageId, int folderId, int messagePart);
/// <summary>
/// Gets the entire message.
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message or null if the message Id is invalid.</returns>
- Message GetMessage(IAuthenticationToken authToken, int messageId, StoreFolder folder);
+ Message GetMessage(IAuthenticationToken authToken, int messageId, int folderId);
+
+ /// <summary>
+ /// Gets the body structure for a message.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="messageId">The Id of the message to get the structure for.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
+ /// <returns>The body structure or null.</returns>
+ BodyStructure GetBodyStructure(IAuthenticationToken authToken, int messageId, int folderId);
#endregion
#region Message Counts
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -214,18 +214,18 @@
/// Gets a specific MIME part from the message.
/// </summary>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <param name="messagePart">The number of the part to get.</param>
/// <returns>The MIME part or null if the part is invalid.</returns>
- IMessageBodyPart GetMessageMimePart(int messageId, StoreFolder folder, int messagePart);
+ IMessageBodyPart GetMessageMimePart(int messageId, int folderId, int messagePart);
/// <summary>
/// Gets the entire message.
/// </summary>
/// <param name="messageId">The Id of the message to get.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message or null if the message Id is invalid.</returns>
- Message GetMessage(int messageId, StoreFolder folder);
+ Message GetMessage(int messageId, int folderId);
#endregion
#region Message Counts
Modified: NMail/trunk/NMail/Helper/MimeHelper.cs
===================================================================
--- NMail/trunk/NMail/Helper/MimeHelper.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail/Helper/MimeHelper.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -170,21 +170,35 @@
/// <param name="headers">The headers to get the content type from.</param>
/// <returns>The parsed content type.</returns>
public static MimeContentType GetContentType(MessageHeaders headers) {
- return GetContentType(headers[ContentTypeHeader]);
+ string temp;
+ return GetContentType(headers[ContentTypeHeader], out temp);
}
/// <summary>
/// Gets the MIME content type from the given MIME header line. The default
/// content type is text.
/// </summary>
+ /// <param name="headers">The headers to get the content type from.</param>
+ /// <param name="subType">The detected sub-type.</param>
+ /// <returns>The parsed content type.</returns>
+ public static MimeContentType GetContentType(MessageHeaders headers, out string subType) {
+ return GetContentType(headers[ContentTypeHeader], out subType);
+ }
+
+ /// <summary>
+ /// Gets the MIME content type from the given MIME header line. The default
+ /// content type is text.
+ /// </summary>
/// <remarks>
/// The MIME header line for this value is named "Content-Type".
/// </remarks>
/// <param name="contentType">The header line to parse.</param>
+ /// <param name="subType">The detected sub-type.</param>
/// <returns>The parsed content type.</returns>
- public static MimeContentType GetContentType(string contentType) {
+ public static MimeContentType GetContentType(string contentType, out string subType) {
if (contentType == null) {
+ subType = "plain";
return MimeContentType.Text;
} else {
@@ -192,8 +206,16 @@
string type = contentType.Replace("\"", string.Empty).Trim();
// Chop at the slash
- type = type.Substring(0, type.IndexOf("/")).ToLower();
+ string[] tokens = type.Split("/".ToCharArray(), 2);
+ if (tokens.Length < 2) {
+ subType = "plain";
+ return MimeContentType.Text;
+ }
+
+ subType = tokens[1].ToLower();
+ type = tokens[0].ToLower();
+
switch (type) {
case "text":
return MimeContentType.Text;
Modified: NMail/trunk/NMail/NMail.csproj
===================================================================
--- NMail/trunk/NMail/NMail.csproj 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail/NMail.csproj 2007-01-24 09:02:05 UTC (rev 123)
@@ -130,11 +130,11 @@
<Compile Include="DataTypes\ACLs\StoreFolderAcl.cs" />
<Compile Include="DataTypes\ACLs\StoreFolderPrivilege.cs" />
<Compile Include="DataTypes\ACLs\UserGroupAdminPrivilege.cs" />
+ <Compile Include="DataTypes\BodyStructure.cs" />
<Compile Include="DataTypes\Service\BaseService.cs" />
<Compile Include="DataTypes\Service\BaseSession.cs" />
<Compile Include="DataTypes\Envelope.cs" />
<Compile Include="DataTypes\IDnsClient.cs" />
- <Compile Include="DataTypes\Imap\BodyStructure.cs" />
<Compile Include="DataTypes\Imap\FetchBodyItem.cs" />
<Compile Include="DataTypes\Imap\FetchBodySectionType.cs" />
<Compile Include="DataTypes\Imap\FetchDataItem.cs" />
Modified: NMail/trunk/NMail.ImapService/State/ExamineState.cs
===================================================================
--- NMail/trunk/NMail.ImapService/State/ExamineState.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.ImapService/State/ExamineState.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -59,7 +59,7 @@
}
// Get the message
- Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder);
+ Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId);
// Attempt to copy the message
DeliveryResult result = LocalStore.DeliverMessage(Session.AuthenticationToken, message, dstFolder);
@@ -247,7 +247,7 @@
if (bodyItem.SectionType == FetchBodySectionType.All) {
// Get the entire message from the local store
- Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder);
+ Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId);
data += "[] {" + message.Size + "}" + this.Session.Connection.Terminator + message.Data.ToString();
response.AppendResponseItem(data);
@@ -281,7 +281,7 @@
}
// Get the mime part from the local store
- IMessageBodyPart bodyPart = LocalStore.GetMessageMimePart(Session.AuthenticationToken, messageUid, this.selectedFolder, mimePart);
+ IMessageBodyPart bodyPart = LocalStore.GetMessageMimePart(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId, mimePart);
if (extractSubPart) {
// TODO extractSubPart
@@ -299,7 +299,7 @@
if (mimePartString == string.Empty) {
// Get the full body from the store
- Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder);
+ Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId);
// Append it to the response
data += "[" + bodyItem.SectionName + "] {" + message.Size + "}"
@@ -318,7 +318,7 @@
}
// Get the mime part from the local store
- IMessageBodyPart bodyPart = LocalStore.GetMessageMimePart(Session.AuthenticationToken, messageUid, this.selectedFolder, mimePart);
+ IMessageBodyPart bodyPart = LocalStore.GetMessageMimePart(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId, mimePart);
if (extractSubPart) {
// TODO extractSubPart
@@ -336,8 +336,7 @@
StringBuilder data = new StringBuilder();
data.Append("BODYSTRUCTURE ");
- Message message = LocalStore.GetMessage(Session.AuthenticationToken, messageUid, Session.SelectedFolder);
- BodyStructure bodyStructure = new BodyStructure(message);
+ BodyStructure bodyStructure = LocalStore.GetBodyStructure(Session.AuthenticationToken, messageUid, Session.SelectedFolder.FolderId);
data.Append(bodyStructure.ToString());
response.AppendResponseItem(data.ToString());
Modified: NMail/trunk/NMail.LocalStore/LocalStore.cs
===================================================================
--- NMail/trunk/NMail.LocalStore/LocalStore.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.LocalStore/LocalStore.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -858,16 +858,16 @@
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <param name="messagePart">The number of the part to get.</param>
/// <returns>The MIME part or null if the part is invalid.</returns>
- public IMessageBodyPart GetMessageMimePart(IAuthenticationToken authToken, int messageId, StoreFolder folder, int messagePart) {
+ public IMessageBodyPart GetMessageMimePart(IAuthenticationToken authToken, int messageId, int folderId, int messagePart) {
// Ensure the user has rights to get the message
- if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) {
+ if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Read)) {
// Return the message part
- return LocalStoreData.GetMessageMimePart(messageId, folder, messagePart);
+ return LocalStoreData.GetMessageMimePart(messageId, folderId, messagePart);
} else {
return null;
@@ -881,22 +881,46 @@
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message or null if the message Id is invalid.</returns>
- public Message GetMessage(IAuthenticationToken authToken, int messageId, StoreFolder folder) {
+ public Message GetMessage(IAuthenticationToken authToken, int messageId, int folderId) {
// Ensure the user has rights to get the message
- if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) {
+ if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Read)) {
// Return the message
- return LocalStoreData.GetMessage(messageId, folder);
+ return LocalStoreData.GetMessage(messageId, folderId);
} else {
return null;
}
}
#endregion
+
+ #region Get Body Structure
+ /// <summary>
+ /// Gets the body structure for a message.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="messageId">The Id of the message to get the structure for.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
+ /// <returns>The body structure or null.</returns>
+ public BodyStructure GetBodyStructure(IAuthenticationToken authToken, int messageId, int folderId) {
+
+ // Ensure the user has rights to get the message
+ if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Read)) {
+
+ // Return the message
+ Message message = LocalStoreData.GetMessage(messageId, folderId);
+ return new BodyStructure(message);
+
+ } else {
+ return null;
+ }
+
+ }
#endregion
+ #endregion
#region Message Counts
#region Get Message Count
Modified: NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
===================================================================
--- NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -666,11 +666,11 @@
#endregion
#region GetMessageMimePart
- public IMessageBodyPart GetMessageMimePart(int messageId, StoreFolder folder, int messagePart) {
+ public IMessageBodyPart GetMessageMimePart(int messageId, int folderId, int messagePart) {
using (MySqlConnection cnn = MySqlHelper.GetConnection()) {
using (MySqlCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "SELECT md.Data FROM Message m, MessageData md WHERE m.MessageId = md.MessageId AND m.FolderId = ?FolderId AND m.FolderMessageId = ?FolderMessageId AND md.Part = ?Part";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
cmd.Parameters.Add("?Part", messagePart);
byte[] bodyDataBytes = (byte[]) cmd.ExecuteScalar();
@@ -681,21 +681,21 @@
#endregion
#region GetMessage
- public Message GetMessage(int messageId, StoreFolder folder) {
+ public Message GetMessage(int messageId, int folderId) {
using (MySqlConnection cnn = MySqlHelper.GetConnection()) {
using (MySqlCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "SELECT MimeMessage FROM Message WHERE FolderId = ?FolderId AND FolderMessageId = ?FolderMessageId";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
SByte sb = (SByte) cmd.ExecuteScalar();
bool mimeMessage = (sb == 1) ? true : false;
Message result = null;
- MessageHeaders headers = this.GetMessageHeaders(messageId, folder.FolderId);
+ MessageHeaders headers = this.GetMessageHeaders(messageId, folderId);
if (mimeMessage) {
cmd.CommandText = "SELECT Preamble, Postamble FROM Message WHERE FolderId = ?FolderId AND FolderMessageId = ?FolderMessageId";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
MySqlDataReader reader = cmd.ExecuteReader();
@@ -712,7 +712,7 @@
reader.Close();
cmd.CommandText = "SELECT md.Data FROM Message m, MessageData md WHERE m.MessageId = md.MessageId AND m.FolderId = ?FolderId AND m.FolderMessageId = ?FolderMessageId ORDER BY md.Part";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
reader = cmd.ExecuteReader();
ArrayList mimePartList = new ArrayList();
@@ -728,7 +728,7 @@
} else {
cmd.CommandText = "SELECT md.Data FROM Message m, MessageData md WHERE m.MessageId = md.MessageId AND m.FolderId = ?FolderId AND m.FolderMessageId = ?FolderMessageId AND md.Part = 1";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
byte[] data = (byte[]) cmd.ExecuteScalar();
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -248,7 +248,52 @@
throw new InvalidOperationException("Authentication token is not valid.");
}
#endregion
+
+ #region GetMessageStructure
+ /// <summary>
+ /// Gets the message structure for a given message Id and folder Id.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="messageId">The Id of the message to get.</param>
+ /// <param name="folderId">The Id of the folder to get.</param>
+ /// <returns>The message structure.</returns>
+ [WebMethod]
+ public BodyStructureSerializer GetMessageStructure(string authToken, int messageId, int folderId)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ BodyStructure bodyStructure = ServiceState.remoteAdmin.NMailServer.LocalStore.GetBodyStructure(token, messageId, folderId);
+ return new BodyStructureSerializer(bodyStructure);
+ }
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+ #endregion
+
+ #region GetMessageMimePart
+ /// <summary>
+ /// Gets a MIME part from the message body for a given message Id and folder Id.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="mimePart">The part of the message to get.</param>
+ /// <param name="messageId">The Id of the message to get.</param>
+ /// <param name="folderId">The Id of the folder to get.</param>
+ /// <returns>The MIME part.</returns>
+ [WebMethod]
+ public string GetMessageMimePart(string authToken, int mimePart, int messageId, int folderId)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ IMessageBodyPart part = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageMimePart(token, messageId, folderId, mimePart);
+ return Convert.ToBase64String(part.BodyData.Bytes);
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+ #endregion
+
protected IAuthenticationToken ValidateAuthenticationToken(string authToken)
{
Guid key = new Guid(Convert.FromBase64String(authToken));
Added: NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs (rev 0)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+using NMail.DataTypes;
+
+namespace NMail.RemoteAccessService.Serializers.DataTypes {
+ /// <summary>
+ /// A simple XML serializer for the bodystructure type.
+ /// </summary>
+ [XmlRoot("BodyStructure")]
+ [SoapType(IncludeInSchema = true, Namespace = "http://nmailserver.sf.net/RemoteAccessService/1.0", TypeName = "BodyStructure")]
+ public class BodyStructureSerializer {
+ public BodyStructureSerializer() { }
+
+ public BodyStructureSerializer(BodyStructure bodyStructure) {
+ this.headers = new MessageHeadersSerializer(bodyStructure.Headers);
+
+ foreach (BodyStructure child in bodyStructure) {
+ this.parts.Add(new BodyStructureSerializer(child));
+ }
+ }
+
+ private MessageHeadersSerializer headers;
+
+ public MessageHeadersSerializer Headers {
+ get { return headers; }
+ set { headers = value; }
+ }
+
+ private List<BodyStructureSerializer> parts = new List<BodyStructureSerializer>();
+
+ public List<BodyStructureSerializer> Parts {
+ get { return parts = new List<BodyStructureSerializer>(); }
+ }
+ }
+}
Added: NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/MessageHeadersSerializer.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/MessageHeadersSerializer.cs (rev 0)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/MessageHeadersSerializer.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+using NMail.DataTypes;
+
+namespace NMail.RemoteAccessService.Serializers.DataTypes {
+ /// <summary>
+ /// A simple XML serializer for the message headers type.
+ /// </summary>
+ [XmlRoot("Headers")]
+ [SoapType(IncludeInSchema = true, Namespace = "http://nmailserver.sf.net/RemoteAccessService/1.0", TypeName = "Headers")]
+ public class MessageHeadersSerializer {
+ public MessageHeadersSerializer() { }
+
+ public MessageHeadersSerializer(MessageHeaders messageHeaders) {
+ this.headers = Convert.ToBase64String(messageHeaders.Data.Bytes);
+ }
+
+ private string headers;
+
+ /// <summary>
+ /// A base 64 encoded copy of the raw headers.
+ /// </summary>
+ public string Headers {
+ get { return headers; }
+ set { headers = value; }
+ }
+
+ public MessageHeaders GetMessageHeaders() {
+ return new MessageHeaders(new ByteString(Convert.FromBase64String(this.headers), Encoding.ASCII));
+ }
+ }
+}
Modified: NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj 2007-01-24 09:02:05 UTC (rev 123)
@@ -33,8 +33,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="DataTypes\BodyStructureSerializer.cs" />
<Compile Include="DataTypes\EnvelopeSerializer.cs" />
<Compile Include="DataTypes\LocalStore\StoreFolderSerializer.cs" />
+ <Compile Include="DataTypes\MessageHeadersSerializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Added: NMail/trunk/NMail.WebAccess/App_Code/Helper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/Helper.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/Helper.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,33 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Text;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.DataTypes;
+using RemoteAccessService;
+
+namespace NMail.WebAccess
+{
+ public static class Helper
+ {
+ public static BodyStructure GetBodyStructure(BodyStructureSerializer serializedBody)
+ {
+ ByteString headerData = new ByteString(Convert.FromBase64String(serializedBody.Headers.Headers), Encoding.ASCII);
+ MessageHeaders headers = new MessageHeaders(headerData);
+ BodyStructure result = new BodyStructure(headers);
+
+ for (int i = 0; i < serializedBody.Parts.Length; i++)
+ {
+ result.Add(GetBodyStructure(serializedBody.Parts[i]));
+ }
+
+ return result;
+ }
+ }
+}
Added: NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/HtmlEscaper.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,31 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+namespace NMail.WebAccess
+{
+ /// <summary>
+ /// Provides methods for escaping HTML.
+ /// </summary>
+ public static class HtmlEscaper
+ {
+ public static string EscapeAll(object o)
+ {
+ return EscapeAll(o.ToString());
+ }
+
+ public static string EscapeAll(string html)
+ {
+ string result = html.Replace("<", "<");
+ result = result.Replace(">", ">");
+
+ return result;
+ }
+ }
+}
Added: NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/RowClickableGridView.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,46 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+namespace NMail.WebAccess
+{
+ /// <summary>
+ /// A grid view that allows rows to be selected by clicking on them.
+ /// </summary>
+ public class RowClickableGridView : System.Web.UI.WebControls.GridView
+ {
+ public RowClickableGridView() : base() {}
+
+ protected override void PrepareControlHierarchy()
+ {
+ base.PrepareControlHierarchy();
+
+ for (int i = 0; i < this.Rows.Count; i++)
+ {
+ string argument = "rowClicked:" + i;
+ this.Rows[i].Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(this, argument));
+ }
+ }
+
+ protected override void RaisePostBackEvent(string eventArgument)
+ {
+ if (eventArgument.StartsWith("rowClicked:"))
+ {
+ eventArgument = eventArgument.Remove(0, 11);
+ int row = int.Parse(eventArgument);
+ this.SelectedIndex = row;
+ this.OnSelectedIndexChanged(new EventArgs());
+ }
+ else
+ {
+ base.RaisePostBackEvent(eventArgument);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -44,6 +44,25 @@
return result;
}
+
+ public static NMail.DataTypes.LocalStore.StoreFolder GetStoreFolder(int folderId)
+ {
+ IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);
+ string authToken = (string)session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
+
+ return GetStoreFolder(ras.GetStoreFolderByFolderId(authToken, folderId));
+ }
+
+ public static NMail.DataTypes.LocalStore.StoreFolder GetStoreFolder(StoreFolderSerializer serializedFolder)
+ {
+ return new NMail.DataTypes.LocalStore.StoreFolder(
+ serializedFolder.NameSpace,
+ serializedFolder.Name,
+ serializedFolder.FolderId,
+ serializedFolder.ParentId,
+ serializedFolder.HasChildren);
+ }
}
public class StoreFolder : NMail.DataTypes.LocalStore.StoreFolder
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-24 09:02:05 UTC (rev 123)
@@ -1,6 +1,7 @@
body
{
font-family: Sans-Serif;
+
}
.LoginBox
@@ -30,6 +31,11 @@
padding-right: 0.5em;
}
+.SubscribedFolderList
+{
+ background-color: White;
+}
+
.SubscribedFolder
{
}
@@ -42,6 +48,7 @@
.MailList
{
width: 100%;
+ background-color: White;
}
.MailListSelectedItem
Modified: NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
===================================================================
--- NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-24 09:02:05 UTC (rev 123)
@@ -155,6 +155,55 @@
<s:element minOccurs="0" maxOccurs="1" name="To" type="s:string" />
</s:sequence>
</s:complexType>
+ <s:element name="GetMessageStructure">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="messageId" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="folderId" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetMessageStructureResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="BodyStructure" nillable="true" type="tns:BodyStructureSerializer" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="BodyStructureSerializer">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="Headers" type="tns:MessageHeadersSerializer" />
+ <s:element minOccurs="0" maxOccurs="1" name="Parts" type="tns:ArrayOfBodyStructureSerializer" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="MessageHeadersSerializer">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="Headers" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="ArrayOfBodyStructureSerializer">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="BodyStructureSerializer" nillable="true" type="tns:BodyStructureSerializer" />
+ </s:sequence>
+ </s:complexType>
+ <s:element name="GetMessageMimePart">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="mimePart" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="messageId" type="s:int" />
+ <s:element minOccurs="1" maxOccurs="1" name="folderId" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetMessageMimePartResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="GetMessageMimePartResult" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="AuthenticateSoapIn">
@@ -199,6 +248,18 @@
<wsdl:message name="GetAllMessageEnvelopesSoapOut">
<wsdl:part name="parameters" element="tns:GetAllMessageEnvelopesResponse" />
</wsdl:message>
+ <wsdl:message name="GetMessageStructureSoapIn">
+ <wsdl:part name="parameters" element="tns:GetMessageStructure" />
+ </wsdl:message>
+ <wsdl:message name="GetMessageStructureSoapOut">
+ <wsdl:part name="parameters" element="tns:GetMessageStructureResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetMessageMimePartSoapIn">
+ <wsdl:part name="parameters" element="tns:GetMessageMimePart" />
+ </wsdl:message>
+ <wsdl:message name="GetMessageMimePartSoapOut">
+ <wsdl:part name="parameters" element="tns:GetMessageMimePartResponse" />
+ </wsdl:message>
<wsdl:portType name="RemoteAccessServiceSoap">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateSoapIn" />
@@ -228,6 +289,14 @@
<wsdl:input message="tns:GetAllMessageEnvelopesSoapIn" />
<wsdl:output message="tns:GetAllMessageEnvelopesSoapOut" />
</wsdl:operation>
+ <wsdl:operation name="GetMessageStructure">
+ <wsdl:input message="tns:GetMessageStructureSoapIn" />
+ <wsdl:output message="tns:GetMessageStructureSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMessageMimePart">
+ <wsdl:input message="tns:GetMessageMimePartSoapIn" />
+ <wsdl:output message="tns:GetMessageMimePartSoapOut" />
+ </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RemoteAccessServiceSoap" type="tns:RemoteAccessServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -294,6 +363,24 @@
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetMessageStructure">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageStructure" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetMessageMimePart">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageMimePart" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RemoteAccessServiceSoap12" type="tns:RemoteAccessServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -360,6 +447,24 @@
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetMessageStructure">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageStructure" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetMessageMimePart">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetMessageMimePart" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:service name="RemoteAccessService">
<wsdl:port name="RemoteAccessServiceSoap" binding="tns:RemoteAccessServiceSoap">
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-01-24 09:02:05 UTC (rev 123)
@@ -1,5 +1,7 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MailList.ascx.cs" Inherits="Controls_Mail_MailList" %>
-<asp:GridView
+
+<%@ Register Namespace="NMail.WebAccess" TagPrefix="nmwa" %>
+<nmwa:RowClickableGridView
SkinID="MailList"
AutoGenerateColumns="false"
ID="MailListGridView"
@@ -10,17 +12,24 @@
SelectedRowStyle-CssClass="MailListSelectedItem"
CssClass="MailList"
Width="100%"
- DataSourceID="MailListDataSource">
+ OnSelectedIndexChanged="MailList_OnSelectedIndexChanged"
+ DataSourceID="MailListDataSource" DataKeyNames="Key">
<Columns>
<asp:TemplateField HeaderText="From">
- <ItemTemplate><%# Eval("Value.From") %></ItemTemplate>
+ <ItemTemplate>
+<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.From")) %>
+</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Subject">
- <ItemTemplate><%# Eval("Value.Subject") %></ItemTemplate>
+ <ItemTemplate>
+<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.Subject")) %>
+</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date">
- <ItemTemplate><%# Eval("Value.Date") %></ItemTemplate>
+ <ItemTemplate>
+<%# NMail.WebAccess.HtmlEscaper.EscapeAll(Eval("Value.Date")) %>
+</ItemTemplate>
</asp:TemplateField>
</Columns>
@@ -31,7 +40,7 @@
<SelectedRowStyle CssClass="MailListSelectedItem" />
<HeaderStyle CssClass="MailListHeader" />
<AlternatingRowStyle CssClass="MailListAlternatingRow" />
-</asp:GridView>
+</nmwa:RowClickableGridView>
<asp:ObjectDataSource ID="MailListDataSource" runat="server" SelectMethod="GetMessageEnvelopes" TypeName="NMail.WebAcess.MailListDataSource" >
<SelectParameters>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -13,6 +13,18 @@
{
protected void Page_Load(object sender, EventArgs e) {}
+ protected void MailList_OnSelectedIndexChanged(object sender, EventArgs args)
+ {
+ if (this.MailListGridView.SelectedIndex == -1)
+ {
+ Session.Remove("SelectedMessageId");
+ }
+ else
+ {
+ Session["SelectedMessageId"] = this.MailListGridView.SelectedValue;
+ }
+ }
+
#region IWebPart Members
private string catalogIconImageUrl;
@@ -48,17 +60,15 @@
get { return null; }
}
- private string title = "Mail List";
-
public string Title
{
get
{
- return this.title;
+ return Session["SelectedFolderName"] as string;
}
set
{
- this.title = value;
+ throw new NotSupportedException("Can't set the title manually for the mail list.");
}
}
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MessageBody.aspx.cs" Inherits="Controls_Mail_MessageBody" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>Untitled Page</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div class="MessageBody">
+ <asp:Literal ID="MessageBody" runat="server" />
+ </div>
+ </form>
+</body>
+</html>
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageBody.aspx.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,65 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Text;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.DataTypes;
+using NMail.Helper;
+using NMail.WebAccess;
+using RemoteAccessService;
+
+public partial class Controls_Mail_MessageBody : System.Web.UI.Page
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ int selectedFolderId = (int) Session["SelectedFolderId"];
+ int messageId = (int) Session["SelectedMessageId"];
+
+ string authToken = (string) Session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService) Session["RAS"];
+
+ BodyStructureSerializer bs = ras.GetMessageStructure(authToken, messageId, selectedFolderId);
+ BodyStructure bodyStructure = Helper.GetBodyStructure(bs);
+
+ int bodyPartNumber = 1;
+
+ if (bodyStructure.Count == 0)
+ {
+ // Simple message body, only one part to the message
+ bodyPartNumber = 1;
+ }
+ else
+ {
+ // Search for the best part
+ for (int i = 0; i < bodyStructure.Count; i++)
+ {
+ string subType;
+ MimeContentType contentType = MimeHelper.GetContentType(bodyStructure[i].Headers, out subType);
+
+ if (contentType == MimeContentType.Text)
+ {
+ // We'll take the first text part we find unless something better appears
+ bodyPartNumber = i + 1;
+
+ if (subType == "html")
+ {
+ // We'll display the first HTML part we find
+ break;
+ }
+ }
+ }
+ }
+
+ string base64Body = ras.GetMessageMimePart(authToken, bodyPartNumber, messageId, selectedFolderId);
+ string bodyData = Encoding.UTF8.GetString(Convert.FromBase64String(base64Body));
+
+ this.MessageBody.Text = bodyData;
+ }
+}
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,3 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MessageViewer.ascx.cs" Inherits="Controls_Mail_MessageViewer" %>
+
+<iframe src="Controls/Mail/MessageBody.aspx"></iframe>
\ No newline at end of file
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MessageViewer.ascx.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -0,0 +1,18 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+public partial class Controls_Mail_MessageViewer : System.Web.UI.UserControl
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+
+ }
+}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-01-24 09:02:05 UTC (rev 123)
@@ -2,25 +2,27 @@
<%@ Register Assembly="MenuPilot" Namespace="MenuPilot.Web.Ui" TagPrefix="mp" %>
-<asp:Repeater
- ID="FolderRepeater"
- runat="server"
- OnItemCommand="FolderRepeater_OnItemCommand"
- DataSourceID="SubscribedFolderDataSource">
-
- <ItemTemplate>
- <asp:LinkButton
- Text='<%# GetFolderString(Container.DataItem) %>'
- CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FolderId") %>'
- CommandName="SelectedFolderChanged"
- runat="server"
- ID="LinkButton" />
- <br />
- </ItemTemplate>
-</asp:Repeater>
+<div class="SubscribedFolderList">
+ <asp:Repeater
+ ID="FolderRepeater"
+ runat="server"
+ OnItemCommand="FolderRepeater_OnItemCommand"
+ DataSourceID="SubscribedFolderDataSource">
+
+ <ItemTemplate>
+ <asp:LinkButton
+ Text='<%# GetFolderString(Container.DataItem) %>'
+ CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FolderId") %>'
+ CommandName="SelectedFolderChanged"
+ runat="server"
+ ID="LinkButton" />
+ <br />
+ </ItemTemplate>
+ </asp:Repeater>
-<asp:ObjectDataSource
- ID="SubscribedFolderDataSource"
- runat="server"
- SelectMethod="GetSubscribedFolders"
- TypeName="NMail.WebAccess.SubscribedFolderDataSource" />
\ No newline at end of file
+ <asp:ObjectDataSource
+ ID="SubscribedFolderDataSource"
+ runat="server"
+ SelectMethod="GetSubscribedFolders"
+ TypeName="NMail.WebAccess.SubscribedFolderDataSource" />
+</div>
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-24 09:02:05 UTC (rev 123)
@@ -48,7 +48,9 @@
protected void FolderRepeater_OnItemCommand(object sender, CommandEventArgs args)
{
int folderId = int.Parse(args.CommandArgument as string);
+ NMail.DataTypes.LocalStore.StoreFolder folder = NMail.WebAccess.SubscribedFolderDataSource.GetStoreFolder(folderId);
Session["SelectedFolderId"] = folderId;
+ Session["SelectedFolderName"] = folder.FullFolderName;
}
}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-21 06:14:55 UTC (rev 122)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-24 09:02:05 UTC (rev 123)
@@ -1,5 +1,7 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
+<%@ Register Src="Controls/Mail/MessageViewer.ascx" TagName="MessageViewer" TagPrefix="uc4" %>
+
<%@ Register Src="Controls/Mail/MailList.ascx" TagName="MailList" TagPrefix="uc3" %>
<%@ Register Src="Controls/Mail/SubscribedFolderList.ascx" TagName="SubscribedFolderList" TagPrefix="uc2" %>
@@ -10,7 +12,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
- <title>Untitled Page</title>
+ <title>Mail</title>
</head>
<body>
<form id="form1" runat="server">
@@ -19,27 +21,31 @@
<table width="100%" border="0">
<tr>
<td rowspan="3" valign="top">
- <asp:WebPartZone ID="LeftZone" runat="server">
+ <asp:WebPartZone ID="LeftZone" runat="server" HeaderText=" ">
+ <CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
+ <uc2:SubscribedFolderList ID="SubscribedFolderList" runat="server" />
<uc1:LinkButtonList ID="ViewList" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
<td valign="top">
- <asp:WebPartZone ID="TopZone" runat="server" LayoutOrientation="Horizontal">
+ <asp:WebPartZone Width="100%" ID="TopZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
+ <CloseVerb Enabled="false" Visible="false" />
</asp:WebPartZone>
</td>
<td rowspan="3" valign="top">
- <asp:WebPartZone ID="RightZone" runat="server">
+ <asp:WebPartZone ID="RightZone" runat="server" HeaderText=" ">
+ <CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
- <uc2:SubscribedFolderList ID="SubscribedFolderList" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
</tr>
<tr>
<td valign="top">
- <asp:WebPartZone ID="CenterZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
+ <asp:WebPartZone Width="100%" ID="CenterZone" runat="server" LayoutOrientation="Vertical" HeaderText=" ">
+ <CloseVerb Enabled="false" Visible="false" />
<ZoneTemplate>
<uc3:MailList ID="MailList1" runat="server" />
</ZoneTemplate>
@@ -48,7 +54,11 @@
</tr>
<tr>
<td valign="top">
- <asp:WebPartZone ID="BottomZone" runat="server" LayoutOrientation="Horizontal">
+ <asp:WebPartZone Width="100%" ID="BottomZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
+ <CloseVerb Enabled="false" Visible="false" />
+ <ZoneTemplate>
+ <uc4:MessageViewer ID="MessageViewer1" runat="server" />
+ </ZoneTemplate>
</asp:WebPartZone>
</td>
</tr>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-21 06:15:01
|
Revision: 122
http://svn.sourceforge.net/nmailserver/?rev=122&view=rev
Author: tmyroadctfig
Date: 2007-01-20 22:14:55 -0800 (Sat, 20 Jan 2007)
Log Message:
-----------
Got an initial subscribed folder list and mail list working.
Modified Paths:
--------------
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
NMail/trunk/NMail.ImapService/State/ExamineState.cs
NMail/trunk/NMail.LocalStore/LocalStore.cs
NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Mail.aspx
Added Paths:
-----------
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/EnvelopeSerializer.cs
NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -214,9 +214,9 @@
/// Gets a list of message Ids for a given folder.
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The list of messages in the folder.</returns>
- List<int> GetMessageIds(IAuthenticationToken authToken, StoreFolder folder);
+ List<int> GetMessageIds(IAuthenticationToken authToken, int folderId);
#endregion
#region Message Flags
@@ -264,9 +264,9 @@
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of folder the message is in.</param>
/// <returns>The message headers or null if none exist.</returns>
- MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, StoreFolder folder);
+ MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, int folderId);
/// <summary>
/// Gets a specific MIME part from the message.
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -161,9 +161,9 @@
/// <summary>
/// Gets a list of message Ids for a given folder.
/// </summary>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The list of messages in the folder.</returns>
- List<int> GetMessageIds(StoreFolder folder);
+ List<int> GetMessageIds(int folderId);
#endregion
#region Message Flags
@@ -206,9 +206,9 @@
/// Gets the headers for the message.
/// </summary>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message headers or null if none exist.</returns>
- MessageHeaders GetMessageHeaders(int messageId, StoreFolder folder);
+ MessageHeaders GetMessageHeaders(int messageId, int folderId);
/// <summary>
/// Gets a specific MIME part from the message.
Modified: NMail/trunk/NMail.ImapService/State/ExamineState.cs
===================================================================
--- NMail/trunk/NMail.ImapService/State/ExamineState.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.ImapService/State/ExamineState.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -155,7 +155,7 @@
#region ensureMessageHeaders
protected virtual void ensureMessageHeaders(int messageUid, ref MessageHeaders messageHeaders) {
if (messageHeaders == null) {
- messageHeaders = this.LocalStore.GetMessageHeaders(Session.AuthenticationToken, messageUid, this.selectedFolder);
+ messageHeaders = this.LocalStore.GetMessageHeaders(Session.AuthenticationToken, messageUid, this.selectedFolder.FolderId);
}
}
#endregion
@@ -525,7 +525,7 @@
#region Search Command
public override void ProcessCommand(SearchCommand cmd) {
// Get a list of Ids for the folder
- List<int> messageUids = LocalStore.GetMessageIds(Session.AuthenticationToken, Session.SelectedFolder);
+ List<int> messageUids = LocalStore.GetMessageIds(Session.AuthenticationToken, Session.SelectedFolder.FolderId);
// Check if there was any messages in the folder
if (messageUids.Count > 0) {
Modified: NMail/trunk/NMail.LocalStore/LocalStore.cs
===================================================================
--- NMail/trunk/NMail.LocalStore/LocalStore.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.LocalStore/LocalStore.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -695,13 +695,13 @@
#region Get Message Ids
- public List<int> GetMessageIds(IAuthenticationToken authToken, StoreFolder folder) {
+ public List<int> GetMessageIds(IAuthenticationToken authToken, int folderId) {
// Ensure the user has rights to get the message Id
- if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) {
+ if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Read)) {
// Return the message Id
- return LocalStoreData.GetMessageIds(folder);
+ return LocalStoreData.GetMessageIds(folderId);
} else {
return new List<int>();
@@ -836,15 +836,15 @@
/// </summary>
/// <param name="authToken">The authentication credentials.</param>
/// <param name="messageId">The Id of the message to get the headers for.</param>
- /// <param name="folder">The folder the message is in.</param>
+ /// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message headers or null if none exist.</returns>
- public MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, StoreFolder folder) {
+ public MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, int folderId) {
// Ensure the user has rights to get the message headers
- if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) {
+ if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Read)) {
// Return the message headers
- return LocalStoreData.GetMessageHeaders(messageId, folder);
+ return LocalStoreData.GetMessageHeaders(messageId, folderId);
} else {
return null;
Modified: NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
===================================================================
--- NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -554,13 +554,13 @@
#endregion
#region GetMessageIds
- public List<int> GetMessageIds(StoreFolder folder) {
+ public List<int> GetMessageIds(int folderId) {
List<int> result = new List<int>();
using (MySqlConnection cnn = MySqlHelper.GetConnection()) {
using (MySqlCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "SELECT FolderMessageId FROM Message WHERE FolderId = ?FolderId";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
MySqlDataReader reader = cmd.ExecuteReader();
@@ -647,11 +647,11 @@
#endregion
#region GetMessageHeaders
- public MessageHeaders GetMessageHeaders(int messageId, StoreFolder folder) {
+ public MessageHeaders GetMessageHeaders(int messageId, int folderId) {
using (MySqlConnection cnn = MySqlHelper.GetConnection()) {
using (MySqlCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "SELECT Headers FROM Message WHERE FolderId = ?FolderId AND FolderMessageId = ?FolderMessageId";
- cmd.Parameters.Add("?FolderId", folder.FolderId);
+ cmd.Parameters.Add("?FolderId", folderId);
cmd.Parameters.Add("?FolderMessageId", messageId);
byte[] headerBytes = (byte[]) cmd.ExecuteScalar();
@@ -691,7 +691,7 @@
SByte sb = (SByte) cmd.ExecuteScalar();
bool mimeMessage = (sb == 1) ? true : false;
Message result = null;
- MessageHeaders headers = this.GetMessageHeaders(messageId, folder);
+ MessageHeaders headers = this.GetMessageHeaders(messageId, folder.FolderId);
if (mimeMessage) {
cmd.CommandText = "SELECT Preamble, Postamble FROM Message WHERE FolderId = ?FolderId AND FolderMessageId = ?FolderMessageId";
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -3,10 +3,14 @@
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
+using System.Xml;
+using System.Xml.Serialization;
using NMail.Authentication;
+using NMail.DataTypes;
using NMail.DataTypes.LocalStore;
using NMail.Server;
+using NMail.RemoteAccessService.Serializers.DataTypes;
using NMail.RemoteAccessService.Serializers.DataTypes.LocalStore;
/// <summary>
@@ -214,6 +218,37 @@
}
#endregion
+ #region GetAllMessageEnvelopes
+ /// <summary>
+ /// Gets all message envelopes and message Ids for a given folder.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="folderId">The folder to get the envelopes for.</param>
+ /// <returns>The list of envelopes.</returns>
+ [WebMethod]
+ public List<KeyValuePair<int, EnvelopeSerializer>> GetAllMessageEnvelopes(string authToken, int folderId)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ List<KeyValuePair<int, EnvelopeSerializer>> result = new List<KeyValuePair<int, EnvelopeSerializer>>();
+ List<int> messageIds = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageIds(token, folderId);
+
+ foreach (int messageId in messageIds)
+ {
+ MessageHeaders headers = ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageHeaders(token, messageId, folderId);
+ Envelope e = new Envelope(headers);
+
+ result.Add(new KeyValuePair<int, EnvelopeSerializer>(messageId, new EnvelopeSerializer(e)));
+ }
+
+ return result;
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+ #endregion
+
protected IAuthenticationToken ValidateAuthenticationToken(string authToken)
{
Guid key = new Guid(Convert.FromBase64String(authToken));
@@ -233,4 +268,32 @@
return null;
}
+
+ [XmlRoot("KeyValuePair")]
+ [SoapType(IncludeInSchema = true, Namespace = "http://nmailserver.sf.net/RemoteAccessService/1.0", TypeName = "KeyValuePair")]
+ public class KeyValuePair<TKey, TValue>
+ {
+ public KeyValuePair() {}
+
+ public KeyValuePair(TKey key, TValue value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ private TKey key;
+
+ public TKey Key
+ {
+ get { return key;}
+ set { key = value;}
+ }
+
+ private TValue value;
+
+ public TValue Value
+ {
+ get { return value;}
+ set { value = value;}
+ }
+ }
}
Added: NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/EnvelopeSerializer.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/EnvelopeSerializer.cs (rev 0)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/EnvelopeSerializer.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+using NMail.DataTypes;
+
+namespace NMail.RemoteAccessService.Serializers.DataTypes {
+ /// <summary>
+ /// A simple XML serializer for the message envelope type.
+ /// </summary>
+ [XmlRoot("Envelope")]
+ [SoapType(IncludeInSchema = true, Namespace = "http://nmailserver.sf.net/RemoteAccessService/1.0", TypeName = "Envelope")]
+ public class EnvelopeSerializer {
+ public EnvelopeSerializer() { }
+
+ public EnvelopeSerializer(Envelope envelope) {
+ this.bcc = envelope.Bcc;
+ this.cc = envelope.Cc;
+ this.date = envelope.Date;
+ this.from = envelope.From;
+ this.inReplyTo = envelope.InReplyTo;
+ this.messageId = envelope.MessageId;
+ this.replyTo = envelope.ReplyTo;
+ this.sender = envelope.Sender;
+ this.subject = envelope.Subject;
+ this.to = envelope.To;
+ }
+
+ private string bcc;
+
+ public string Bcc {
+ get { return bcc; }
+ set { bcc = value; }
+ }
+
+ private string cc;
+
+ public string Cc {
+ get { return cc; }
+ set { cc = value; }
+ }
+
+ private string date;
+
+ public string Date {
+ get { return date; }
+ set { date = value; }
+ }
+
+ private string from;
+
+ public string From {
+ get { return from; }
+ set { from = value; }
+ }
+
+ private string inReplyTo;
+
+ public string InReplyTo {
+ get { return inReplyTo; }
+ set { inReplyTo = value; }
+ }
+
+ private string messageId;
+
+ public string MessageId {
+ get { return messageId; }
+ set { messageId = value; }
+ }
+
+ private string replyTo;
+
+ public string ReplyTo {
+ get { return replyTo; }
+ set { replyTo = value; }
+ }
+
+ private string sender;
+
+ public string Sender {
+ get { return sender; }
+ set { sender = value; }
+ }
+
+ private string subject;
+
+ public string Subject {
+ get { return subject; }
+ set { subject = value; }
+ }
+
+ private string to;
+
+ public string To {
+ get { return to; }
+ set { to = value; }
+ }
+ }
+}
Modified: NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj
===================================================================
--- NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.RemoteAccessService.Serializers/NMail.RemoteAccessService.Serializers.csproj 2007-01-21 06:14:55 UTC (rev 122)
@@ -33,6 +33,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="DataTypes\EnvelopeSerializer.cs" />
<Compile Include="DataTypes\LocalStore\StoreFolderSerializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Added: NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/MailListDataSource.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -0,0 +1,35 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.Web.SessionState;
+
+using RemoteAccessService;
+
+namespace NMail.WebAcess
+{
+ public static class MailListDataSource
+ {
+ public static KeyValuePairOfInt32EnvelopeSerializer[] GetMessageEnvelopes(int folderId)
+ {
+ try
+ {
+ IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);
+ string authToken = (string)session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
+
+ return ras.GetAllMessageEnvelopes(authToken, folderId);
+
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-21 06:14:55 UTC (rev 122)
@@ -37,4 +37,22 @@
.SubscribedFolderUnread
{
font-weight: bold;
+}
+
+.MailList
+{
+ width: 100%;
+}
+
+.MailListSelectedItem
+{
+ background-color: lightblue;
+}
+
+.MailListRow {}
+.MailListAlternatingRow {}
+
+.MailListHeader
+{
+ background-color: buttonface;
}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.skin 2007-01-21 06:14:55 UTC (rev 122)
@@ -15,3 +15,5 @@
--%>
<asp:Image runat="server" SkinId="LoginBanner" ImageUrl="~/Images/Skins/Default/LoginBanner.jpg" />
+
+<%-- <asp:GridView runat="server" SkinId="MailList" Width="100%" /> --%>
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
===================================================================
--- NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-21 06:14:55 UTC (rev 122)
@@ -115,6 +115,46 @@
<s:element minOccurs="0" maxOccurs="unbounded" name="ArrayOfInt" nillable="true" type="tns:ArrayOfInt" />
</s:sequence>
</s:complexType>
+ <s:element name="GetAllMessageEnvelopes">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="folderId" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetAllMessageEnvelopesResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="GetAllMessageEnvelopesResult" type="tns:ArrayOfKeyValuePairOfInt32EnvelopeSerializer" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfKeyValuePairOfInt32EnvelopeSerializer">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="KeyValuePairOfInt32EnvelopeSerializer" nillable="true" type="tns:KeyValuePairOfInt32EnvelopeSerializer" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="KeyValuePairOfInt32EnvelopeSerializer">
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="Key" type="s:int" />
+ <s:element minOccurs="0" maxOccurs="1" name="Value" type="tns:EnvelopeSerializer" />
+ </s:sequence>
+ </s:complexType>
+ <s:complexType name="EnvelopeSerializer">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="Bcc" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Cc" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Date" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="From" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="InReplyTo" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="MessageId" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="ReplyTo" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Sender" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="Subject" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="To" type="s:string" />
+ </s:sequence>
+ </s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="AuthenticateSoapIn">
@@ -153,6 +193,12 @@
<wsdl:message name="GetFolderMessageCountsSoapOut">
<wsdl:part name="parameters" element="tns:GetFolderMessageCountsResponse" />
</wsdl:message>
+ <wsdl:message name="GetAllMessageEnvelopesSoapIn">
+ <wsdl:part name="parameters" element="tns:GetAllMessageEnvelopes" />
+ </wsdl:message>
+ <wsdl:message name="GetAllMessageEnvelopesSoapOut">
+ <wsdl:part name="parameters" element="tns:GetAllMessageEnvelopesResponse" />
+ </wsdl:message>
<wsdl:portType name="RemoteAccessServiceSoap">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateSoapIn" />
@@ -178,6 +224,10 @@
<wsdl:input message="tns:GetFolderMessageCountsSoapIn" />
<wsdl:output message="tns:GetFolderMessageCountsSoapOut" />
</wsdl:operation>
+ <wsdl:operation name="GetAllMessageEnvelopes">
+ <wsdl:input message="tns:GetAllMessageEnvelopesSoapIn" />
+ <wsdl:output message="tns:GetAllMessageEnvelopesSoapOut" />
+ </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RemoteAccessServiceSoap" type="tns:RemoteAccessServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -235,6 +285,15 @@
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetAllMessageEnvelopes">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetAllMessageEnvelopes" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RemoteAccessServiceSoap12" type="tns:RemoteAccessServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -292,6 +351,15 @@
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetAllMessageEnvelopes">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetAllMessageEnvelopes" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:service name="RemoteAccessService">
<wsdl:port name="RemoteAccessServiceSoap" binding="tns:RemoteAccessServiceSoap">
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx 2007-01-21 06:14:55 UTC (rev 122)
@@ -0,0 +1,41 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MailList.ascx.cs" Inherits="Controls_Mail_MailList" %>
+<asp:GridView
+ SkinID="MailList"
+ AutoGenerateColumns="false"
+ ID="MailListGridView"
+ runat="server"
+ HeaderStyle-CssClass="MailListHeader"
+ RowStyle-CssClass="MailListRow"
+ AlternatingRowStyle-CssClass="MailListAlternatingRow"
+ SelectedRowStyle-CssClass="MailListSelectedItem"
+ CssClass="MailList"
+ Width="100%"
+ DataSourceID="MailListDataSource">
+
+ <Columns>
+ <asp:TemplateField HeaderText="From">
+ <ItemTemplate><%# Eval("Value.From") %></ItemTemplate>
+ </asp:TemplateField>
+ <asp:TemplateField HeaderText="Subject">
+ <ItemTemplate><%# Eval("Value.Subject") %></ItemTemplate>
+ </asp:TemplateField>
+ <asp:TemplateField HeaderText="Date">
+ <ItemTemplate><%# Eval("Value.Date") %></ItemTemplate>
+ </asp:TemplateField>
+ </Columns>
+
+ <EmptyDataTemplate>
+ This folder does not contain any messages.
+ </EmptyDataTemplate>
+ <RowStyle CssClass="MailListRow" />
+ <SelectedRowStyle CssClass="MailListSelectedItem" />
+ <HeaderStyle CssClass="MailListHeader" />
+ <AlternatingRowStyle CssClass="MailListAlternatingRow" />
+</asp:GridView>
+
+<asp:ObjectDataSource ID="MailListDataSource" runat="server" SelectMethod="GetMessageEnvelopes" TypeName="NMail.WebAcess.MailListDataSource" >
+ <SelectParameters>
+ <asp:SessionParameter DefaultValue="0" Name="folderId" SessionField="SelectedFolderId"
+ Type="Int32" />
+ </SelectParameters>
+</asp:ObjectDataSource>
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/MailList.ascx.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -0,0 +1,93 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+public partial class Controls_Mail_MailList : System.Web.UI.UserControl, IWebPart
+{
+ protected void Page_Load(object sender, EventArgs e) {}
+
+ #region IWebPart Members
+
+ private string catalogIconImageUrl;
+
+ public string CatalogIconImageUrl
+ {
+ get
+ {
+ return this.catalogIconImageUrl;
+ }
+ set
+ {
+ this.catalogIconImageUrl = value;
+ }
+ }
+
+ private string description = "Displays the list of messages in a folder.";
+
+ public string Description
+ {
+ get
+ {
+ return this.description;
+ }
+ set
+ {
+ this.description = value;
+ }
+ }
+
+ public string Subtitle
+ {
+ get { return null; }
+ }
+
+ private string title = "Mail List";
+
+ public string Title
+ {
+ get
+ {
+ return this.title;
+ }
+ set
+ {
+ this.title = value;
+ }
+ }
+
+ private string titleIconImageUrl;
+
+ public string TitleIconImageUrl
+ {
+ get
+ {
+ return this.titleIconImageUrl;
+ }
+ set
+ {
+ this.titleIconImageUrl = value;
+ }
+ }
+
+ private string titleUrl;
+
+ public string TitleUrl
+ {
+ get
+ {
+ return this.titleUrl;
+ }
+ set
+ {
+ this.titleUrl = value;
+ }
+ }
+ #endregion
+}
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-01-21 06:14:55 UTC (rev 122)
@@ -2,22 +2,20 @@
<%@ Register Assembly="MenuPilot" Namespace="MenuPilot.Web.Ui" TagPrefix="mp" %>
-<asp:Repeater ID="FolderRepeater" runat="server" DataSourceID="SubscribedFolderDataSource">
+<asp:Repeater
+ ID="FolderRepeater"
+ runat="server"
+ OnItemCommand="FolderRepeater_OnItemCommand"
+ DataSourceID="SubscribedFolderDataSource">
+
<ItemTemplate>
- <mp:MenuPilotHyperlink
+ <asp:LinkButton
Text='<%# GetFolderString(Container.DataItem) %>'
- ID="MenuPilotHyperlink"
- HintIcon="~/Images/action.gif"
- NavigateUrl="dff"
- runat="server">
-
- <mp:MenuItem NavigateUrl="someurl" Text="cccc" Title="sfdv" />
- </mp:MenuPilotHyperlink>
-
-
-
+ CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FolderId") %>'
+ CommandName="SelectedFolderChanged"
+ runat="server"
+ ID="LinkButton" />
<br />
- <!-- <mp:MenuPilotLabel Text= -->
</ItemTemplate>
</asp:Repeater>
Modified: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-21 06:14:55 UTC (rev 122)
@@ -44,4 +44,11 @@
return result.ToString();
}
-}
+
+ protected void FolderRepeater_OnItemCommand(object sender, CommandEventArgs args)
+ {
+ int folderId = int.Parse(args.CommandArgument as string);
+
+ Session["SelectedFolderId"] = folderId;
+ }
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-19 13:02:39 UTC (rev 121)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-21 06:14:55 UTC (rev 122)
@@ -1,5 +1,7 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
+<%@ Register Src="Controls/Mail/MailList.ascx" TagName="MailList" TagPrefix="uc3" %>
+
<%@ Register Src="Controls/Mail/SubscribedFolderList.ascx" TagName="SubscribedFolderList" TagPrefix="uc2" %>
<%@ Register Src="Controls/LinkButtonList.ascx" TagName="LinkButtonList" TagPrefix="uc1" %>
@@ -37,7 +39,10 @@
</tr>
<tr>
<td valign="top">
- <asp:WebPartZone ID="CenterZone" runat="server" LayoutOrientation="Horizontal">
+ <asp:WebPartZone ID="CenterZone" runat="server" LayoutOrientation="Horizontal" HeaderText=" ">
+ <ZoneTemplate>
+ <uc3:MailList ID="MailList1" runat="server" />
+ </ZoneTemplate>
</asp:WebPartZone>
</td>
</tr>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 13:14:09
|
Revision: 116
http://svn.sourceforge.net/nmailserver/?rev=116&view=rev
Author: tmyroadctfig
Date: 2007-01-19 04:49:27 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Removed SSH RFCs.
Removed Paths:
-------------
NMail/trunk/doc/RFC/SSH/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 13:02:38
|
Revision: 121
http://svn.sourceforge.net/nmailserver/?rev=121&view=rev
Author: tmyroadctfig
Date: 2007-01-19 05:02:39 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Added MenuPilot.dll to references.
Added Paths:
-----------
NMail/trunk/References/MenuPilot.dll
Added: NMail/trunk/References/MenuPilot.dll
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/References/MenuPilot.dll
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 13:01:54
|
Revision: 120
http://svn.sourceforge.net/nmailserver/?rev=120&view=rev
Author: tmyroadctfig
Date: 2007-01-19 05:01:52 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Further work on RemoteAccessService.
Modified Paths:
--------------
NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
Modified: NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs
===================================================================
--- NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-19 13:01:16 UTC (rev 119)
+++ NMail/trunk/NMail.RemoteAccessService/App_Code/RemoteAccessService.cs 2007-01-19 13:01:52 UTC (rev 120)
@@ -9,10 +9,14 @@
using NMail.Server;
using NMail.RemoteAccessService.Serializers.DataTypes.LocalStore;
+/// <summary>
+/// A web service that provides access to NMail.
+/// </summary>
[WebService(Namespace = "http://nmailserver.sf.net/RemoteAccessService/1.0")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class RemoteAccessService : System.Web.Services.WebService
{
+ #region Authenticate
/// <summary>
/// Authenticates the current user.
/// </summary>
@@ -24,7 +28,7 @@
[WebMethod]
public string Authenticate(string user, string password)
{
- // TODO: ensure secure
+ // TODO: ensure connection is secure
IAuthenticationToken token = ServiceState.remoteAdmin.NMailServer.AuthenticationProvider.Authenticate(user, password);
@@ -43,7 +47,9 @@
return string.Empty;
}
+ #endregion
+ #region GetNominalFolder
/// <summary>
/// Gets the user's nominal folder.
/// </summary>
@@ -61,13 +67,60 @@
throw new InvalidOperationException("Authentication token is not valid.");
}
+ #endregion
+ #region GetStoreFolder
+ /// <summary>
+ /// Gets a store folder.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="folderId">The folder Id to lookup.</param>
+ /// <returns>The store folder.</returns>
[WebMethod]
- public List<StoreFolderSerializer> GetSubscribedFolders(string authToken)
+ public StoreFolderSerializer GetStoreFolderByFolderId(string authToken, int folderId)
{
IAuthenticationToken token = ValidateAuthenticationToken(authToken);
if (token != null)
{
+ StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
+ return new StoreFolderSerializer(storeFolder);
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+
+ /// <summary>
+ /// Gets a store folder.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="folderName">The name of the folder to lookup.</param>
+ /// <returns>The store folder.</returns>
+ [WebMethod]
+ public StoreFolderSerializer GetStoreFolderByName(string authToken, string folderName)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderName);
+ return new StoreFolderSerializer(storeFolder);
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+ #endregion
+
+ #region GetSubscribedFolders
+ /// <summary>
+ /// Gets a list of subscribed folders for the user.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <returns>The list of folders.</returns>
+ [WebMethod]
+ public List<StoreFolderSerializer> GetAllSubscribedFolders(string authToken)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
List<StoreFolder> subscribed = new List<StoreFolder>(ServiceState.remoteAdmin.NMailServer.LocalStore.GetSubscribed(token, "*"));
List<StoreFolderSerializer> result = new List<StoreFolderSerializer>();
@@ -81,7 +134,86 @@
throw new InvalidOperationException("Authentication token is not valid.");
}
+ #endregion
+ #region GetFolderMessageCounts
+ /// <summary>
+ /// Gets the number of messages in each requested folder and then the number
+ /// of messages with each matching flag per folder.
+ /// </summary>
+ /// <param name="authToken">The authentication credentials.</param>
+ /// <param name="folderIds">The list of folder Ids to get message counts for.</param>
+ /// <param name="flags">The flags to look up message counts for.</param>
+ /// <returns>The list of counts for each folder Id.</returns>
+ [WebMethod]
+ public List<List<int>> GetFolderMessageCounts(string authToken, List<int> folderIds, int flags)
+ {
+ IAuthenticationToken token = ValidateAuthenticationToken(authToken);
+ if (token != null)
+ {
+ List<List<int>> result = new List<List<int>>();
+ StoreMessageFlags messageFlags = (StoreMessageFlags)flags;
+
+ // Process each folder
+ foreach (int folderId in folderIds)
+ {
+ List<int> currentList = new List<int>();
+ result.Add(currentList);
+
+ StoreFolder storeFolder = ServiceState.remoteAdmin.NMailServer.LocalStore.GetStoreFolder(token, folderId);
+
+ if (storeFolder != null)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCount(token, storeFolder));
+
+ if ((messageFlags & StoreMessageFlags.Answered) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Answered));
+ }
+
+ if ((messageFlags & StoreMessageFlags.Deleted) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Deleted));
+ }
+
+ if ((messageFlags & StoreMessageFlags.Draft) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Draft));
+ }
+
+ if ((messageFlags & StoreMessageFlags.Flagged) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Flagged));
+ }
+
+ if ((messageFlags & StoreMessageFlags.Recent) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Recent));
+ }
+
+ if ((messageFlags & StoreMessageFlags.Seen) != 0)
+ {
+ addMessageCount(currentList, ServiceState.remoteAdmin.NMailServer.LocalStore.GetMessageCountWithFlags(token, storeFolder, StoreMessageFlags.Seen));
+ }
+ }
+ else
+ {
+ // List will remain empty
+ }
+ }
+
+ return result;
+ }
+
+ throw new InvalidOperationException("Authentication token is not valid.");
+ }
+
+ private void addMessageCount(List<int> list, int? item)
+ {
+ list.Add(item.HasValue ? item.Value : -1);
+ }
+ #endregion
+
protected IAuthenticationToken ValidateAuthenticationToken(string authToken)
{
Guid key = new Guid(Convert.FromBase64String(authToken));
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 13:01:23
|
Revision: 119
http://svn.sourceforge.net/nmailserver/?rev=119&view=rev
Author: tmyroadctfig
Date: 2007-01-19 05:01:16 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Added missing namespace.
Modified Paths:
--------------
NMail/trunk/NMail.Server/NMailServer.cs
Modified: NMail/trunk/NMail.Server/NMailServer.cs
===================================================================
--- NMail/trunk/NMail.Server/NMailServer.cs 2007-01-19 12:59:46 UTC (rev 118)
+++ NMail/trunk/NMail.Server/NMailServer.cs 2007-01-19 13:01:16 UTC (rev 119)
@@ -26,6 +26,7 @@
using NMail.Configuration;
using NMail.DataTypes;
using NMail.DataTypes.LocalStore;
+using NMail.DataTypes.Service;
namespace NMail.Server {
/// <summary>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 12:59:49
|
Revision: 118
http://svn.sourceforge.net/nmailserver/?rev=118&view=rev
Author: tmyroadctfig
Date: 2007-01-19 04:59:46 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Got mail folder list working.
Modified Paths:
--------------
NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
NMail/trunk/NMail.WebAccess/Login.aspx
NMail/trunk/NMail.WebAccess/Mail.aspx
NMail/trunk/NMail.WebAccess/Web.config
Added Paths:
-----------
NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
NMail/trunk/NMail.WebAccess/Bin/MenuPilot.dll.refresh
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
NMail/trunk/NMail.WebAccess/Global.asax
NMail/trunk/NMail.WebAccess/Images/Tango/
NMail/trunk/NMail.WebAccess/Images/Tango/Folder.png
NMail/trunk/NMail.WebAccess/Images/Tango/FolderOpen.png
NMail/trunk/NMail.WebAccess/Images/Tango/License.txt
NMail/trunk/NMail.WebAccess/Images/action.gif
Removed Paths:
-------------
NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx
NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx.cs
Property Changed:
----------------
NMail/trunk/NMail.WebAccess/Bin/
NMail/trunk/NMail.WebAccess/Images/Skins/Default/
Added: NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/App_Code/SubscribedFolderDataSource.cs 2007-01-19 12:59:46 UTC (rev 118)
@@ -0,0 +1,79 @@
+
+using System;
+using System.Data;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.SessionState;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.DataTypes.LocalStore;
+using RemoteAccessService;
+
+namespace NMail.WebAccess
+{
+ public static class SubscribedFolderDataSource
+ {
+ public static List<StoreFolder> GetSubscribedFolders()
+ {
+ IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);
+ string authToken = (string)session["AuthToken"];
+ RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)session["RAS"];
+
+ StoreFolderSerializer[] serializedFolders = ras.GetAllSubscribedFolders(authToken);
+ List<StoreFolder> result = new List<StoreFolder>();
+ List<int> folderIds = new List<int>();
+
+ foreach (StoreFolderSerializer serializedFolder in serializedFolders)
+ {
+ result.Add(new StoreFolder(serializedFolder));
+ folderIds.Add(serializedFolder.FolderId);
+ }
+
+ int[][] folderMessageCounts = ras.GetFolderMessageCounts(authToken, folderIds.ToArray(), (int)StoreMessageFlags.Seen);
+
+ for (int i = 0; i < folderMessageCounts.Length; i++)
+ {
+ result[i].TotalMessages = folderMessageCounts[i][0];
+ result[i].SeenMessages = folderMessageCounts[i][1];
+ }
+
+ return result;
+ }
+ }
+
+ public class StoreFolder : NMail.DataTypes.LocalStore.StoreFolder
+ {
+ public StoreFolder(StoreFolderSerializer serializedFolder)
+ : base(serializedFolder.NameSpace, serializedFolder.Name, serializedFolder.FolderId, serializedFolder.ParentId, serializedFolder.HasChildren)
+ {}
+
+ private int totalMessages;
+
+ public int TotalMessages
+ {
+ get { return totalMessages; }
+ set { totalMessages = value; }
+ }
+
+ private int seenMessages;
+
+ public int SeenMessages
+ {
+ get { return seenMessages; }
+ set { seenMessages = value; }
+ }
+
+ /// <summary>
+ /// The number of unread messages in the folder.
+ /// </summary>
+ public int UnreadMessages
+ {
+ get { return (totalMessages - seenMessages); }
+ }
+ }
+}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css
===================================================================
--- NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/App_Themes/Default/Default.css 2007-01-19 12:59:46 UTC (rev 118)
@@ -28,4 +28,13 @@
vertical-align: middle;
padding-left: 0.5em;
padding-right: 0.5em;
+}
+
+.SubscribedFolder
+{
+}
+
+.SubscribedFolderUnread
+{
+ font-weight: bold;
}
\ No newline at end of file
Modified: NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl
===================================================================
--- NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/App_WebReferences/RemoteAccessService/RemoteAccessService.wsdl 2007-01-19 12:59:46 UTC (rev 118)
@@ -40,25 +40,81 @@
<s:element minOccurs="1" maxOccurs="1" name="ParentId" nillable="true" type="s:int" />
</s:sequence>
</s:complexType>
- <s:element name="GetSubscribedFolders">
+ <s:element name="GetStoreFolderByFolderId">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="1" maxOccurs="1" name="folderId" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
- <s:element name="GetSubscribedFoldersResponse">
+ <s:element name="GetStoreFolderByFolderIdResponse">
<s:complexType>
<s:sequence>
- <s:element minOccurs="0" maxOccurs="1" name="GetSubscribedFoldersResult" type="tns:ArrayOfStoreFolderSerializer" />
+ <s:element minOccurs="1" maxOccurs="1" name="StoreFolder" nillable="true" type="tns:StoreFolderSerializer" />
</s:sequence>
</s:complexType>
</s:element>
+ <s:element name="GetStoreFolderByName">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="folderName" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetStoreFolderByNameResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1" name="StoreFolder" nillable="true" type="tns:StoreFolderSerializer" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetAllSubscribedFolders">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:element name="GetAllSubscribedFoldersResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="GetAllSubscribedFoldersResult" type="tns:ArrayOfStoreFolderSerializer" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
<s:complexType name="ArrayOfStoreFolderSerializer">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="StoreFolderSerializer" nillable="true" type="tns:StoreFolderSerializer" />
</s:sequence>
</s:complexType>
+ <s:element name="GetFolderMessageCounts">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="authToken" type="s:string" />
+ <s:element minOccurs="0" maxOccurs="1" name="folderIds" type="tns:ArrayOfInt" />
+ <s:element minOccurs="1" maxOccurs="1" name="flags" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfInt">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="int" type="s:int" />
+ </s:sequence>
+ </s:complexType>
+ <s:element name="GetFolderMessageCountsResponse">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="1" name="GetFolderMessageCountsResult" type="tns:ArrayOfArrayOfInt" />
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:complexType name="ArrayOfArrayOfInt">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="ArrayOfInt" nillable="true" type="tns:ArrayOfInt" />
+ </s:sequence>
+ </s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="AuthenticateSoapIn">
@@ -73,12 +129,30 @@
<wsdl:message name="GetNominalFolderSoapOut">
<wsdl:part name="parameters" element="tns:GetNominalFolderResponse" />
</wsdl:message>
- <wsdl:message name="GetSubscribedFoldersSoapIn">
- <wsdl:part name="parameters" element="tns:GetSubscribedFolders" />
+ <wsdl:message name="GetStoreFolderByFolderIdSoapIn">
+ <wsdl:part name="parameters" element="tns:GetStoreFolderByFolderId" />
</wsdl:message>
- <wsdl:message name="GetSubscribedFoldersSoapOut">
- <wsdl:part name="parameters" element="tns:GetSubscribedFoldersResponse" />
+ <wsdl:message name="GetStoreFolderByFolderIdSoapOut">
+ <wsdl:part name="parameters" element="tns:GetStoreFolderByFolderIdResponse" />
</wsdl:message>
+ <wsdl:message name="GetStoreFolderByNameSoapIn">
+ <wsdl:part name="parameters" element="tns:GetStoreFolderByName" />
+ </wsdl:message>
+ <wsdl:message name="GetStoreFolderByNameSoapOut">
+ <wsdl:part name="parameters" element="tns:GetStoreFolderByNameResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetAllSubscribedFoldersSoapIn">
+ <wsdl:part name="parameters" element="tns:GetAllSubscribedFolders" />
+ </wsdl:message>
+ <wsdl:message name="GetAllSubscribedFoldersSoapOut">
+ <wsdl:part name="parameters" element="tns:GetAllSubscribedFoldersResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetFolderMessageCountsSoapIn">
+ <wsdl:part name="parameters" element="tns:GetFolderMessageCounts" />
+ </wsdl:message>
+ <wsdl:message name="GetFolderMessageCountsSoapOut">
+ <wsdl:part name="parameters" element="tns:GetFolderMessageCountsResponse" />
+ </wsdl:message>
<wsdl:portType name="RemoteAccessServiceSoap">
<wsdl:operation name="Authenticate">
<wsdl:input message="tns:AuthenticateSoapIn" />
@@ -88,10 +162,22 @@
<wsdl:input message="tns:GetNominalFolderSoapIn" />
<wsdl:output message="tns:GetNominalFolderSoapOut" />
</wsdl:operation>
- <wsdl:operation name="GetSubscribedFolders">
- <wsdl:input message="tns:GetSubscribedFoldersSoapIn" />
- <wsdl:output message="tns:GetSubscribedFoldersSoapOut" />
+ <wsdl:operation name="GetStoreFolderByFolderId">
+ <wsdl:input message="tns:GetStoreFolderByFolderIdSoapIn" />
+ <wsdl:output message="tns:GetStoreFolderByFolderIdSoapOut" />
</wsdl:operation>
+ <wsdl:operation name="GetStoreFolderByName">
+ <wsdl:input message="tns:GetStoreFolderByNameSoapIn" />
+ <wsdl:output message="tns:GetStoreFolderByNameSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetAllSubscribedFolders">
+ <wsdl:input message="tns:GetAllSubscribedFoldersSoapIn" />
+ <wsdl:output message="tns:GetAllSubscribedFoldersSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetFolderMessageCounts">
+ <wsdl:input message="tns:GetFolderMessageCountsSoapIn" />
+ <wsdl:output message="tns:GetFolderMessageCountsSoapOut" />
+ </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RemoteAccessServiceSoap" type="tns:RemoteAccessServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -113,8 +199,8 @@
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
- <wsdl:operation name="GetSubscribedFolders">
- <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetSubscribedFolders" style="document" />
+ <wsdl:operation name="GetStoreFolderByFolderId">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetStoreFolderByFolderId" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
@@ -122,6 +208,33 @@
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetStoreFolderByName">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetStoreFolderByName" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetAllSubscribedFolders">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetAllSubscribedFolders" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFolderMessageCounts">
+ <soap:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetFolderMessageCounts" style="document" />
+ <wsdl:input>
+ <soap:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RemoteAccessServiceSoap12" type="tns:RemoteAccessServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
@@ -143,8 +256,8 @@
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
- <wsdl:operation name="GetSubscribedFolders">
- <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetSubscribedFolders" style="document" />
+ <wsdl:operation name="GetStoreFolderByFolderId">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetStoreFolderByFolderId" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
@@ -152,6 +265,33 @@
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
+ <wsdl:operation name="GetStoreFolderByName">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetStoreFolderByName" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetAllSubscribedFolders">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetAllSubscribedFolders" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFolderMessageCounts">
+ <soap12:operation soapAction="http://nmailserver.sf.net/RemoteAccessService/1.0/GetFolderMessageCounts" style="document" />
+ <wsdl:input>
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
</wsdl:binding>
<wsdl:service name="RemoteAccessService">
<wsdl:port name="RemoteAccessServiceSoap" binding="tns:RemoteAccessServiceSoap">
Property changes on: NMail/trunk/NMail.WebAccess/Bin
___________________________________________________________________
Name: svn:ignore
- log4net.dll
NMail.dll
NMail.RemoteAccessService.Serializers.dll
NMail.RemoteAccessService.Serializers.pdb
NMail.LocalStore.dll
+ log4net.dll
NMail.dll
NMail.RemoteAccessService.Serializers.dll
NMail.RemoteAccessService.Serializers.pdb
NMail.LocalStore.dll
MenuPilot.dll
Added: NMail/trunk/NMail.WebAccess/Bin/MenuPilot.dll.refresh
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Bin/MenuPilot.dll.refresh
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx 2007-01-19 12:59:46 UTC (rev 118)
@@ -1,3 +0,0 @@
-<%@ Control Language="C#" AutoEventWireup="true" CodeFile="FolderTree.ascx.cs" Inherits="Controls_Mail_FolderTree" %>
-<asp:TreeView ID="FolderTreeView" runat="server">
-</asp:TreeView>
Deleted: NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx.cs 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/FolderTree.ascx.cs 2007-01-19 12:59:46 UTC (rev 118)
@@ -1,21 +0,0 @@
-using System;
-using System.Data;
-using System.Configuration;
-using System.Collections;
-using System.Web;
-using System.Web.Security;
-using System.Web.UI;
-using System.Web.UI.WebControls;
-using System.Web.UI.WebControls.WebParts;
-using System.Web.UI.HtmlControls;
-
-public partial class Controls_Mail_FolderTree : System.Web.UI.UserControl
-{
- protected void Page_Load(object sender, EventArgs e)
- {
- RemoteAccessService.RemoteAccessService ras = (RemoteAccessService.RemoteAccessService)Session["RAS"];
- string authToken = Session["AuthToken"];
-
- ras.Get
- }
-}
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx 2007-01-19 12:59:46 UTC (rev 118)
@@ -0,0 +1,28 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SubscribedFolderList.ascx.cs" Inherits="Controls_Mail_SubscribedFolderList" %>
+
+<%@ Register Assembly="MenuPilot" Namespace="MenuPilot.Web.Ui" TagPrefix="mp" %>
+
+<asp:Repeater ID="FolderRepeater" runat="server" DataSourceID="SubscribedFolderDataSource">
+ <ItemTemplate>
+ <mp:MenuPilotHyperlink
+ Text='<%# GetFolderString(Container.DataItem) %>'
+ ID="MenuPilotHyperlink"
+ HintIcon="~/Images/action.gif"
+ NavigateUrl="dff"
+ runat="server">
+
+ <mp:MenuItem NavigateUrl="someurl" Text="cccc" Title="sfdv" />
+ </mp:MenuPilotHyperlink>
+
+
+
+ <br />
+ <!-- <mp:MenuPilotLabel Text= -->
+ </ItemTemplate>
+</asp:Repeater>
+
+<asp:ObjectDataSource
+ ID="SubscribedFolderDataSource"
+ runat="server"
+ SelectMethod="GetSubscribedFolders"
+ TypeName="NMail.WebAccess.SubscribedFolderDataSource" />
\ No newline at end of file
Added: NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs
===================================================================
--- NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs (rev 0)
+++ NMail/trunk/NMail.WebAccess/Controls/Mail/SubscribedFolderList.ascx.cs 2007-01-19 12:59:46 UTC (rev 118)
@@ -0,0 +1,47 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Text;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+using NMail.WebAccess;
+
+public partial class Controls_Mail_SubscribedFolderList : System.Web.UI.UserControl
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ protected string GetFolderString(object o) {
+ StoreFolder f = (StoreFolder) o;
+ StringBuilder result = new StringBuilder();
+
+ result.Append("<span class='");
+
+ if (f.UnreadMessages > 0)
+ {
+ result.Append("SubscribedFolderUnread");
+ }
+ else
+ {
+ result.Append("SubscribedFolder");
+ }
+ result.Append("'>");
+
+ result.Append(f.FullFolderName);
+
+ if (f.UnreadMessages > 0) {
+ result.Append(string.Format(" ({0})", f.UnreadMessages));
+ result.Append("</span>");
+ }
+
+ return result.ToString();
+ }
+}
Added: NMail/trunk/NMail.WebAccess/Global.asax
===================================================================
--- NMail/trunk/NMail.WebAccess/Global.asax (rev 0)
+++ NMail/trunk/NMail.WebAccess/Global.asax 2007-01-19 12:59:46 UTC (rev 118)
@@ -0,0 +1,39 @@
+<%@ Application Language="C#" %>
+<%@ Import Namespace="System.Web.Configuration" %>
+
+<script runat="server">
+
+ void Application_Start(object sender, EventArgs e)
+ {
+ Configuration c = WebConfigurationManager.OpenWebConfiguration("/NMail.WebAccess");
+ NMail.Configuration.NMailConfigFile.Current = c;
+ }
+
+ void Application_End(object sender, EventArgs e)
+ {
+ // Code that runs on application shutdown
+
+ }
+
+ void Application_Error(object sender, EventArgs e)
+ {
+ // Code that runs when an unhandled error occurs
+
+ }
+
+ void Session_Start(object sender, EventArgs e)
+ {
+ // Code that runs when a new session is started
+
+ }
+
+ void Session_End(object sender, EventArgs e)
+ {
+ // Code that runs when a session ends.
+ // Note: The Session_End event is raised only when the sessionstate mode
+ // is set to InProc in the Web.config file. If session mode is set to StateServer
+ // or SQLServer, the event is not raised.
+
+ }
+
+</script>
Property changes on: NMail/trunk/NMail.WebAccess/Images/Skins/Default
___________________________________________________________________
Name: svn:ignore
+ Thumbs.db
Added: NMail/trunk/NMail.WebAccess/Images/Tango/Folder.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/Tango/Folder.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/Tango/FolderOpen.png
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/Tango/FolderOpen.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: NMail/trunk/NMail.WebAccess/Images/Tango/License.txt
===================================================================
--- NMail/trunk/NMail.WebAccess/Images/Tango/License.txt (rev 0)
+++ NMail/trunk/NMail.WebAccess/Images/Tango/License.txt 2007-01-19 12:59:46 UTC (rev 118)
@@ -0,0 +1,5 @@
+These icons are from the Tango Desktop Project and are licensed under the Creative Commons
+Attribution Share-Alike license.
+
+See http://tango.freedesktop.org and http://creativecommons.org/licenses/by-sa/2.5/ for more
+information.
\ No newline at end of file
Added: NMail/trunk/NMail.WebAccess/Images/action.gif
===================================================================
(Binary files differ)
Property changes on: NMail/trunk/NMail.WebAccess/Images/action.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: NMail/trunk/NMail.WebAccess/Login.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Login.aspx 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/Login.aspx 2007-01-19 12:59:46 UTC (rev 118)
@@ -14,7 +14,8 @@
<asp:LoginView ID="LoginView" runat="server">
<LoggedInTemplate>
You are currently logged in as
- <asp:LoginName ID="LoginName" runat="server" />.
+ <asp:LoginName ID="LoginName" runat="server" />.<br />
+ <asp:LoginStatus ID="LoginStatus" runat="server" />
</LoggedInTemplate>
<AnonymousTemplate>
<asp:Login ID="Login" runat="server" OnAuthenticate="Login_Authenticate" DestinationPageUrl="~/Default.aspx" TitleText="Log in to NMail web access">
Modified: NMail/trunk/NMail.WebAccess/Mail.aspx
===================================================================
--- NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/Mail.aspx 2007-01-19 12:59:46 UTC (rev 118)
@@ -1,6 +1,6 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Mail.aspx.cs" Inherits="Mail" %>
-<%@ Register Src="Controls/Mail/FolderTree.ascx" TagName="FolderTree" TagPrefix="uc2" %>
+<%@ Register Src="Controls/Mail/SubscribedFolderList.ascx" TagName="SubscribedFolderList" TagPrefix="uc2" %>
<%@ Register Src="Controls/LinkButtonList.ascx" TagName="LinkButtonList" TagPrefix="uc1" %>
@@ -30,7 +30,7 @@
<td rowspan="3" valign="top">
<asp:WebPartZone ID="RightZone" runat="server">
<ZoneTemplate>
- <uc2:FolderTree ID="FolderTree1" runat="server" />
+ <uc2:SubscribedFolderList ID="SubscribedFolderList" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
Modified: NMail/trunk/NMail.WebAccess/Web.config
===================================================================
--- NMail/trunk/NMail.WebAccess/Web.config 2007-01-19 12:51:44 UTC (rev 117)
+++ NMail/trunk/NMail.WebAccess/Web.config 2007-01-19 12:59:46 UTC (rev 118)
@@ -8,12 +8,24 @@
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
+ <configSections>
+ <section name="NMail" type="NMail.Configuration.NMailConfiguration, NMail" />
+ </configSections>
+
+ <NMail>
+ <NamedServices>
+ <NamedService Name="LocalStore" Type="NMail.LocalStore.LocalStore, NMail.LocalStore" />
+ </NamedServices>
+ </NMail>
+
<appSettings>
<add key="RemoteAccessService.RemoteAccessService" value="http://localhost:1288/NMail.RemoteAccessService/RemoteAccessService.asmx"/>
</appSettings>
+
<connectionStrings/>
<system.web>
<pages theme="Default"/>
+
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
@@ -21,14 +33,17 @@
during development.
-->
<compilation debug="true"/>
- <!--
- The <authentication> section enables configuration
- of the security authentication mode used by
- ASP.NET to identify an incoming user.
- -->
+
+ <!-- Setup the authentication for the web access. -->
<authentication mode="Forms">
- <forms loginUrl="Login.aspx" timeout="60" protection="All" slidingExpiration="true"/>
+ <forms loginUrl="Login.aspx" defaultUrl="Default.aspx" timeout="60" protection="All" slidingExpiration="true"/>
</authentication>
+
+ <!-- Deny any un-authenticated users. -->
+ <authorization>
+ <deny users="?" />
+ </authorization>
+
<webParts enableExport="true">
<personalization defaultProvider="XmlFileSharedPersonalizationProvider">
<providers>
@@ -36,6 +51,7 @@
</providers>
</personalization>
</webParts>
+
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
@@ -49,4 +65,23 @@
</customErrors>
-->
</system.web>
+
+ <!-- Allow access to the themes without authentication so the login page is nice. -->
+ <location path="App_Themes">
+ <system.web>
+ <authorization>
+ <allow users="*" />
+ </authorization>
+ </system.web>
+ </location>
+
+ <!-- Allow access to the images without authentication so the login page is nice. -->
+ <location path="Images">
+ <system.web>
+ <authorization>
+ <allow users="*" />
+ </authorization>
+ </system.web>
+ </location>
+
</configuration>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-19 12:51:46
|
Revision: 117
http://svn.sourceforge.net/nmailserver/?rev=117&view=rev
Author: tmyroadctfig
Date: 2007-01-19 04:51:44 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
Removed SSH references.
Modified Paths:
--------------
NMail/trunk/NMail.PostInstall/PostInstallForm.cs
Modified: NMail/trunk/NMail.PostInstall/PostInstallForm.cs
===================================================================
--- NMail/trunk/NMail.PostInstall/PostInstallForm.cs 2007-01-19 12:49:27 UTC (rev 116)
+++ NMail/trunk/NMail.PostInstall/PostInstallForm.cs 2007-01-19 12:51:44 UTC (rev 117)
@@ -45,9 +45,9 @@
}
private void DeleteSmtpServiceCounters() {
- if (PerformanceCounterCategory.Exists(SmtpService.SmtpService.PerfCounterCategory)) {
+ if (PerformanceCounterCategory.Exists(SmtpService.SmtpService.SmtpPerfCounterCategory)) {
// Remove any old performance counters if they are present
- PerformanceCounterCategory.Delete(SmtpService.SmtpService.PerfCounterCategory);
+ PerformanceCounterCategory.Delete(SmtpService.SmtpService.SmtpPerfCounterCategory);
}
}
@@ -63,7 +63,7 @@
// Create the category with all the counters
PerformanceCounterCategory.Create(
- SmtpService.SmtpService.PerfCounterCategory,
+ SmtpService.SmtpService.SmtpPerfCounterCategory,
"Performance counters for NMail's SMTP service.",
PerformanceCounterCategoryType.SingleInstance,
ccdc);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-11 12:37:30
|
Revision: 115
http://svn.sourceforge.net/nmailserver/?rev=115&view=rev
Author: tmyroadctfig
Date: 2007-01-11 04:37:29 -0800 (Thu, 11 Jan 2007)
Log Message:
-----------
Copy edits from Darton Williams (http://corp.expr.net).
Modified Paths:
--------------
NMail/trunk/doc/NMail Developer's Guide.doc
Modified: NMail/trunk/doc/NMail Developer's Guide.doc
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-10 10:19:39
|
Revision: 114
http://svn.sourceforge.net/nmailserver/?rev=114&view=rev
Author: tmyroadctfig
Date: 2007-01-10 02:19:39 -0800 (Wed, 10 Jan 2007)
Log Message:
-----------
Added missing base classes.
Added Paths:
-----------
NMail/trunk/NMail/DataTypes/Service/BaseService.cs
NMail/trunk/NMail/DataTypes/Service/BaseSession.cs
Added: NMail/trunk/NMail/DataTypes/Service/BaseService.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Service/BaseService.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Service/BaseService.cs 2007-01-10 10:19:39 UTC (rev 114)
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2004-2006 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+
+using log4net;
+
+using NMail.DataTypes;
+using NMail.Configuration;
+using NMail.Helper;
+
+namespace NMail.DataTypes.Service {
+ /// <summary>
+ /// Provides a base class for services.
+ /// </summary>
+ public abstract class BaseService<SessionType> : MarshalByRefObject, IService where SessionType : BaseSession {
+ /// <summary>
+ /// A list of sockets listening for new connections.
+ /// </summary>
+ private List<TcpListener> listenSockets;
+
+ /// <summary>
+ /// A list of threads processing current sessions.
+ /// </summary>
+ private List<Thread> sessionThreads;
+
+ /// <summary>
+ /// A flag indicating the server is shutting down or shutdown.
+ /// </summary>
+ private bool shutdown;
+
+ /// <summary>
+ /// The performance counter for tracking the number of received connections.
+ /// </summary>
+ private PerformanceCounter connectionsReceived;
+
+ /// <summary>
+ /// Creates a new instance of the SMTP service.
+ /// </summary>
+ public BaseService() {
+ this.listenSockets = new List<TcpListener>();
+ this.sessionThreads = new List<Thread>();
+ this.shutdown = true;
+
+ this.connectionsReceived = new PerformanceCounter(
+ PerfCounterCategory,
+ TotalConnectionsReceived,
+ false);
+ }
+
+ #region IService Members
+ public void Start() {
+ this.shutdown = false;
+
+ // Create a new thread to listen on each listen end point
+ foreach (IPEndPointElement endPointElement in this.ListenEndpoints) {
+ ThreadHelper th = new ThreadHelper(new WaitCallback(handleConnections),
+ endPointElement.ToEndPoint());
+
+ Thread listenThread = new Thread(new ThreadStart(th.CallDelegate));
+ listenThread.Start();
+ }
+
+ // Notify any listeners that the service has started
+ if (this.startedEvent != null) {
+ this.startedEvent(this, new EventArgs());
+ }
+ }
+
+ public void Init() { }
+
+ public abstract string Name { get; }
+
+ public abstract string Description { get; }
+
+ public IService ReloadConfiguration() {
+ return this;
+ }
+
+ public bool AllowsReloadConfiguration {
+ get {
+ return false;
+ }
+ }
+
+ public void Stop(bool runCurrentToCompletion) {
+ this.shutdown = true;
+
+ lock (this) {
+ // Kill each of the listening sockets
+ foreach (TcpListener listener in this.listenSockets) {
+ listener.Stop();
+ }
+ this.listenSockets.Clear();
+ }
+
+ if (runCurrentToCompletion) {
+ // wait for sessions threads to finish up
+ while (this.sessionThreads.Count > 0) {
+ Thread.Sleep(500);
+ }
+ } else {
+ lock (this) {
+ // non-graceful shutdown of smtp sessions
+ foreach (Thread thread in this.sessionThreads) {
+ thread.Abort();
+ }
+ this.sessionThreads.Clear();
+ }
+ }
+
+ // Notify any listeners that the service has stopped
+ if (this.stoppedEvent != null) {
+ this.stoppedEvent(this, new EventArgs());
+ }
+ }
+
+ public bool SupportsPause {
+ get {
+ return false;
+ }
+ }
+
+ public void Pause() {
+ throw new InvalidOperationException("Pause not supported.");
+ }
+
+ public void Continue() {
+ throw new InvalidOperationException("Pause not supported.");
+ }
+
+ public abstract Uri SupportUrl { get; }
+
+ public bool Running {
+ get {
+ return ((this.listenSockets.Count > 0) || (this.sessionThreads.Count > 0));
+ }
+ }
+
+ private event EventHandler startedEvent;
+
+ public event EventHandler Started {
+ add {
+ this.startedEvent += value;
+ }
+ remove {
+ this.startedEvent -= value;
+ }
+ }
+
+ private event EventHandler stoppedEvent;
+
+ public event EventHandler Stopped {
+ add {
+ this.stoppedEvent += value;
+ }
+ remove {
+ this.stoppedEvent -= value;
+ }
+ }
+ #endregion
+
+ public int ConnectionCount {
+ get {
+ return this.sessionThreads.Count;
+ }
+ }
+
+ /// <summary>
+ /// Handles incomming connections for an interface (IP address).
+ /// </summary>
+ /// <param name="o">The interface to listen for connections on.</param>
+ protected void handleConnections(object o) {
+ Thread.CurrentThread.Name = "HandleConnections:" + o.ToString();
+ TcpListener socket = null;
+
+ try {
+ IPEndPoint ep = (IPEndPoint) o;
+ if (Log.IsDebugEnabled) {
+ Log.Debug("Binding to IP endpoint: [" + ep + "]");
+ }
+ socket = new TcpListener(ep);
+ socket.Start();
+ lock (this) {
+ // Register this socket
+ this.listenSockets.Add(socket);
+ }
+
+ while (true) {
+ Socket client = socket.AcceptSocket();
+ this.connectionsReceived.Increment();
+
+ lock (this) {
+ if (this.ConnectionCount < this.MaximumConnections) {
+ // Create a new session and thread to handle this connection
+ SessionType session = CreateSession(client);
+ Thread sessionThread = new Thread(new ThreadStart(session.Process));
+ this.RegisterSession(sessionThread);
+ sessionThread.Start();
+ } else {
+ Log.Warn("Server too busy to accept connections.");
+ client.Send(Encoding.ASCII.GetBytes(BusyReply));
+ client.Close();
+ }
+ }
+ }
+ } catch (SocketException e) {
+ // Ignore interrupted exception during shutdown
+ if (!this.shutdown) {
+ Log.Warn(e.Message, e);
+ }
+
+ lock (this) {
+ // De-register this socket
+ this.listenSockets.Remove(socket);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Registers the session thread with the service so that it can be kill if
+ /// required.
+ /// </summary>
+ /// <param name="sessionThread">The session thread to register.</param>
+ public void RegisterSession(Thread sessionThread) {
+ lock (this) {
+ this.sessionThreads.Add(sessionThread);
+ }
+ }
+
+ /// <summary>
+ /// Deregisters the session thread with the service. The session thread will not
+ /// attempt to kill this thread in a shutdown.
+ /// </summary>
+ /// <param name="sessionThread">The session thread to deregister.</param>
+ public void DeregisterSession(Thread sessionThread) {
+ lock (this) {
+ this.sessionThreads.Remove(sessionThread);
+ }
+ }
+
+ /// <summary>
+ /// Creates a new session for the given client socket.
+ /// </summary>
+ /// <param name="client">The socket to use in the session.</param>
+ /// <returns>The session.</returns>
+ protected abstract SessionType CreateSession(Socket client);
+
+ /// <summary>
+ /// The log for this service.
+ /// </summary>
+ protected abstract ILog Log { get; }
+
+ /// <summary>
+ /// The maximum number of connections allowed.
+ /// </summary>
+ protected abstract int MaximumConnections { get; }
+
+ /// <summary>
+ /// The listen endpoints for this service.
+ /// </summary>
+ protected abstract IPEndPointsCollection ListenEndpoints { get; }
+
+ /// <summary>
+ /// The reply to send when the server is busy.
+ /// </summary>
+ protected abstract string BusyReply { get; }
+
+ /// <summary>
+ /// The category the SMTP service uses for its performance counters.
+ /// </summary>
+ public abstract string PerfCounterCategory { get; }
+
+ /// <summary>
+ /// The name of the performance counter that tracks the total number of
+ /// received connections.
+ /// </summary>
+ public const string TotalConnectionsReceived = "TotalConnectionsReceived";
+ }
+}
\ No newline at end of file
Added: NMail/trunk/NMail/DataTypes/Service/BaseSession.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Service/BaseSession.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Service/BaseSession.cs 2007-01-10 10:19:39 UTC (rev 114)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004-2006 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net.Sockets;
+using System.Text;
+
+namespace NMail.DataTypes.Service {
+ /// <summary>
+ /// The base class for a session.
+ /// </summary>
+ public abstract class BaseSession {
+
+ public BaseSession(Socket socket) {
+ this.socket = socket;
+ }
+
+ protected Socket socket;
+
+ /// <summary>
+ /// The socket to the client.
+ /// </summary>
+ protected Socket Socket {
+ get { return socket; }
+ }
+
+ /// <summary>
+ /// Processes the current session.
+ /// </summary>
+ public abstract void Process();
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tmy...@us...> - 2007-01-10 09:43:08
|
Revision: 113
http://svn.sourceforge.net/nmailserver/?rev=113&view=rev
Author: tmyroadctfig
Date: 2007-01-10 01:43:06 -0800 (Wed, 10 Jan 2007)
Log Message:
-----------
Added a base class for services and sessions.
Modified Paths:
--------------
NMail/trunk/NMail/Configuration/IServiceCollection.cs
NMail/trunk/NMail/Configuration/NamedServiceCollection.cs
NMail/trunk/NMail/DataTypes/ServiceStartInfo.cs
NMail/trunk/NMail/DataTypes/Spool/ISpoolFilterService.cs
NMail/trunk/NMail/DataTypes/Spool/ISpoolService.cs
NMail/trunk/NMail/NMail.csproj
NMail/trunk/NMail.ImapService/ImapService.cs
NMail/trunk/NMail.SmtpService/SmtpService.cs
NMail/trunk/NMail.SmtpService/SmtpSession.cs
NMail/trunk/NMail.SpoolFilter/SpoolFilter.cs
NMail/trunk/NMail.SpoolService/SpoolService.cs
Added Paths:
-----------
NMail/trunk/NMail/DataTypes/Service/IService.cs
Removed Paths:
-------------
NMail/trunk/NMail/DataTypes/IService.cs
Modified: NMail/trunk/NMail/Configuration/IServiceCollection.cs
===================================================================
--- NMail/trunk/NMail/Configuration/IServiceCollection.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/Configuration/IServiceCollection.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -23,6 +23,7 @@
using System.Text;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
namespace NMail.Configuration {
/// <summary>
Modified: NMail/trunk/NMail/Configuration/NamedServiceCollection.cs
===================================================================
--- NMail/trunk/NMail/Configuration/NamedServiceCollection.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/Configuration/NamedServiceCollection.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -61,7 +61,7 @@
/// </summary>
/// <param name="name">The name of the named service element to get or set.</param>
/// <returns>The named service element.</returns>
- public NamedServiceElement this[string name] {
+ public new NamedServiceElement this[string name] {
get {
return (NamedServiceElement) BaseGet(name);
}
Deleted: NMail/trunk/NMail/DataTypes/IService.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/IService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/DataTypes/IService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -1,121 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane and Daniel Frampton
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-
-namespace NMail.DataTypes {
- /// <summary>
- /// A service to be hosted by NMail. This includes but it not
- /// limited to SpoolService, POP3, SMTP and IMAP services.
- /// </summary>
- public interface IService {
- /// <summary>
- /// Initialise the service. All services are <b>Init</b>ialised before any services are <b>Start</b>ed.
- /// </summary>
- void Init();
-
- /// <summary>
- /// Start the service.
- /// </summary>
- /// <exception cref="System.InvalidOperationException">
- /// If Start() is called before Init().
- /// </exception>
- void Start();
-
- /// <summary>
- /// Stop the service. It should be possible to resume the service with a subsequent call to Init and Start.
- /// If you take too long (arbitrary) to Stop gracefully, then you may get an additional call to Stop
- /// immediately on another thread, you must be able to handle this.
- /// </summary>
- void Stop(bool runCurrentToCompletion);
-
- /// <summary>
- /// Returns true if this service supports pausing processing without performing a complete shutdown.
- /// </summary>
- bool SupportsPause {get;}
-
- /// <summary>
- /// Pauses the service from processing but doesn't require a complete shutdown. E.g. a service may stop
- /// accepting new connections or stop processing its work queue.
- /// </summary>
- /// <exception cref="System.InvalidOperationException">
- /// If this service doesn't support pausing.
- /// </exception>
- void Pause();
-
- /// <summary>
- /// Continues processing following a pause command.
- /// </summary>
- /// <exception cref="System.InvalidOperationException">
- /// If this service doesn't support pausing.
- /// </exception>
- void Continue();
-
- /// <summary>
- /// Reload the service configuration. This may recycle the service instance by stopping and discarding
- /// the current IService and returning a new one.
- /// </summary>
- /// <remarks>
- /// The service is <b>running</b> when this is called.
- /// </remarks>
- /// <exception cref="System.InvalidOperationException">
- /// If this service is not running when this is called.
- /// </exception>
- IService ReloadConfiguration();
-
- /// <summary>
- /// Does this service support reloading configuration parameters on the fly?
- /// </summary>
- bool AllowsReloadConfiguration {get;}
-
- /// <summary>
- /// Is the service currently running?
- /// </summary>
- bool Running {get;}
-
- /// <summary>
- /// The name of this service.
- /// </summary>
- string Name {get;}
-
- /// <summary>
- /// The description of this service.
- /// </summary>
- string Description {get;}
-
- /// <summary>
- /// A URL for details on this service.
- /// </summary>
- Uri SupportUrl {get;}
-
- /// <summary>
- /// The event triggered when the service has been started.
- /// </summary>
- /// <remarks>
- /// Running should return true when this event is recieved.
- /// </remarks>
- event EventHandler Started;
-
- /// <summary>
- /// The event triggered when the sevice has been stopped.
- /// </summary>
- /// <remarks>
- /// Running should return false when this event is recieved.
- /// </remarks>
- event EventHandler Stopped;
- }
-}
Copied: NMail/trunk/NMail/DataTypes/Service/IService.cs (from rev 110, NMail/trunk/NMail/DataTypes/IService.cs)
===================================================================
--- NMail/trunk/NMail/DataTypes/Service/IService.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Service/IService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+
+namespace NMail.DataTypes.Service {
+ /// <summary>
+ /// A service to be hosted by NMail. This includes but it not
+ /// limited to SpoolService, POP3, SMTP and IMAP services.
+ /// </summary>
+ public interface IService {
+ /// <summary>
+ /// Initialise the service. All services are <b>Init</b>ialised before any services are <b>Start</b>ed.
+ /// </summary>
+ void Init();
+
+ /// <summary>
+ /// Start the service.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If Start() is called before Init().
+ /// </exception>
+ void Start();
+
+ /// <summary>
+ /// Stop the service. It should be possible to resume the service with a subsequent call to Init and Start.
+ /// If you take too long (arbitrary) to Stop gracefully, then you may get an additional call to Stop
+ /// immediately on another thread, you must be able to handle this.
+ /// </summary>
+ void Stop(bool runCurrentToCompletion);
+
+ /// <summary>
+ /// Returns true if this service supports pausing processing without performing a complete shutdown.
+ /// </summary>
+ bool SupportsPause {get;}
+
+ /// <summary>
+ /// Pauses the service from processing but doesn't require a complete shutdown. E.g. a service may stop
+ /// accepting new connections or stop processing its work queue.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service doesn't support pausing.
+ /// </exception>
+ void Pause();
+
+ /// <summary>
+ /// Continues processing following a pause command.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service doesn't support pausing.
+ /// </exception>
+ void Continue();
+
+ /// <summary>
+ /// Reload the service configuration. This may recycle the service instance by stopping and discarding
+ /// the current IService and returning a new one.
+ /// </summary>
+ /// <remarks>
+ /// The service is <b>running</b> when this is called.
+ /// </remarks>
+ /// <exception cref="System.InvalidOperationException">
+ /// If this service is not running when this is called.
+ /// </exception>
+ IService ReloadConfiguration();
+
+ /// <summary>
+ /// Does this service support reloading configuration parameters on the fly?
+ /// </summary>
+ bool AllowsReloadConfiguration {get;}
+
+ /// <summary>
+ /// Is the service currently running?
+ /// </summary>
+ bool Running {get;}
+
+ /// <summary>
+ /// The name of this service.
+ /// </summary>
+ string Name {get;}
+
+ /// <summary>
+ /// The description of this service.
+ /// </summary>
+ string Description {get;}
+
+ /// <summary>
+ /// A URL for details on this service.
+ /// </summary>
+ Uri SupportUrl {get;}
+
+ /// <summary>
+ /// The event triggered when the service has been started.
+ /// </summary>
+ /// <remarks>
+ /// Running should return true when this event is recieved.
+ /// </remarks>
+ event EventHandler Started;
+
+ /// <summary>
+ /// The event triggered when the sevice has been stopped.
+ /// </summary>
+ /// <remarks>
+ /// Running should return false when this event is recieved.
+ /// </remarks>
+ event EventHandler Stopped;
+ }
+}
Modified: NMail/trunk/NMail/DataTypes/ServiceStartInfo.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/ServiceStartInfo.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/DataTypes/ServiceStartInfo.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -18,6 +18,8 @@
using System;
using System.Diagnostics;
+using NMail.DataTypes.Service;
+
namespace NMail.DataTypes {
/// <summary>
/// Specifies the details of a service to start.
Modified: NMail/trunk/NMail/DataTypes/Spool/ISpoolFilterService.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Spool/ISpoolFilterService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/DataTypes/Spool/ISpoolFilterService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -17,6 +17,8 @@
using System;
+using NMail.DataTypes.Service;
+
namespace NMail.DataTypes.Spool {
/// <summary>
/// The interface for a spool filter service.
Modified: NMail/trunk/NMail/DataTypes/Spool/ISpoolService.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Spool/ISpoolService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/DataTypes/Spool/ISpoolService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -19,6 +19,7 @@
using System.Collections.Generic;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
namespace NMail.DataTypes.Spool {
/// <summary>
Modified: NMail/trunk/NMail/NMail.csproj
===================================================================
--- NMail/trunk/NMail/NMail.csproj 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail/NMail.csproj 2007-01-10 09:43:06 UTC (rev 113)
@@ -130,6 +130,8 @@
<Compile Include="DataTypes\ACLs\StoreFolderAcl.cs" />
<Compile Include="DataTypes\ACLs\StoreFolderPrivilege.cs" />
<Compile Include="DataTypes\ACLs\UserGroupAdminPrivilege.cs" />
+ <Compile Include="DataTypes\Service\BaseService.cs" />
+ <Compile Include="DataTypes\Service\BaseSession.cs" />
<Compile Include="DataTypes\Envelope.cs" />
<Compile Include="DataTypes\IDnsClient.cs" />
<Compile Include="DataTypes\Imap\BodyStructure.cs" />
@@ -138,7 +140,6 @@
<Compile Include="DataTypes\Imap\FetchDataItem.cs" />
<Compile Include="DataTypes\Imap\FetchDataItemType.cs" />
<Compile Include="DataTypes\Imap\FetchDataList.cs" />
- <Compile Include="DataTypes\IService.cs" />
<Compile Include="DataTypes\ISmtpClient.cs" />
<Compile Include="DataTypes\ByteString.cs">
<SubType>Code</SubType>
@@ -208,6 +209,7 @@
<Compile Include="DataTypes\ServiceStartInfo.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="DataTypes\Service\IService.cs" />
<Compile Include="DataTypes\SimpleBodyPart.cs">
<SubType>Code</SubType>
</Compile>
Modified: NMail/trunk/NMail.ImapService/ImapService.cs
===================================================================
--- NMail/trunk/NMail.ImapService/ImapService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail.ImapService/ImapService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -26,6 +26,7 @@
using NMail;
using NMail.Configuration;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
using NMail.Helper;
using NMail.ImapService.Configuration;
Modified: NMail/trunk/NMail.SmtpService/SmtpService.cs
===================================================================
--- NMail/trunk/NMail.SmtpService/SmtpService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail.SmtpService/SmtpService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -26,6 +26,7 @@
using log4net;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
using NMail.Configuration;
using NMail.Helper;
using NMail.SmtpService.Configuration;
@@ -34,268 +35,69 @@
/// <summary>
/// Provides a SMTP server service for NMail.
/// </summary>
- public class SmtpService : MarshalByRefObject, IService {
+ public class SmtpService : BaseService<SmtpSession> {
/// <summary>
/// Logging support for this class.
/// </summary>
protected static readonly ILog log = LogManager.GetLogger(typeof(SmtpService));
/// <summary>
- /// A list of sockets listening for new connections.
- /// </summary>
- private ArrayList listenSockets;
-
- /// <summary>
- /// A list of threads processing current sessions.
- /// </summary>
- private ArrayList sessionThreads;
-
- /// <summary>
/// The configuration for this service.
/// </summary>
- private SmtpServiceConfiguration config;
-
- /// <summary>
- /// A flag indicating the server is shutting down or shutdown.
- /// </summary>
- private bool shutdown;
-
- /// <summary>
- /// The performance counter for tracking the number of received connections.
- /// </summary>
- private PerformanceCounter connectionsReceived;
-
- /// <summary>
- /// Creates a new instance of the SMTP service.
- /// </summary>
- public SmtpService() {
- this.config = SmtpServiceConfiguration.Current;
- this.listenSockets = new ArrayList();
- this.sessionThreads = new ArrayList();
- this.shutdown = true;
-
- this.connectionsReceived = new PerformanceCounter(
- PerfCounterCategory,
- TotalConnectionsReceived,
- false);
- }
-
- #region IService Members
- public void Start() {
- this.shutdown = false;
-
- // Create a new thread to listen on each listen end point
- foreach (IPEndPointElement endPointElement in this.config.ListenEndPoints) {
- ThreadHelper th = new ThreadHelper(new WaitCallback(handleConnections),
- endPointElement.ToEndPoint());
-
- Thread listenThread = new Thread(new ThreadStart(th.CallDelegate));
- listenThread.Start();
- }
-
- // Notify any listeners that the service has started
- if (this.startedEvent != null) {
- this.startedEvent(this, new EventArgs());
- }
- }
-
- public void Init() { }
-
- public string Name {
+ private SmtpServiceConfiguration config = SmtpServiceConfiguration.Current;
+
+ public override string Name {
get {
return "SMTP Server Service";
}
}
- public string Description {
+ public override string Description {
get {
return "Provides an SMTP server for remote clients to connect to.";
}
}
- public IService ReloadConfiguration() {
- return this;
- }
-
- public bool AllowsReloadConfiguration {
+ public override Uri SupportUrl {
get {
- return false;
- }
- }
-
- public void Stop(bool runCurrentToCompletion) {
- this.shutdown = true;
-
- lock (this) {
- // Kill each of the listening sockets
- foreach (object o in this.listenSockets) {
- ((TcpListener) o).Stop();
- }
- this.listenSockets = new ArrayList();
- }
-
- if (runCurrentToCompletion) {
- // wait for sessions threads to finish up
- while (this.sessionThreads.Count > 0) {
- Thread.Sleep(500);
- }
- } else {
- lock (this) {
- // non-graceful shutdown of smtp sessions
- foreach (object o in this.sessionThreads) {
- ((Thread) o).Abort();
- }
- }
- }
-
- // Notify any listeners that the service has stopped
- if (this.stoppedEvent != null) {
- this.stoppedEvent(this, new EventArgs());
- }
- }
-
- public bool SupportsPause {
- get {
- return false;
- }
- }
-
- public void Pause() {
- throw new InvalidOperationException("Pause not supported.");
- }
-
- public void Continue() {
- throw new InvalidOperationException("Pause not supported.");
- }
-
- public Uri SupportUrl {
- get {
return new Uri("http://nmailserver.sf.net/support/services/smtp");
}
}
-
- public bool Running {
- get {
- return ((this.listenSockets.Count > 0) || (this.sessionThreads.Count > 0));
- }
+
+ protected override SmtpSession CreateSession(Socket client) {
+ return new SmtpSession(this, client);
}
- private event EventHandler startedEvent;
-
- public event EventHandler Started {
- add {
- this.startedEvent += value;
- }
- remove {
- this.startedEvent -= value;
- }
+ protected override ILog Log {
+ get { return log; }
}
- private event EventHandler stoppedEvent;
-
- public event EventHandler Stopped {
- add {
- this.stoppedEvent += value;
- }
- remove {
- this.stoppedEvent -= value;
- }
+ protected override int MaximumConnections {
+ get { return config.MaximumConnections; }
}
- #endregion
- public int ConnectionCount {
- get {
- return this.sessionThreads.Count;
- }
+ protected override IPEndPointsCollection ListenEndpoints {
+ get { return config.ListenEndPoints; }
}
/// <summary>
- /// Handles incomming connections for an interface (IP address).
+ /// The reply to send when the server is busy.
/// </summary>
- /// <param name="o">The interface to listen for connections on.</param>
- protected void handleConnections(object o) {
- Thread.CurrentThread.Name = "HandleSmtp:" + o.ToString();
- TcpListener socket = null;
-
- try {
- IPEndPoint ep = (IPEndPoint) o;
- if (log.IsDebugEnabled) {
- log.Debug("Binding to IP endpoint: [" + ep + "]");
- }
- socket = new TcpListener(ep);
- socket.Start();
- lock (this) {
- // Register this socket
- this.listenSockets.Add(socket);
- }
-
- while (true) {
- Socket client = socket.AcceptSocket();
- this.connectionsReceived.Increment();
-
- lock (this) {
- if (this.ConnectionCount < this.config.MaximumConnections) {
- // Create a new session and thread to handle this connection
- SmtpSession session = new SmtpSession(this, client);
- Thread sessionThread = new Thread(new ThreadStart(session.Process));
- this.RegisterSession(sessionThread);
- sessionThread.Start();
- } else {
- log.Warn("Server too busy to accept SMTP connection.");
- client.Send(Encoding.ASCII.GetBytes(BusyReply));
- client.Close();
- }
- }
- }
- } catch (SocketException e) {
- // Ignore interrupted exception during shutdown
- if (!this.shutdown) {
- log.Warn(e.Message, e);
- }
-
- lock (this) {
- // De-register this socket
- this.listenSockets.Remove(socket);
- }
+ protected override string BusyReply {
+ get {
+ return "421 Error - Server busy, try again later.\r\n";
}
}
/// <summary>
- /// Registers the session thread with the service so that it can be kill if
- /// required.
+ /// The category the SMTP service uses for its performance counters.
/// </summary>
- /// <param name="sessionThread">The session thread to register.</param>
- internal void RegisterSession(Thread sessionThread) {
- lock (this) {
- this.sessionThreads.Add(sessionThread);
+ public override string PerfCounterCategory {
+ get {
+ return SmtpPerfCounterCategory;
}
}
- /// <summary>
- /// Deregisters the session thread with the service. The session thread will not
- /// attempt to kill this thread in a shutdown.
- /// </summary>
- /// <param name="sessionThread">The session thread to deregister.</param>
- internal void DeregisterSession(Thread sessionThread) {
- lock (this) {
- this.sessionThreads.Remove(sessionThread);
- }
- }
-
- /// <summary>
- /// The reply to send when the server is busy.
- /// </summary>
- const string BusyReply = "421 Error - Server busy, try again later.\r\n";
-
- /// <summary>
- /// The category the SMTP service uses for its performance counters.
- /// </summary>
- public const string PerfCounterCategory = "NMail.SmtpService";
-
- /// <summary>
- /// The name of the performance counter that tracks the total number of
- /// received connections.
- /// </summary>
- public const string TotalConnectionsReceived = "TotalConnectionsReceived";
+ public const string SmtpPerfCounterCategory = "NMail.SmtpService";
}
}
\ No newline at end of file
Modified: NMail/trunk/NMail.SmtpService/SmtpSession.cs
===================================================================
--- NMail/trunk/NMail.SmtpService/SmtpSession.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail.SmtpService/SmtpSession.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -24,6 +24,7 @@
using log4net;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
using NMail.IO;
using NMail.SmtpService.Configuration;
using NMail.SmtpService.State;
@@ -32,7 +33,7 @@
/// <summary>
/// Handles SMTP sessions for connecting clients.
/// </summary>
- public class SmtpSession {
+ public class SmtpSession : BaseSession {
#region Attributes
/// <summary>
/// Logging support for this class.
@@ -90,14 +91,8 @@
private AbstractSmtpState currentState;
/// <summary>
- /// The socket to the client.
+ /// The service that owns this session.
/// </summary>
- private Socket socket;
-
- /// <summary>
- /// A reference back to the service for registering/deregistering this
- /// session.
- /// </summary>
private SmtpService smtpService;
#endregion
@@ -106,10 +101,9 @@
/// </summary>
/// <param name="smtpService">The service that the session belongs to.</param>
/// <param name="socket">The socket to the client.</param>
- public SmtpSession(SmtpService smtpService, Socket socket) {
+ public SmtpSession(SmtpService smtpService, Socket socket) : base(socket) {
this.config = SmtpServiceConfiguration.Current;
this.smtpService = smtpService;
- this.socket = socket;
this.badCommandCount = 0;
this.badRecipientCount = 0;
}
@@ -117,7 +111,7 @@
/// <summary>
/// Processes the current session.
/// </summary>
- public void Process() {
+ public override void Process() {
// create the connection
this.connection = new SmtpServiceConnection(SmtpSession.log);
Modified: NMail/trunk/NMail.SpoolFilter/SpoolFilter.cs
===================================================================
--- NMail/trunk/NMail.SpoolFilter/SpoolFilter.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail.SpoolFilter/SpoolFilter.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -23,6 +23,7 @@
using NMail.Configuration;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
using NMail.DataTypes.Spool;
using NMail.Threading;
using NMail.SpoolFilter.Configuration;
Modified: NMail/trunk/NMail.SpoolService/SpoolService.cs
===================================================================
--- NMail/trunk/NMail.SpoolService/SpoolService.cs 2007-01-10 09:10:39 UTC (rev 112)
+++ NMail/trunk/NMail.SpoolService/SpoolService.cs 2007-01-10 09:43:06 UTC (rev 113)
@@ -22,6 +22,7 @@
using log4net;
using NMail.DataTypes;
+using NMail.DataTypes.Service;
using NMail.DataTypes.Spool;
using NMail.Threading;
using NMail.Configuration;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|