nmailserver-commits Mailing List for NMail (Page 10)
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...> - 2006-07-11 12:26:00
|
Revision: 58 Author: tmyroadctfig Date: 2006-07-11 05:25:54 -0700 (Tue, 11 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=58&view=rev Log Message: ----------- Added directories to ignore list. Property Changed: ---------------- NMail/branches/luke-dev/NMail.SetupWizard/ Property changes on: NMail/branches/luke-dev/NMail.SetupWizard ___________________________________________________________________ Name: svn:ignore + bin obj This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-07-11 12:25:10
|
Revision: 57 Author: tmyroadctfig Date: 2006-07-11 05:24:16 -0700 (Tue, 11 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=57&view=rev Log Message: ----------- Converted webpages to use a standard theme. Added the start of a configuration wizard. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Thumbs.db NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap NMail/branches/luke-dev/NMail.Administration.Web/web.config NMail/branches/luke-dev/NMail.Server.Console/NMail.config NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs NMail/branches/luke-dev/NMail.sln Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/ NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/ NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/Default.skin NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/StyleSheet.css NMail/branches/luke-dev/NMail.SetupWizard/ NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.cs NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.resx NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.cs NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.resx NMail/branches/luke-dev/NMail.SetupWizard/DnsConfigPanel.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/DnsConfigPanel.cs NMail/branches/luke-dev/NMail.SetupWizard/DnsConfigPanel.resx NMail/branches/luke-dev/NMail.SetupWizard/NMail.SetupWizard.csproj NMail/branches/luke-dev/NMail.SetupWizard/Program.cs NMail/branches/luke-dev/NMail.SetupWizard/Properties/ NMail/branches/luke-dev/NMail.SetupWizard/Properties/AssemblyInfo.cs NMail/branches/luke-dev/NMail.SetupWizard/Properties/Resources.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/Properties/Resources.resx NMail/branches/luke-dev/NMail.SetupWizard/Properties/Settings.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/Properties/Settings.settings NMail/branches/luke-dev/NMail.SetupWizard/SmtpSubSysConfigPanel.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/SmtpSubSysConfigPanel.cs NMail/branches/luke-dev/NMail.SetupWizard/SmtpSubSysConfigPanel.resx NMail/branches/luke-dev/NMail.SetupWizard/WelcomePanel.Designer.cs NMail/branches/luke-dev/NMail.SetupWizard/WelcomePanel.cs NMail/branches/luke-dev/NMail.SetupWizard/WelcomePanel.resx Removed Paths: ------------- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css Modified: NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -25,6 +25,7 @@ /// <summary> /// The envelope for a message in the spool. /// </summary> + [Serializable] public class SpoolEnvelope : Envelope { /// <summary> /// Creates a new spool envelope. Modified: NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -6,6 +6,7 @@ /// <summary> /// Holds the details of a message recipient that is waiting delivery. /// </summary> + [Serializable] public class SpoolRecipient { /// <summary> /// Creates a new spool recipient. Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/Default.skin =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/Default.skin (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/Default.skin 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,25 @@ +<asp:SiteMapPath runat="server" Font-Size="smaller" /> + +<asp:LoginStatus runat="server" Font-Size="smaller" /> + +<asp:DetailsView runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> +</asp:DetailsView> + +<asp:GridView runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> +</asp:GridView> \ No newline at end of file Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/StyleSheet.css (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Themes/Default/StyleSheet.css 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,69 @@ +body +{ + font-family: Sans-Serif; +} + +.title +{ + font-size: 24pt; + color: white; + font-family: Tahoma, Arial, Sans-Serif; + padding: 0px; + margin: 0px; +} + +.title-nmail +{ + font-weight: bold; + font-style: italic; + font-size: 24pt; + color: white; + font-family: Tahoma, Arial, Sans-Serif; + padding: 0px; + margin: 0px; +} + +.title-box +{ + background-color: #123785; + border-top: black thin solid; + border-bottom: black thin solid; + padding: 0.5em; +} + +.status-box +{ + background-color: #666666; + border-bottom: black thin solid; + padding-left: 0.5em; + padding-right: 0.5em; +} + +.side-bar +{ + background-color: #999999; + border-right: black thin solid; + vertical-align: top; + height: 100%; + padding: 0.5em +} + +.header-style +{ + background-color: #507CD1; + font-weight: bold; + color: white; + padding: 4px; +} + +.row-style +{ + background-color: #EFF3FB; + padding: 4px; +} + +.alternating-row-style +{ + background-color: white; + padding: 4px; +} \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,21 +1,13 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateFolder.aspx.cs" Inherits="CreateFolder" Title="Untitled Page" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateFolder.aspx.cs" Inherits="CreateFolder" Title="NMail Administration - Create Folder" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> - <h2>Create New Folder</h2> - <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - ForeColor="#333333" GridLines="None" DefaultMode="Insert" DataSourceID="CreateFolderDataSource" AutoGenerateInsertButton="True" OnModeChanging="FolderDetailsView_ModeChanging"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <h1>Create New Folder</h1> + <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" + DefaultMode="Insert" DataSourceID="CreateFolderDataSource" AutoGenerateInsertButton="True" OnModeChanging="FolderDetailsView_ModeChanging"> <Fields> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" SortExpression="FolderName" /> </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> <asp:ObjectDataSource ID="CreateFolderDataSource" runat="server" InsertMethod="CreateFolder" OnInserted="FolderDataSource_Inserted" OnInserting="FolderDataSource_Inserting" Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,17 +1,9 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateMailDomain.aspx.cs" Inherits="CreateMailDomain" Title="Untitled Page" %> -<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateMailDomain.aspx.cs" Inherits="CreateMailDomain" Title="NMail Administration - Create Mail Domain" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" Visible="false" runat="server" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> - <h2>Create New Mail Domain</h2> - <asp:DetailsView ID="MailDomainDetailsView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateRows="False" DefaultMode="Insert" DataMember=" " OnItemInserting="MailDomainDetailsView_ItemInserting" OnModeChanging="MailDomainDetailsView_ModeChanging"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> + <h1>Create New Mail Domain</h1> + <asp:DetailsView ID="MailDomainDetailsView" runat="server" AutoGenerateRows="False" DefaultMode="Insert" DataMember=" " OnItemInserting="MailDomainDetailsView_ItemInserting" OnModeChanging="MailDomainDetailsView_ModeChanging"> <Fields> <asp:TemplateField HeaderText="Primary Host" SortExpression="PrimaryHost"> <InsertItemTemplate> Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,25 +1,17 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateUser.aspx.cs" Inherits="CreateUser" Title="Untitled Page" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateUser.aspx.cs" Inherits="CreateUser" Title="NMail Administration - Create User" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> - <h2>Create user</h2> - <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - DataSourceID="CreateUserDataSource" DefaultMode="Insert" ForeColor="#333333" - GridLines="None" OnModeChanging="UserDetailsView_ModeChanging"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <h1>Create user</h1> + <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" + DataSourceID="CreateUserDataSource" DefaultMode="Insert" + OnModeChanging="UserDetailsView_ModeChanging"> <Fields> <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Warn Quota" SortExpression="QuotaWarnLimit" /> <asp:BoundField DataField="QuotaHardLimit" HeaderText="Hard Quota" SortExpression="QuotaHardLimit" /> <asp:CommandField ShowInsertButton="True" /> </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> <asp:ObjectDataSource ID="CreateUserDataSource" runat="server" InsertMethod="CreateUesr" OnInserted="CreateUserDataSource_Inserted" OnInserting="CreateUserDataSource_Inserting" @@ -31,4 +23,3 @@ </InsertParameters> </asp:ObjectDataSource> </asp:Content> - Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,5 +1,5 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="FolderDetails.aspx.cs" Inherits="FolderDetails" Title="Untitled Page" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="FolderDetails.aspx.cs" Inherits="FolderDetails" Title="NMail Administration - Folder Details" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> @@ -13,13 +13,8 @@ </asp:Panel> <asp:Panel ID="MainPanel" runat="server"> - <h2>Folder Details</h2> - <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="FolderDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="FolderDetailsView_ItemDeleting"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <h1>Folder Details</h1> + <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" DataSourceID="FolderDataSource" OnItemDeleting="FolderDetailsView_ItemDeleting"> <Fields> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> <asp:HyperLinkField DataNavigateUrlFields="ParentId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" @@ -29,9 +24,6 @@ <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" ReadOnly="True" /> <asp:CommandField ShowDeleteButton="True" /> </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> <asp:ObjectDataSource ID="FolderDataSource" runat="server" SelectMethod="GetFolder" TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder"> @@ -46,10 +38,8 @@ </InsertParameters> </asp:ObjectDataSource> - <h2>Sub-folders</h2> - <asp:GridView ID="SubFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" - DataSourceID="FolderChildrenDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <h1>Sub-folders</h1> + <asp:GridView ID="SubFoldersGridView" runat="server" AutoGenerateColumns="False" DataSourceID="FolderChildrenDataSource"> <Columns> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> @@ -58,12 +48,6 @@ <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" HeaderText="Details" Text="details" /> </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> <EmptyDataTemplate> This folder has no subfolders.<br /> </EmptyDataTemplate> @@ -78,15 +62,8 @@ <asp:Image ID="AclStatusImage" runat="server" Visible="false" /> <asp:Label ID="AclStatusLabel" runat="server"></asp:Label> - <h2>Folder ACL</h2> - <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True" DataKeyNames="Identifier"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> + <h1>Folder ACL</h1> + <asp:GridView ID="AclGridView" runat="server" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True" DataKeyNames="Identifier"> <Columns> <asp:BoundField DataField="Identifier" HeaderText="Identifier" /> <asp:CheckBoxField DataField="CanInsert" HeaderText="Insert" /> @@ -132,15 +109,9 @@ <asp:LinkButton ID="ShowInsertAclEntryBtn" runat="server" OnClick="ShowInsertAclEntryBtn_Click">Insert ACL Entry</asp:LinkButton> <asp:Panel ID="InsertAclPanel" runat="server" Visible="false"> - <h3>Add an ACL Entry</h3> + <h2>Add an ACL Entry</h2> <asp:DetailsView ID="CreateAclDetailView" runat="server" AutoGenerateRows="False" - CellPadding="4" DataSourceID="FolderAclDataSource" DefaultMode="Insert" ForeColor="#333333" - GridLines="None" OnModeChanging="CreateAclDetailView_ModeChanging"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + DataSourceID="FolderAclDataSource" DefaultMode="Insert" OnModeChanging="CreateAclDetailView_ModeChanging"> <Fields> <asp:BoundField DataField="Identifier" HeaderText="Identifier" /> <asp:CheckBoxField DataField="CanInsert" HeaderText="Insert" /> @@ -154,11 +125,7 @@ <asp:CheckBoxField DataField="AdministrativePrivileges" HeaderText="Admin" /> <asp:CommandField ShowInsertButton="True" /> </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> </asp:Panel> </asp:Panel> </asp:Content> - Modified: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Thumbs.db =================================================================== (Binary files differ) Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,6 +1,6 @@ <%@ Page Language="C#" CodeFile="Login.aspx.cs" Inherits="NMail.Administration.Web.Login" MasterPageFile="~/MasterPage.master" Title="NMail Administration - Login" %> -<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:LoginView ID="LoginView" runat="server"> <LoggedInTemplate> You are currently logged in as Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -38,11 +38,11 @@ Session["RemoteAdministration"] = ra; Session["LocalStore"] = ra.NMailServer.LocalStore; - foreach (IService service in ra.NMailServer.Services) + foreach (ServiceStartInfo service in ra.NMailServer.Services) { - if (service is ISpoolService) + if (service.Service is ISpoolService) { - Session["Spool"] = service; + Session["Spool"] = service.Service; break; } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,5 +1,5 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="Mail Domain Details" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="NMail Administration - Mail Domain Details" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> @@ -13,17 +13,9 @@ </asp:Panel> <asp:Panel ID="MainPanel" runat="server"> - <h2>Mail Domain Details</h2> - <asp:DetailsView ID="MailDomainDetailsView" runat="server" CellPadding="4" DataSourceID="MailDomainDataSource" - ForeColor="#333333" GridLines="None" AutoGenerateRows="False" OnItemDeleting="MailDomainDetailsView_ItemDeleting"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> + <h1>Mail Domain Details</h1> + <asp:DetailsView ID="MailDomainDetailsView" runat="server" DataSourceID="MailDomainDataSource" + AutoGenerateRows="False" OnItemDeleting="MailDomainDetailsView_ItemDeleting"> <Fields> <asp:BoundField DataField="MailDomainId" HeaderText="Mail Domain Id" SortExpression="MailDomainId" /> <asp:BoundField DataField="PrimaryHost" HeaderText="Primary Host" SortExpression="PrimaryHost" /> @@ -46,4 +38,3 @@ </asp:ObjectDataSource> </asp:Panel> </asp:Content> - Modified: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-07-11 12:24:16 UTC (rev 57) @@ -25,61 +25,55 @@ <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> - <title>Untitled Page</title> - <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> + <title>NMail Administration</title> </head> <body> <form id="MainForm" runat="server"> <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> <tr> <td colspan="2" style="vertical-align: middle; width: 100%;"> - <div class="box"> - <h1> - <img src="Images/nmail-logo.png" style="vertical-align: middle" /> - NMail Web Administration</h1> - <table> - <tr> - <td style="width: 100%"> - <asp:SiteMapPath ID="SiteMapPath" runat="server" Font-Names="Verdana" Font-Size="0.8em" - PathSeparator=" : "> - <PathSeparatorStyle Font-Bold="True" ForeColor="#1C5E55" /> - <CurrentNodeStyle ForeColor="#333333" /> - <NodeStyle Font-Bold="True" ForeColor="#666666" /> - <RootNodeStyle Font-Bold="True" ForeColor="#1C5E55" /> - </asp:SiteMapPath> - </td> - <td> - <asp:LoginStatus ID="LoginStatus" runat="server" /> - </td> - </tr> - </table> + <div class="title-box"> + <p class="title"> + <span class="title-nmail"> + <img src="Images/nmail-logo-white.png" style="vertical-align: middle" />NMail + </span> + <br /> + Web Administration + </p> </div> + <table class="status-box"> + <tr> + <td style="width: 100%"> + <asp:SiteMapPath ID="SiteMapPath" runat="server" PathSeparator=" : "> + </asp:SiteMapPath> + </td> + <td> + <asp:LoginStatus ID="LoginStatus" runat="server" /> + </td> + </tr> + </table> </td> </tr> <tr> - <td style="vertical-align: top; height: 100%;"> - <div class="box"> - <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource" OnTreeNodeDataBound="TreeView_TreeNodeDataBound"> - </asp:TreeView> - <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> - </div> - + <td class="side-bar"> + <asp:TreeView ID="TreeView" runat="server" ShowLines="true" DataSourceID="SiteMapDataSource" OnTreeNodeDataBound="TreeView_TreeNodeDataBound"> + </asp:TreeView> + <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> + <uc1:TaskList ID="TaskList" runat="server" /> <asp:ContentPlaceHolder ID="SiteContentPlaceHolder" runat="server"> </asp:ContentPlaceHolder> </td> - <td style="width: 100%; vertical-align: top;"> - <div style="padding: 0.5em"> - <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> - </asp:ContentPlaceHolder> - </div> + <td style="width: 100%; vertical-align: top; padding: 0.5em"> + <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> + </asp:ContentPlaceHolder> </td> </tr> <tr> - <td style="text-align: center; top: 100%;"> - <a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> - <td> + <td class="side-bar"> + <a href="http://nmailserver.sourceforege.net">NMail homepage.</a> </td> + <td></td> </tr> </table> </form> Modified: NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,12 +1,10 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeFile="SetPasswordPanel.ascx.cs" Inherits="SetPasswordPanel" %> -<div class="box"> - <h3>Set a new password</h3> - <asp:Image ID="StatusImg" runat="server" /> - <asp:Label ID="StatusMessageLbl" runat="server" /> - - New Password: - <input id="PasswordBox" type="password" runat="server" /> - <br /> - <asp:Button ID="OkBtn" runat="Server" Text="Set" OnClick="OkBtn_Click" /> - <asp:Button ID="CancelBtn" runat="Server" Text="Cancel" OnClick="CancelBtn_Click" /> -</div> \ No newline at end of file +<h2>Set a new password</h2> +<asp:Image ID="StatusImg" runat="server" /> +<asp:Label ID="StatusMessageLbl" runat="server" /> + +New Password: +<input id="PasswordBox" type="password" runat="server" /> +<br /> +<asp:Button ID="OkBtn" runat="Server" Text="Set" OnClick="OkBtn_Click" /> +<asp:Button ID="CancelBtn" runat="Server" Text="Cancel" OnClick="CancelBtn_Click" /> \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,8 +1,52 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="SpoolDetails.aspx.cs" Inherits="SpoolDetails" Title="Untitled Page" %> -<asp:Content ID="Content1" ContentPlaceHolderID="SiteContentPlaceHolder" Runat="Server"> +<%@ Import Namespace="NMail.DataTypes.Spool" %> + +<asp:Content ID="SideContent" ContentPlaceHolderID="SiteContentPlaceHolder" Runat="Server"> </asp:Content> -<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SpoolMessagesDataSource"> + +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Repeater ID="MessageRepeater" runat="server" DataSourceID="SpoolMessagesDataSource"> + <ItemTemplate> + <table cellspacing="0"> + <tr> + <td class="header-style">Message Id</td> + <td class="row-style"><%# DataBinder.Eval(Container.DataItem, "MessageId") %></td> + </tr> + <tr> + <td class="header-style">Filtered</td> + <td class="alternating-row-style"><%# DataBinder.Eval(Container.DataItem, "Filtered") %></td> + </tr> + <tr> + <td class="header-style">Date</td> + <td class="row-style"><%# DataBinder.Eval(Container.DataItem, "Date") %></td> + </tr> + <tr> + <td class="header-style">Subject</td> + <td class="alternating-row-style"><%# DataBinder.Eval(Container.DataItem, "Subject") %></td> + </tr> + <tr> + <td class="header-style">Sender</td> + <td class="row-style"><%# DataBinder.Eval(Container.DataItem, "Sender") %></td> + </tr> + <tr> + <td class="header-style">Recipients</td> + <td class="alternating-row-style"> + <asp:GridView ID="RecipientGridView" + runat="server" + AutoGenerateColumns="false" + DataSource='<%# ((SpoolEnvelope) Container.DataItem).Recipients %>'> + + <Columns> + <asp:BoundField DataField="RecipientId" HeaderText="Recipient Id" ReadOnly="True" SortExpression="RecipientId" /> + <asp:BoundField DataField="Address" HeaderText="Email Address" SortExpression="Address" /> + <asp:BoundField DataField="NextDeliveryAttempt" HeaderText="Next Delivery Attempt" SortExpression="NextDeliveryAttempt" /> + <asp:BoundField DataField="DeliveryAttempts" HeaderText="Delivery Attempts" SortExpression="DeliveryAttempts" /> + </Columns> + </asp:GridView> + </td> + </tr> + </table> + </ItemTemplate> </asp:Repeater> <asp:ObjectDataSource ID="SpoolMessagesDataSource" runat="server" SelectMethod="GetSpooledMessages" TypeName="NMail.Administration.Web.SpooledMessageDataSource"></asp:ObjectDataSource> Deleted: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-07-11 12:24:16 UTC (rev 57) @@ -1,32 +0,0 @@ -body -{ - font-family: Sans-Serif; -} - -h1 -{ - font-size: large; -} - -h2 -{ - font-size: large; - margin-bottom: 0.5em; - margin-top: 1em; -} - -h3 -{ - font-style: italic; - font-size: medium; - margin-bottom: 0.25em; - margin-top: 0.5em; -} - -.box -{ - background-color: #eff3fb; - margin: 0.5em; - border: #507cd1 thin solid; - padding: 0.5em; -} \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,15 +1,13 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeFile="TaskList.ascx.cs" Inherits="TaskList" %> -<div class="box"> - <asp:Repeater ID="TaskRepeater" runat="server"> - <HeaderTemplate><ul></HeaderTemplate> - - <ItemTemplate> - <li> - <asp:Image runat="server" ID="Image" ImageUrl='<%# Eval("ImageUrl") %>' /> - <asp:LinkButton runat="server" ID="LinkButton" Text='<%# Eval("Text") %>' /> - </li> - </ItemTemplate> - - <FooterTemplate></ul></FooterTemplate> - </asp:Repeater> -</div> \ No newline at end of file +<asp:Repeater ID="TaskRepeater" runat="server"> + <HeaderTemplate><ul></HeaderTemplate> + + <ItemTemplate> + <li> + <asp:Image runat="server" ID="Image" ImageUrl='<%# Eval("ImageUrl") %>' /> + <asp:LinkButton runat="server" ID="LinkButton" Text='<%# Eval("Text") %>' /> + </li> + </ItemTemplate> + + <FooterTemplate></ul></FooterTemplate> +</asp:Repeater> \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,9 +1,9 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="Untitled Page" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="NMail Administration - User Details" %> <%@ Register Src="SetPasswordPanel.ascx" TagName="SetPasswordPanel" TagPrefix="uc1" %> <%@ Reference Control="~/TaskList.ascx" %> -<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> @@ -17,14 +17,8 @@ </asp:Panel> <asp:Panel ID="MainPanel" runat="server"> - <h2>User Details</h2> - <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <h1>User Details</h1> + <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" DataSourceID="UserDataSource"> <Fields> <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> <asp:BoundField DataField="UserId" HeaderText="User Id" ReadOnly="True" SortExpression="UserId" /> @@ -32,9 +26,6 @@ <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Quota Warn Limit" SortExpression="QuotaWarnLimit" /> <asp:BoundField DataField="QuotaHardLimit" HeaderText="Quota Hard Limit" SortExpression="QuotaHardLimit" /> </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> <asp:ObjectDataSource ID="UserDataSource" runat="server" SelectMethod="GetUser" TypeName="NMail.Administration.Web.UserDataSource" DeleteMethod="DeleteUser" OnDeleting="UserDataSource_Deleting" OnDeleted="UserDataSource_Deleted"> @@ -46,10 +37,8 @@ </DeleteParameters> </asp:ObjectDataSource> - <h2>User's Folders</h2> - <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" - DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <h1>User's Folders</h1> + <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" DataSourceID="UserFolderDataSource"> <Columns> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> @@ -58,12 +47,6 @@ <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" Text="details" /> </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> <EmptyDataTemplate> The user doesn't have any folders. </EmptyDataTemplate> @@ -76,7 +59,7 @@ </asp:ObjectDataSource> </asp:Panel> </asp:Content> -<asp:Content ID="SiteContent" runat="server" ContentPlaceHolderID="SiteContentPlaceHolder"> +<asp:Content ID="SideContent" runat="server" ContentPlaceHolderID="SiteContentPlaceHolder"> <uc1:SetPasswordPanel ID="SetPasswordPanel" runat="server" Visible="false" /> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,9 +1,7 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="Folders" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <h2>Folders</h2> - <asp:GridView ID="FoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" - DataSourceID="FoldersDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="NMail Administration - Folders" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h1>Folders</h1> + <asp:GridView ID="FoldersGridView" runat="server" AutoGenerateColumns="False" DataSourceID="FoldersDataSource"> <Columns> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> <asp:HyperLinkField DataNavigateUrlFields="ParentId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" @@ -13,12 +11,6 @@ <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" Text="details" /> </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> <EmptyDataTemplate> There are no folders currently in the system. </EmptyDataTemplate> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,23 +1,15 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Mail Domains" %> -<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <h2>Mail Domains</h2> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="NMail Administration -Mail Domains" %> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h1>Mail Domains</h1> <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource"> </asp:ObjectDataSource> - <asp:GridView ID="GridView1" runat="server" AllowSorting="True" - CellPadding="4" DataSourceID="MailDomainDataSource" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <asp:GridView ID="MailDomainsGridView" runat="server" AllowSorting="True" DataSourceID="MailDomainDataSource" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="MailDomainId" HeaderText="MailDomainId" SortExpression="MailDomainId" /> <asp:BoundField DataField="PrimaryHost" HeaderText="Primary Host" SortExpression="PrimaryHost" /> <asp:HyperLinkField DataNavigateUrlFields="MailDomainId" DataNavigateUrlFormatString="MailDomainDetails.aspx?MailDomainId={0}" Text="details" /> </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> <EmptyDataTemplate> There are no mail domains currently defined in the system. </EmptyDataTemplate> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-07-11 12:24:16 UTC (rev 57) @@ -1,4 +1,4 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Users" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="NMail Administration - Users" %> <%@ Reference Control="~/TaskList.ascx" %> <script runat="server"> @@ -20,10 +20,9 @@ } </script> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <h2>Users</h2> - <asp:GridView ID="GridView1" runat="server" DataSourceID="UserDataSource" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> +<asp:Content ID="MainContent" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h1>Users</h1> + <asp:GridView ID="UsersGridView" runat="server" DataSourceID="UserDataSource" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="UserId" HeaderText="UserId" SortExpression="UserId" /> <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> @@ -32,12 +31,6 @@ <asp:BoundField DataField="QuotaHardLimit" HeaderText="QuotaHardLimit" SortExpression="QuotaHardLimit" /> <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="UserDetails.aspx?UserId={0}" Text="details" /> </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> <EmptyDataTemplate> No users currently in the system. </EmptyDataTemplate> Modified: NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-07-11 12:24:16 UTC (rev 57) @@ -2,6 +2,7 @@ <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="Default.aspx" title="Home" description=""> <siteMapNode url="Login.aspx" title="Login" description="" /> + <siteMapNode url="SpoolDetails.aspx" title="Spool" description="" /> <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" imageUrl="~/Images/Tango/MailDomain.png" /> <siteMapNode url="ViewUsers.aspx" title="Users" description="" imageUrl="~/Images/Tango/User.png" /> <siteMapNode url="ViewFolders.aspx" title="Folders" description="" imageUrl="~/Images/Tango/OpenFolder.png" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/web.config =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/web.config 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Administration.Web/web.config 2006-07-11 12:24:16 UTC (rev 57) @@ -11,6 +11,8 @@ <appSettings/> <connectionStrings/> <system.web> + <pages theme="Default" /> + <!-- Set compilation debug="true" to insert debugging symbols into the compiled page. Because this Modified: NMail/branches/luke-dev/NMail.Server.Console/NMail.config =================================================================== --- NMail/branches/luke-dev/NMail.Server.Console/NMail.config 2006-07-05 12:05:15 UTC (rev 56) +++ NMail/branches/luke-dev/NMail.Server.Console/NMail.config 2006-07-11 12:24:16 UTC (rev 57) @@ -63,11 +63,14 @@ <NMail.ImapService VisibleHost="localhost" - CertificateFile="NMail.pfx"> - + CertificateFile="NMail.pfx" + AllowInsecureLogon="true"> + <!-- TODO: for testing only!!! remove above line!! --> + <!-- --> + <Listen> - <EndPoint Address="127.0.0.1" Port="143" /> - <!-- <EndPoint Address="0.0.0.0" Port="143" /> --> + <!-- <EndPoint Address="127.0.0.1" Port="143" /> --> + <EndPoint Address="0.0.0.0" Port="143" /> </Listen> <ListenSecure> <EndPoint Address="127.0.0.1" Port="993" /> Added: NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.Designer.cs =================================================================== --- NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.Designer.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.Designer.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,46 @@ +namespace NMail.SetupWizard { + partial class BaseForm { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.SuspendLayout(); + // + // BaseForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(457, 355); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.Name = "BaseForm"; + this.Text = "NMail Setup Wizard"; + this.ResumeLayout(false); + + } + + #endregion + + } +} + Added: NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.cs =================================================================== --- NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NMail.SetupWizard { + public partial class BaseForm : Form { + public BaseForm() { + InitializeComponent(); + } + + public void SetPanel(BasePanel panel) { + this.Controls.Clear(); + + panel.Dock = DockStyle.Fill; + this.Controls.Add(panel); + } + } +} \ No newline at end of file Added: NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.resx =================================================================== --- NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.resx (rev 0) +++ NMail/branches/luke-dev/NMail.SetupWizard/BaseForm.resx 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file Added: NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.Designer.cs =================================================================== --- NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.Designer.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SetupWizard/BasePanel.Designer.cs 2006-07-11 12:24:16 UTC (rev 57) @@ -0,0 +1,148 @@ +namespace NMail.SetupWizard { + partial class BasePanel { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.nextButton = new System.Windows.Forms.Button(); + this.titleLabel = new System.Windows.Forms.Label(); + this.mainPanel = new System.Windows.Forms.Panel(); + this.topPanel = new System.Windows.Forms.Panel(); + this.backButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.leftPanel = new System.Windows.Forms.Panel(); + this.buttonPanel = new System.Windows.Forms.Panel(); + this.topPanel.SuspendLayout(); + this.buttonPanel.SuspendLayout(); + this.SuspendLayout(); + // + // nextButton + // + this.nextButton.Location = new System.Drawing.P... [truncated message content] |
|
From: <tmy...@us...> - 2006-07-05 12:06:05
|
Revision: 56 Author: tmyroadctfig Date: 2006-07-05 05:05:15 -0700 (Wed, 05 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=56&view=rev Log Message: ----------- Fixed some small defects in the localstore. Work on spool administration. Added SASL plain authentication. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolData.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolService.cs NMail/branches/luke-dev/NMail/NMail.csproj NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx NMail/branches/luke-dev/NMail.ImapService/Command/AuthenticateCommand.cs NMail/branches/luke-dev/NMail.ImapService/Configuration/ImapServiceConfiguration.cs NMail/branches/luke-dev/NMail.ImapService/ImapSession.cs NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs NMail/branches/luke-dev/NMail.ImapService/State/ConnectedState.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.sql NMail/branches/luke-dev/NMail.SpoolService/SpoolService.cs Added Paths: ----------- NMail/branches/luke-dev/NMail/Authentication/SaslPlainAuthMsg.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/SpooledMessageDataSource.cs Added: NMail/branches/luke-dev/NMail/Authentication/SaslPlainAuthMsg.cs =================================================================== --- NMail/branches/luke-dev/NMail/Authentication/SaslPlainAuthMsg.cs (rev 0) +++ NMail/branches/luke-dev/NMail/Authentication/SaslPlainAuthMsg.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.Authentication { + public class SaslPlainAuthMsg { + + public SaslPlainAuthMsg(string base64Data) { + byte[] msgData = Convert.FromBase64String(base64Data); + string msgStr = Encoding.UTF8.GetString(msgData); + + string[] tokens = msgStr.Split("\000u".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + if (tokens.Length == 3) { + this.authorisationId = tokens[0]; + this.authenticationId = tokens[1]; + this.password = tokens[2]; + } else { + this.authorisationId = tokens[0]; + this.authenticationId = tokens[0]; + this.password = tokens[1]; + } + } + + private string authenticationId; + + public string AuthenticationId { + get { + return this.authenticationId; + } + } + + private string authorisationId; + + public string AuthorisationId { + get { + return this.authorisationId; + } + } + + private string password; + + public string Password { + get { + return this.password; + } + } + } +} Modified: NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -27,6 +27,9 @@ /// </summary> [Serializable] public class Envelope { + + protected Envelope() { } + /// <summary> /// Creates a new envelope from the message headers. /// </summary> Modified: NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolData.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolData.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolData.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -16,6 +16,7 @@ */ using System; +using System.Collections.Generic; using NMail.DataTypes; @@ -86,5 +87,11 @@ /// <param name="message">The message to set the status for.</param> /// <param name="filtered">True if filtered successfuly, false if failed.</param> void SetFilterStatus(SmtpMessage message, bool filtered); + + /// <summary> + /// Gets a list of message envelopes for messages currently in the spool. + /// </summary> + /// <returns>The list of envelopes.</returns> + List<SpoolEnvelope> GetSpooledEnvelopes(); } } Modified: NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolService.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolService.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolService.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -16,6 +16,7 @@ */ using System; +using System.Collections.Generic; using NMail.DataTypes; @@ -50,5 +51,11 @@ /// Notifies the spool service thread that a message is waiting in the spool. /// </summary> void NotifyServiceThread(); + + /// <summary> + /// Gets a list of message envelopes for messages currently in the spool. + /// </summary> + /// <returns>The list of envelopes.</returns> + List<SpoolEnvelope> GetSpooledEnvelopes(); } } Added: NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolEnvelope.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -0,0 +1,95 @@ +/* + * 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.DataTypes; + +namespace NMail.DataTypes.Spool { + /// <summary> + /// The envelope for a message in the spool. + /// </summary> + public class SpoolEnvelope : Envelope { + /// <summary> + /// Creates a new spool envelope. + /// </summary> + /// <param name="messageId">The Id of the message.</param> + /// <param name="filtered">True if the message has been filtered.</param> + /// <param name="recipients">The recipients for this message still awaiting delivery.</param> + public SpoolEnvelope(Envelope envelope, int messageId, bool filtered, SpoolRecipient[] recipients) { + + this.Bcc = envelope.Bcc; + this.Cc = envelope.Cc; + this.Date = envelope.Date; + this.From = envelope.From; + this.InReplyTo = envelope.InReplyTo; + this.ReplyTo = envelope.ReplyTo; + this.Sender = envelope.Sender; + this.Subject = envelope.Subject; + this.To = envelope.To; + + this.messageId = messageId; + this.filtered = filtered; + this.recipients = recipients; + } + + private int messageId; + + /// <summary> + /// The Id of this message in the spool. + /// </summary> + /// <remarks>This is different to the Id stored in the message headers.</remarks> + public int MessageId { + get { + return this.messageId; + } + set { + this.messageId = value; + } + } + + private bool filtered; + + /// <summary> + /// True if the message has been filtered. + /// </summary> + public bool Filtered { + get { + return this.filtered; + } + set { + this.filtered = value; + } + } + + private SpoolRecipient[] recipients; + + /// <summary> + /// The recipients of this message still awaiting delivery. + /// </summary> + public SpoolRecipient[] Recipients { + get { + return this.recipients; + } + set { + this.recipients = value; + } + } + } +} Added: NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/Spool/SpoolRecipient.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.DataTypes.Spool { + /// <summary> + /// Holds the details of a message recipient that is waiting delivery. + /// </summary> + public class SpoolRecipient { + /// <summary> + /// Creates a new spool recipient. + /// </summary> + /// <param name="address">The recipient's address.</param> + /// <param name="recipientId">The Id of the recipient in the spool.</param> + /// <param name="nextDelivery">The time for the next delivery attempt.</param> + /// <param name="deliveryAttempts">The number of delivery attempts.</param> + public SpoolRecipient(EmailAddress address, int recipientId, DateTime nextDelivery, int deliveryAttempts) { + this.address = address; + this.recipientId = recipientId; + this.nextDeliveryAttempt = nextDeliveryAttempt; + this.deliveryAttempts = deliveryAttempts; + } + + private int recipientId; + + /// <summary> + /// The Id of this recipient in the spool. + /// </summary> + public int RecipientId { + get { + return this.recipientId; + } + set { + this.recipientId = value; + } + } + + private EmailAddress address; + + /// <summary> + /// The recipient's address. + /// </summary> + public EmailAddress Address { + get { + return this.address; + } + set { + this.address = value; + } + } + + private DateTime nextDeliveryAttempt; + + /// <summary> + /// The time for the next delivery attempt. + /// </summary> + public DateTime NextDeliveryAttempt { + get { + return this.nextDeliveryAttempt; + } + set { + this.nextDeliveryAttempt = value; + } + } + + private int deliveryAttempts; + + /// <summary> + /// The number of delivery attempts for this message. + /// </summary> + public int DeliveryAttempts { + get { + return this.deliveryAttempts; + } + set { + this.deliveryAttempts = value; + } + } + } +} Modified: NMail/branches/luke-dev/NMail/NMail.csproj =================================================================== --- NMail/branches/luke-dev/NMail/NMail.csproj 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail/NMail.csproj 2006-07-05 12:05:15 UTC (rev 56) @@ -109,6 +109,7 @@ <Compile Include="Authentication\NullAuthentication.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Authentication\SaslPlainAuthMsg.cs" /> <Compile Include="Configuration\NamedServiceCollection.cs" /> <Compile Include="Configuration\IServiceCollection.cs" /> <Compile Include="Configuration\IPAddressCollection.cs" /> @@ -215,6 +216,8 @@ <Compile Include="DataTypes\Spool\ISpoolFilter.cs" /> <Compile Include="DataTypes\Spool\ISpoolFilterService.cs" /> <Compile Include="DataTypes\Spool\ISpoolService.cs" /> + <Compile Include="DataTypes\Spool\SpoolEnvelope.cs" /> + <Compile Include="DataTypes\Spool\SpoolRecipient.cs" /> <Compile Include="DataTypes\WildcardHost.cs" /> <Compile Include="Helper\ByteStringBuilder.cs"> <SubType>Code</SubType> Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/SpooledMessageDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/SpooledMessageDataSource.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/SpooledMessageDataSource.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -0,0 +1,27 @@ +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.SessionState; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +using NMail.DataTypes.Spool; + +namespace NMail.Administration.Web +{ + public static class SpooledMessageDataSource + { + public static List<SpoolEnvelope> GetSpooledMessages() + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + ISpoolService spool = (ISpoolService)session["Spool"]; + + return spool.GetSpooledEnvelopes(); + } + } +} \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -15,6 +15,8 @@ using System.Web.UI.HtmlControls; using NMail.Authentication; +using NMail.DataTypes; +using NMail.DataTypes.Spool; using NMail.IO; using NMail.Server; @@ -35,6 +37,15 @@ Session["AuthToken"] = authToken; Session["RemoteAdministration"] = ra; Session["LocalStore"] = ra.NMailServer.LocalStore; + + foreach (IService service in ra.NMailServer.Services) + { + if (service is ISpoolService) + { + Session["Spool"] = service; + break; + } + } } } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx 2006-07-05 12:05:15 UTC (rev 56) @@ -2,5 +2,9 @@ <asp:Content ID="Content1" ContentPlaceHolderID="SiteContentPlaceHolder" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SpoolMessagesDataSource"> + </asp:Repeater> + <asp:ObjectDataSource ID="SpoolMessagesDataSource" runat="server" SelectMethod="GetSpooledMessages" + TypeName="NMail.Administration.Web.SpooledMessageDataSource"></asp:ObjectDataSource> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -9,12 +9,13 @@ using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; +using NMail.DataTypes.Spool; + public partial class SpoolDetails : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { - NMail.Server.RemoteAdministration ra; - // ra.NMailServer.Services[0].Service + } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-07-05 12:05:15 UTC (rev 56) @@ -1,4 +1,5 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Users" %> +<%@ Reference Control="~/TaskList.ascx" %> <script runat="server"> protected override void OnLoad(EventArgs e) Modified: NMail/branches/luke-dev/NMail.ImapService/Command/AuthenticateCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/Command/AuthenticateCommand.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.ImapService/Command/AuthenticateCommand.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -41,6 +41,8 @@ } public enum ImapAuthenticationMethod { + Plain, + Ntlm } } Modified: NMail/branches/luke-dev/NMail.ImapService/Configuration/ImapServiceConfiguration.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/Configuration/ImapServiceConfiguration.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.ImapService/Configuration/ImapServiceConfiguration.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -125,5 +125,18 @@ this["Timeout"] = value; } } + + /// <summary> + /// True if unencrypted/protected logons are allowed. + /// </summary> + [ConfigurationProperty("AllowInsecureLogon", DefaultValue = false)] + public bool AllowInsecureLogon { + get { + return (bool) this["AllowInsecureLogon"]; + } + set { + this["AllowInsecureLogon"] = value; + } + } } } Modified: NMail/branches/luke-dev/NMail.ImapService/ImapSession.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/ImapSession.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.ImapService/ImapSession.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -29,7 +29,6 @@ using NMail.DataTypes.LocalStore; using NMail.ImapService.Command; using NMail.ImapService.Response; -using NMail.ImapService.Configuration; using NMail.ImapService.State; namespace NMail.ImapService { Modified: NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -136,12 +136,17 @@ #region Process Subscribe Command public override void ProcessCommand(SubscribeCommand cmd) { try { - // Attempt to subscribe to the folder StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); - LocalStore.Subscribe(Session.AuthenticationToken, folder); - - // Finish off the request - QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.Ok, "SUBSCRIBE Completed.")); + + if (folder != null) { + // Attempt to subscribe to the folder + LocalStore.Subscribe(Session.AuthenticationToken, folder); + QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.Ok, "SUBSCRIBE Completed.")); + + } else { + QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.No, "SUBSCRIBE No such folder.")); + } + } catch (Exception ex) { // Error occured subscribing folder QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.No, "SUBSCRIBE: " + ex.Message)); Modified: NMail/branches/luke-dev/NMail.ImapService/State/ConnectedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/ConnectedState.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.ImapService/State/ConnectedState.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -24,6 +24,7 @@ using NMail.Authentication; using NMail.Configuration; using NMail.ImapService.Command; +using NMail.ImapService.Configuration; using NMail.ImapService.Response; namespace NMail.ImapService.State { @@ -63,7 +64,7 @@ capabilities += " AUTH=NTLM"; } - if (this.Session.Connection.Encrypted) { + if (this.Session.Connection.Encrypted || ImapServiceConfiguration.Current.AllowInsecureLogon) { capabilities += " AUTH=PLAIN"; } else { capabilities += " STARTTLS LOGINDISABLED"; @@ -79,12 +80,13 @@ } else { QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.Ok, "Start Tls negotiation.")); + Session.Connection.Flush(); Session.Connection.StartTlsAsServer(); } } public override void ProcessCommand(LoginCommand cmd) { - if (Session.Connection.Encrypted) { + if (Session.Connection.Encrypted || ImapServiceConfiguration.Current.AllowInsecureLogon) { IAuthenticationProvider authProvider = (IAuthenticationProvider) NMailConfiguration.Current.AuthenticationProvider; IAuthenticationToken authToken = authProvider.Authenticate(cmd.Username, cmd.Password); @@ -101,9 +103,32 @@ } public override void ProcessCommand(AuthenticateCommand cmd) { - if (cmd.AuthenticationMethod == ImapAuthenticationMethod.Ntlm && this.supportsNtlmAuth) { + if (cmd.AuthenticationMethod == ImapAuthenticationMethod.Plain) { + // Ensure the connection is secure + if (!Session.Connection.Encrypted) { + QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.No, "AUTH: Need to STARTTLS first.")); + return; + } + + // Get the username and password QueueResponse(new ContinuationResponse(string.Empty)); + SaslPlainAuthMsg authMsg = new SaslPlainAuthMsg(Session.Connection.ReadLine()); + // Check the password against our copy + IAuthenticationProvider authProvider = (IAuthenticationProvider) NMailConfiguration.Current.AuthenticationProvider; + IAuthenticationToken authToken = authProvider.Authenticate(authMsg.AuthenticationId, authMsg.Password); + + if (authToken != null) { + this.Session.AuthenticationToken = authToken; + QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.Ok, "AUTHENTICATE Completed.")); + ChangeState(ImapState.Authenticated); + } else { + QueueResponse(new SimpleResponse(cmd.Tag, ResponseType.No, "AUTHENTICATE: Bad username or password.")); + } + + } else if (cmd.AuthenticationMethod == ImapAuthenticationMethod.Ntlm && this.supportsNtlmAuth) { + QueueResponse(new ContinuationResponse(string.Empty)); + // Read in client cababilities string type1MsgStr = Session.Connection.ReadLine(); Type1Message type1Msg = new Type1Message(Convert.FromBase64String(type1MsgStr)); Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-07-05 12:05:15 UTC (rev 56) @@ -3,9 +3,17 @@ USE NMailLocalStore; +DROP TABLE IF EXISTS SchemaVersion; +CREATE TABLE SchemaVersion ( + Version INT NOT NULL +); + +INSERT INTO SchemaVersion (Version) VALUES (1); + + -- ----------------------------------------------------------------------- -- --- Tables +-- Data Tables -- -- ----------------------------------------------------------------------- @@ -1107,7 +1115,7 @@ -- ----------------------------------------------------------------------- INSERT INTO Namespace (Name) VALUES ("LocalMail"); -INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Administrator", "changeme", 2); +INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Administrator", "changeme", 1); INSERT INTO Folder (NamespaceId, Name, OwnerUserId, NextMessageId) VALUES (1, "Administrator", 1, 1); INSERT INTO Folder (NamespaceId, Name, OwnerUserId, NextMessageId, ParentFolderId) VALUES (1, "Administrator.INBOX", 1, 1, 1); INSERT INTO FolderAcl (FolderId, Identifier, Allow, Privilege) VALUES (1, "Administrator", 1, 0xffffff); -- All privs Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -202,9 +202,10 @@ cmd.Parameters.Add("NameSpace", folder.NameSpace); cmd.Parameters["FolderId"].Direction = ParameterDirection.Output; - cmd.ExecuteNonQuery(); + int count = cmd.ExecuteNonQuery(); - int? folderId = (int?) cmd.Parameters["FolderId"].Value; + object o = cmd.Parameters["FolderId"].Value; + int? folderId = (o == DBNull.Value) ? null : (int?) o; if (folderId.HasValue) { return GetStoreFolder(folderId.Value); Modified: NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs =================================================================== --- NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -17,6 +17,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Net; using log4net; @@ -276,9 +277,10 @@ cmd.Transaction = transaction; // Insert the sender details and message data - cmd.CommandText = "INSERT INTO Message (MessageGuid, MessageData, ReportedHost, SourceAddress, Sender, InProgress, Filtered) VALUES (?MessageGuid, ?MessageData, ?ReportedHost, ?SourceAddress, ?Sender, ?InProgress, ?Filtered);"; + cmd.CommandText = "INSERT INTO Message (MessageGuid, MessageData, MessageEnvelope, ReportedHost, SourceAddress, Sender, InProgress, Filtered) VALUES (?MessageGuid, ?MessageData, ?MessageEnvelope, ?ReportedHost, ?SourceAddress, ?Sender, ?InProgress, ?Filtered);"; cmd.Parameters.Add("MessageGuid", message.MessageId.ToByteArray()); cmd.Parameters.Add("MessageData", SerializationHelper.Serialize(message.Data)); + cmd.Parameters.Add("MessageEnvelope", SerializationHelper.Serialize(message.Data.GetEnvelope())); cmd.Parameters.Add("ReportedHost", message.ReportedHost.ToString()); cmd.Parameters.Add("SourceAddress", message.SourceAddress.ToString()); cmd.Parameters.Add("Sender", message.Sender.ToString()); @@ -484,6 +486,65 @@ } } #endregion + + private SpoolRecipient[] getSpoolRecipients(int messageId) { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetSpoolRecipient"; + cmd.Parameters.Add("MessageId", messageId); + + List<SpoolRecipient> result = new List<SpoolRecipient>(); + MySqlDataReader reader = cmd.ExecuteReader(); + + // Get a list of recipients for the message + while (reader.Read()) { + int recipientId = (int) reader["MessageRecipientId"]; + EmailAddress address = new EmailAddress((string) reader["Recipient"]); + int deliveryAttempts = (int) reader["DeliveryAttempts"]; + DateTime nextAttempt = (DateTime) reader["NextDeliveryAttempt"]; + + result.Add(new SpoolRecipient(address, recipientId, nextAttempt, deliveryAttempts)); + } + + return result; + } + } + } + + /// <summary> + /// Gets a list of message envelopes for messages currently in the spool. + /// </summary> + /// <returns>The list of envelopes.</returns> + public List<SpoolEnvelope> GetSpooledEnvelopes() { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetSpooledEnvelopes"; + + List<SpoolEnvelope> result = new List<SpoolEnvelope>(); + MySqlDataReader reader = cmd.ExecuteReader(); + + // Get a list of messages + while (reader.Read()) { + int messageId = (int) reader["MessageId"]; + bool filtered = ((sbyte) reader["Filtered"] == 1) ? true : false; + Envelope envelope = (Envelope) SerializationHelper.Deserialize((byte[]) reader["MessageEnvelope"]); + + result.Add(new SpoolEnvelope(envelope, messageId, filtered, null)); + } + + reader.Close(); + + // Add the message's recipients + foreach (SpoolEnvelope spoolEnvelope in result) { + spoolEnvelope.Recipients = getSpoolRecipients(spoolEnvelope.MessageId); + } + + return result; + } + } + } #endregion } } Modified: NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.sql =================================================================== --- NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.sql 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.sql 2006-07-05 12:05:15 UTC (rev 56) @@ -2,6 +2,13 @@ CREATE DATABASE NMailSpool; USE NMailSpool; +DROP TABLE IF EXISTS SchemaVersion; +CREATE TABLE SchemaVersion ( + Version INT NOT NULL +); + +INSERT INTO SchemaVersion (Version) VALUES (1); + DROP TABLE IF EXISTS Message; CREATE TABLE Message ( MessageId INT AUTO_INCREMENT NOT NULL, @@ -12,19 +19,64 @@ InProgress BOOL NOT NULL, Filtered BOOL NOT NULL, MessageData LONGBLOB NOT NULL, + MessageEnvelope LONGBLOB NOT NULL, PRIMARY KEY(MessageId) -) TYPE=InnoDB; - -DROP TABLE IF EXISTS MessageRecipient; -CREATE TABLE MessageRecipient ( - MessageRecipientId INT AUTO_INCREMENT NOT NULL, - MessageId INT NOT NULL, - Host VARCHAR(255) NOT NULL, - Recipient VARCHAR(990) NOT NULL, - DeliveryAttempts INT NOT NULL, - NextDeliveryAttempt DATETIME NOT NULL, - InProgress BOOL NOT NULL, - PRIMARY KEY(MessageRecipientId), - INDEX MessageId (MessageId), - FOREIGN KEY (MessageId) REFERENCES Message (MessageId) -) TYPE=InnoDB; \ No newline at end of file +) TYPE=InnoDB; + +DROP TABLE IF EXISTS MessageRecipient; +CREATE TABLE MessageRecipient ( + MessageRecipientId INT AUTO_INCREMENT NOT NULL, + MessageId INT NOT NULL, + Host VARCHAR(255) NOT NULL, + Recipient VARCHAR(990) NOT NULL, + DeliveryAttempts INT NOT NULL, + NextDeliveryAttempt DATETIME NOT NULL, + InProgress BOOL NOT NULL, + PRIMARY KEY(MessageRecipientId), + INDEX MessageId (MessageId), + FOREIGN KEY (MessageId) REFERENCES Message (MessageId) +) TYPE=InnoDB; + + +delimiter // + + +-- ----------------------------------------------------------------------- +-- +-- Stored procedures +-- +-- ----------------------------------------------------------------------- + +DROP PROCEDURE IF EXISTS GetSpoolEnvelopes // +CREATE PROCEDURE GetSpoolEnvelopes +( +) +BEGIN + + SELECT + MessageId, Filtered, MessageEnvelope + FROM + Message; + +END +// + +DROP PROCEDURE IF EXISTS GetSpoolRecipients // +CREATE PROCEDURE GetSpoolRecipients +( + MessageId INT +) +BEGIN + + SELECT + mr.MessageRecipientId, + mr.Recipient, + mr.DeliveryAttempts, + mr.NextDeliveryAttempt + FROM + MessageRecipient mr + WHERE + mr.MessageId = MessageId; + +END +// \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.SpoolService/SpoolService.cs =================================================================== --- NMail/branches/luke-dev/NMail.SpoolService/SpoolService.cs 2006-07-01 15:34:40 UTC (rev 55) +++ NMail/branches/luke-dev/NMail.SpoolService/SpoolService.cs 2006-07-05 12:05:15 UTC (rev 56) @@ -16,6 +16,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using log4net; @@ -69,6 +70,14 @@ Monitor.PulseAll(this); Monitor.Exit(this); } + + /// <summary> + /// Gets a list of message envelopes for messages currently in the spool. + /// </summary> + /// <returns>The list of envelopes.</returns> + public List<SpoolEnvelope> GetSpooledEnvelopes() { + return this.data.GetSpooledEnvelopes(); + } #endregion #region IService Members This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-07-01 17:28:28
|
Revision: 55 Author: tmyroadctfig Date: 2006-07-01 08:34:40 -0700 (Sat, 01 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=55&view=rev Log Message: ----------- Moved classes into (hopefully) a better structure. Modified Paths: -------------- NMail/branches/luke-dev/NMail/Configuration/NMailConfiguration.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs NMail/branches/luke-dev/NMail/NMail.csproj NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/DeleteUserCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/ListFoldersCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/ListUserAddressesCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/ListUsersCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Context/LocalStoreContext.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx.cs NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.ImapService/Command/AppendCommand.cs NMail/branches/luke-dev/NMail.ImapService/Command/StoreCommand.cs NMail/branches/luke-dev/NMail.ImapService/ImapSession.cs NMail/branches/luke-dev/NMail.ImapService/Response/LSubResponse.cs NMail/branches/luke-dev/NMail.ImapService/Response/ListResponse.cs NMail/branches/luke-dev/NMail.ImapService/State/AbstractState.cs NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs NMail/branches/luke-dev/NMail.ImapService/State/ExamineState.cs NMail/branches/luke-dev/NMail.ImapService/State/SelectedState.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Copy.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Move.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressDate.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressKeyword.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressSender.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/OnWhiteList.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/OrdbBlackList.cs NMail/branches/luke-dev/NMail.Server/NMailServer.cs NMail/branches/luke-dev/NMail.SmtpService/SmtpService.cs NMail/branches/luke-dev/NMail.SpoolData.MySql/MySqlSpoolData.cs NMail/branches/luke-dev/NMail.SpoolFilter/Configuration/SpoolFilterConfiguration.cs NMail/branches/luke-dev/NMail.SpoolFilter/NoActionFilter.cs NMail/branches/luke-dev/NMail.SpoolFilter/SpoolFilter.cs NMail/branches/luke-dev/NMail.SpoolFilter.RegexAddressRewriter/RegexAddressRewriter.cs NMail/branches/luke-dev/NMail.SpoolService/SpoolService.cs Added Paths: ----------- NMail/branches/luke-dev/NMail/DataTypes/AbstractMessageRouter.cs NMail/branches/luke-dev/NMail/DataTypes/IDnsClient.cs NMail/branches/luke-dev/NMail/DataTypes/IService.cs NMail/branches/luke-dev/NMail/DataTypes/ISmtpClient.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStore.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreData.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreDeliveryAction.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreRecipientValidator.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreUserMap.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/LocalStoreDelivery.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/LocalStoreGroup.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/LocalStoreUser.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/StoreFolder.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStore/StoreMessageFlags.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolData.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolFilter.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolFilterService.cs NMail/branches/luke-dev/NMail/DataTypes/Spool/ISpoolService.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/Task.cs Removed Paths: ------------- NMail/branches/luke-dev/NMail/AbstractMessageRouter.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStoreDelivery.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStoreGroup.cs NMail/branches/luke-dev/NMail/DataTypes/LocalStoreUser.cs NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs NMail/branches/luke-dev/NMail/DataTypes/StoreMessageFlags.cs NMail/branches/luke-dev/NMail/IDnsClient.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail/ILocalStoreDeliveryAction.cs NMail/branches/luke-dev/NMail/ILocalStoreRecipientValidator.cs NMail/branches/luke-dev/NMail/ILocalStoreUserMap.cs NMail/branches/luke-dev/NMail/IService.cs NMail/branches/luke-dev/NMail/ISmtpClient.cs NMail/branches/luke-dev/NMail/ISpoolData.cs NMail/branches/luke-dev/NMail/ISpoolFilter.cs NMail/branches/luke-dev/NMail/ISpoolFilterService.cs NMail/branches/luke-dev/NMail/ISpoolService.cs NMail/branches/luke-dev/NMail/Interfaces/ Property Changed: ---------------- NMail/branches/luke-dev/NMail.PostInstall/ Deleted: NMail/branches/luke-dev/NMail/AbstractMessageRouter.cs =================================================================== --- NMail/branches/luke-dev/NMail/AbstractMessageRouter.cs 2006-07-01 09:39:32 UTC (rev 54) +++ NMail/branches/luke-dev/NMail/AbstractMessageRouter.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -1,101 +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; -using System.Collections; - -using NMail.Configuration; -using NMail.DataTypes; - -namespace NMail { - /// <summary> - /// Provides the basis for a message router. - /// </summary> - public abstract class AbstractMessageRouter { - /// <summary> - /// A delegate for validating a recipient. - /// </summary> - /// <param name="messageRecipient">The recipient to validate.</param> - /// <param name="result">The result of the validation.</param> - /// <returns> - /// True if validation should continue to the next step. False if this result - /// should be final. - /// </returns> - public delegate bool ValidateRecipientDelegate(out DeliveryResult result, SmtpMessageRecipient messageRecipient); - - /// <summary> - /// A event that occurs before built in message router validation. - /// </summary> - public event ValidateRecipientDelegate OnBeforeValidateRecipient; - - /// <summary> - /// A event that occurs after built in message router validation. - /// </summary> - public event ValidateRecipientDelegate OnAfterValidateRecipient; - - /// <summary> - /// Validate a specified recipient of the passed message. - /// </summary> - /// <param name="messageRecipient">The recipient to validate.</param> - /// <returns>The result of the request.</returns> - public DeliveryResult ValidateRecipient(SmtpMessageRecipient messageRecipient) { - - if (OnBeforeValidateRecipient != null) { - foreach(ValidateRecipientDelegate method in OnBeforeValidateRecipient.GetInvocationList()) { - DeliveryResult result; - - if (!method(out result, messageRecipient)) - return result; - } - } - - DeliveryResult internalResult = this.ValidateRecipientInternal(messageRecipient); - - if (OnAfterValidateRecipient != null) { - foreach(ValidateRecipientDelegate method in OnAfterValidateRecipient.GetInvocationList()) { - DeliveryResult result; - - if (!method(out result, messageRecipient)) - return result; - } - } - - return internalResult; - } - - /// <summary> - /// Validate a specified recipient of the passed message. - /// </summary> - /// <param name="messageRecipient">The recipient to validate.</param> - /// <returns>The result of the request.</returns> - abstract protected DeliveryResult ValidateRecipientInternal(SmtpMessageRecipient messageRecipient); - - /// <summary> - /// Spool a mail message. - /// </summary> - /// <param name="message">The message to be spooled.</param> - /// <returns>The result of the request.</returns> - abstract public DeliveryResult SpoolMessage(SmtpMessage message); - - /// <summary> - /// Deliver a group of messages, including both connecting to remote SMTP - /// servers and the local store. - /// </summary> - /// <param name="batch">The batch of messages to deliver</param> - abstract public void DeliverMessages(DeliveryBatch batch); - } -} Modified: NMail/branches/luke-dev/NMail/Configuration/NMailConfiguration.cs =================================================================== --- NMail/branches/luke-dev/NMail/Configuration/NMailConfiguration.cs 2006-07-01 09:39:32 UTC (rev 54) +++ NMail/branches/luke-dev/NMail/Configuration/NMailConfiguration.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -22,6 +22,8 @@ using NMail.Authentication; using NMail.DataTypes; +using NMail.DataTypes.LocalStore; +using NMail.DataTypes.Spool; using NMail.Helper; namespace NMail.Configuration { Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-07-01 09:39:32 UTC (rev 54) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -19,6 +19,8 @@ using System.Collections.Generic; using System.Text; +using NMail.DataTypes.LocalStore; + namespace NMail.DataTypes.ACLs { /// <summary> /// A list of access control entries for a folder. Copied: NMail/branches/luke-dev/NMail/DataTypes/AbstractMessageRouter.cs (from rev 49, NMail/branches/luke-dev/NMail/AbstractMessageRouter.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/AbstractMessageRouter.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/AbstractMessageRouter.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -0,0 +1,100 @@ +/* + * 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 NMail.Configuration; + +namespace NMail.DataTypes { + /// <summary> + /// Provides the basis for a message router. + /// </summary> + public abstract class AbstractMessageRouter { + /// <summary> + /// A delegate for validating a recipient. + /// </summary> + /// <param name="messageRecipient">The recipient to validate.</param> + /// <param name="result">The result of the validation.</param> + /// <returns> + /// True if validation should continue to the next step. False if this result + /// should be final. + /// </returns> + public delegate bool ValidateRecipientDelegate(out DeliveryResult result, SmtpMessageRecipient messageRecipient); + + /// <summary> + /// A event that occurs before built in message router validation. + /// </summary> + public event ValidateRecipientDelegate OnBeforeValidateRecipient; + + /// <summary> + /// A event that occurs after built in message router validation. + /// </summary> + public event ValidateRecipientDelegate OnAfterValidateRecipient; + + /// <summary> + /// Validate a specified recipient of the passed message. + /// </summary> + /// <param name="messageRecipient">The recipient to validate.</param> + /// <returns>The result of the request.</returns> + public DeliveryResult ValidateRecipient(SmtpMessageRecipient messageRecipient) { + + if (OnBeforeValidateRecipient != null) { + foreach(ValidateRecipientDelegate method in OnBeforeValidateRecipient.GetInvocationList()) { + DeliveryResult result; + + if (!method(out result, messageRecipient)) + return result; + } + } + + DeliveryResult internalResult = this.ValidateRecipientInternal(messageRecipient); + + if (OnAfterValidateRecipient != null) { + foreach(ValidateRecipientDelegate method in OnAfterValidateRecipient.GetInvocationList()) { + DeliveryResult result; + + if (!method(out result, messageRecipient)) + return result; + } + } + + return internalResult; + } + + /// <summary> + /// Validate a specified recipient of the passed message. + /// </summary> + /// <param name="messageRecipient">The recipient to validate.</param> + /// <returns>The result of the request.</returns> + abstract protected DeliveryResult ValidateRecipientInternal(SmtpMessageRecipient messageRecipient); + + /// <summary> + /// Spool a mail message. + /// </summary> + /// <param name="message">The message to be spooled.</param> + /// <returns>The result of the request.</returns> + abstract public DeliveryResult SpoolMessage(SmtpMessage message); + + /// <summary> + /// Deliver a group of messages, including both connecting to remote SMTP + /// servers and the local store. + /// </summary> + /// <param name="batch">The batch of messages to deliver</param> + abstract public void DeliverMessages(DeliveryBatch batch); + } +} Copied: NMail/branches/luke-dev/NMail/DataTypes/IDnsClient.cs (from rev 49, NMail/branches/luke-dev/NMail/IDnsClient.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/IDnsClient.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/IDnsClient.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -0,0 +1,57 @@ +/* + * 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.Net; + +namespace NMail.DataTypes { + /// <summary> + /// The interface for NMail to access Dns. + /// </summary> + public interface IDnsClient { + /// <summary> + /// One of the IP addresses listed against this domain matches the given address. + /// </summary> + /// <param name="domain">The domain to compare.</param> + /// <param name="address">The address to compare.</param> + /// <returns>True if the domain matches the address.</returns> + bool DomainMatchesAddress(Domain domain, IPAddress address); + + /// <summary> + /// Attempts to resolve the IP address to a domain name and returns a host + /// containing either the resolved domain name or the given IP address. + /// </summary> + /// <param name="address">The address to resolve.</param> + /// <returns>The resolved host.</returns> + Host ResolveHost(IPAddress address); + + /// <summary> + /// Returns an IP address for the given domain. + /// </summary> + /// <param name="domain">The domain to resolve.</param> + /// <returns>The resolved IP address.</returns> + IPAddress ResolveIPAddress(Domain domain); + + /// <summary> + /// Returns all valid MX records for the domain in order of preference. + /// </summary> + /// <remarks>Returns null when no MX records are found.</remarks> + /// <param name="domain">The domain to lookup the MX records for.</param> + /// <returns>The list of MX records or null.</returns> + Domain[] ResolveMXRecords(Domain domain); + } +} Copied: NMail/branches/luke-dev/NMail/DataTypes/IService.cs (from rev 49, NMail/branches/luke-dev/NMail/IService.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/IService.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/IService.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -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 { + /// <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/branches/luke-dev/NMail/DataTypes/ISmtpClient.cs (from rev 49, NMail/branches/luke-dev/NMail/ISmtpClient.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ISmtpClient.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/ISmtpClient.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -0,0 +1,43 @@ +/* + * 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> + /// The interface for a SMTP client. + /// </summary> + public interface ISmtpClient { + /// <summary> + /// Connects to an MX for the given destination. + /// </summary> + /// <param name="destination">The destination address.</param> + void Connect(Host destination); + + /// <summary> + /// Sends the given message. + /// </summary> + /// <param name="message">The message to send.</param> + /// <returns>The result of the delivery attempt.</returns> + SmtpDeliveryResult Send(SmtpMessage message); + + /// <summary> + /// Closes the connection to the remote server. + /// </summary> + void Close(); + } +} Copied: NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStore.cs (from rev 49, NMail/branches/luke-dev/NMail/ILocalStore.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStore.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStore.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -0,0 +1,773 @@ +/* + * 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 NMail.Authentication; +using NMail.DataTypes; +using NMail.DataTypes.ACLs; + +namespace NMail.DataTypes.LocalStore { + /// <summary> + /// The interface for a local store. + /// </summary> + public interface ILocalStore { + /// <summary> + /// Gets the folder delimiter for this local store. + /// </summary> + char FolderDelimiter {get;} + + #region Delivery Validation + /// <summary> + /// Checks if this local store handles mail for the given hostname. + /// </summary> + /// <param name="host">The host to check.</param> + /// <returns>True if the store accepts mail for the hostname.</returns> + bool WithinLocalStore(Host host); + + /// <summary> + /// Checks if the given recipient is valid for this local store. + /// </summary> + /// <param name="recipient">The recipient to check.</param> + /// <returns>The result of the validation.</returns> + DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient); + #endregion + + #region Message Delivery + /// <summary> + /// Delivers the given recipient and message into the local store. + /// </summary> + /// <param name="recipient">The recipient and message to deliver.</param> + /// <returns>The result of the delivery attempt.</returns> + RecipientDeliveryResult DeliverMessage(SmtpMessageRecipient recipient); + + /// <summary> + /// Delivers the message into the given folder. + /// </summary> + /// <param name="authToken">The authentication credentials of the current user.</param> + /// <param name="message">The message to deliver.</param> + /// <param name="folder">The folder to deliver the message into.</param> + /// <returns>The result of the delivery.</returns> + DeliveryResult DeliverMessage(IAuthenticationToken authToken, Message message, StoreFolder folder); + #endregion + + #region Folder Retrieval and Manipulation + /// <summary> + /// Gets the nominal folder for the given authentication creditials. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The nominal store folder or null if the authentication token is invalid.</returns> + StoreFolder GetNominalStoreFolder(IAuthenticationToken authToken); + + /// <summary> + /// Gets the store folder from the given folder name. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to lookup.</param> + /// <returns>The store folder or null if the folder name is invalid.</returns> + StoreFolder GetStoreFolder(IAuthenticationToken authToken, string folder); + + /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invalid.</returns> + StoreFolder GetStoreFolder(IAuthenticationToken authToken, int folderId); + + /// <summary> + /// Creates a new folder. + /// </summary> + /// <remarks> + /// It is a requirement of the local store that each new folder get an incremented Id number. + /// </remarks> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="newFolder">The folder to create.</param> + /// <returns>The result of the create attempt.</returns> + LocalStoreFolderResult CreateFolder(IAuthenticationToken authToken, string newFolder); + + /// <summary> + /// Deletes an existing folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to delete.</param> + /// <returns>The result of the delete attempt.</returns> + LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, int folderId); + + /// <summary> + /// Renames an existing folder in the local store. + /// </summary> + /// <remarks> + /// It is a requirement of the local store that a renamed folder and all its sub-folder get a new + /// folder Id. Futher, this new Id number cannot have been used previously. + /// + /// Thus any existing folder Ids for the rename folder or its childed obtained before the rename may + /// be altered and must be reaquired from the local store. + /// </remarks> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to rename.</param> + /// <param name="newFolder">The new folder name.</param> + /// <returns>The result of the rename attempt.</returns> + LocalStoreFolderResult RenameFolder(IAuthenticationToken authToken, StoreFolder folder, string newFolder); + + /// <summary> + /// Gets a list of folders that match the query folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="queryFolder">The query folder used in the lookup.</param> + /// <returns>The list of matching folders.</returns> + StoreFolder[] GetMatching(IAuthenticationToken authToken, string queryFolder); + + /// <summary> + /// Gets a list of child folders for the given parent folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="parent">The parent to get the children from.</param> + /// <returns>The list of folders.</returns> + StoreFolder[] GetChildren(IAuthenticationToken authToken, StoreFolder parent); + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of folders.</returns> + StoreFolder[] GetFolders(IAuthenticationToken authToken); + #endregion + + #region Folder Subscription + /// <summary> + /// Gets a list of subscribed folders that match the query folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="queryFolder">The query folder used in the lookup.</param> + /// <returns>The list of folders.</returns> + StoreFolder[] GetSubscribed(IAuthenticationToken authToken, string queryFolder); + + /// <summary> + /// Subscribes to a folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to subscribe to.</param> + /// <returns>The result of the subscribe attempt.</returns> + LocalStoreFolderResult Subscribe(IAuthenticationToken authToken, StoreFolder folder); + + /// <summary> + /// Un-subscribes from a folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to unsubscribe from.</param> + void UnSubscribe(IAuthenticationToken authToken, StoreFolder folder); + #endregion + + #region Message Id and Offset + /// <summary> + /// Gets the Id for the next message in the folder after the current Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="currentId">The Id to start looking from.</param> + /// <param name="folder"></param> + /// <returns>The Id of the next existing message or 0 if there is none.</returns> + int GetNextMessageId(IAuthenticationToken authToken, int currentId, StoreFolder folder); + + /// <summary> + /// Gets the Id for the next message to be added into the folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The next message Id or 0 if insufficient privileges.</returns> + int GetNextMessageId(IAuthenticationToken authToken, StoreFolder folder); + + /// <summary> + /// Gets the message Id (UID) corresponding to the given message offset. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageOffset">The offset of the message to lookup.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The message Id or 0 if there is no such message.</returns> + int GetMessageId(IAuthenticationToken authToken, int messageOffset, StoreFolder folder); + + /// <summary> + /// Gets the message offset corresponding the to given message Id (UID). + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageId">The Id of the message to lookup.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The message offset or 0 if there is no such message.</returns> + int GetMessageOffset(IAuthenticationToken authToken, int messageId, StoreFolder folder); + #endregion + + #region Message Flags + /// <summary> + /// Gets the message flags for a message. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageId">The Id of the message to get the flags for.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The message flags or null if invalid folder or privileges.</returns> + StoreMessageFlags? GetMessageFlags(IAuthenticationToken authToken, int messageId, StoreFolder folder); + + /// <summary> + /// Sets the message flags for a message. + /// </summary> + /// <remarks>This will replace any existing flags on the message.</remarks> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageId">The Id of the message to set the flags for.</param> + /// <param name="folder">The folder the message is in.</param> + /// <param name="flags">The flags to set.</param> + void SetMessageFlags(IAuthenticationToken authToken, int messageId, StoreFolder folder, StoreMessageFlags flags); + #endregion + + #region Message Retrieval + /// <summary> + /// Gets the internal date for the message. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageId">The Id of the message to get the date for.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The message date or null if invalid folder or privileges.</returns> + DateTime? GetInternalDate(IAuthenticationToken authToken, int messageId, StoreFolder folder); + + /// <summary> + /// Gets the size of the message. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="messageId">The Id of the message to get the size from.</param> + /// <param name="folder">The folder the message is in.</param> + /// <returns>The message size in bytes or null if invalid folder or privileges.</returns> + int? GetMessageSize(IAuthenticationToken authToken, int messageId, StoreFolder folder); + + /// <summary> + /// Gets the headers for the message. + /// </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> + /// <returns>The message headers or null if none exist.</returns> + MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, StoreFolder folder); + + /// <summary> + /// Gets a specific MIME part from the message. + /// </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="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); + + /// <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> + /// <returns>The message or null if the message Id is invalid.</returns> + Message GetMessage(IAuthenticationToken authToken, int messageId, StoreFolder folder); + #endregion + + #region Message Counts + /// <summary> + /// Gets the number of messages in the given store folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to count the messages in.</param> + /// <returns>The message count or null if invalid folder or privileges.</returns> + int? GetMessageCount(IAuthenticationToken authToken, StoreFolder folder); + + /// <summary> + /// Gets the number of messages with the RECENT flag set. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to count the recent messages in.</param> + /// <returns>The number of recent messages or null if invalid folder or privileges.</returns> + int? GetRecentMessageCount(IAuthenticationToken authToken, StoreFolder folder); + #endregion + + /// <summary> + /// Permanently removes messages flagged as deleted. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to delete messages in.</param> + /// <returns> + /// The list of message offsets for the deleted messages or null if insufficient + /// privileges or invalid folder. + /// </returns> + int[] PurgeDeletedMessages(IAuthenticationToken authToken, StoreFolder folder); + + #region Folder ACLs + /// <summary> + /// Sets the privileges on the folder. If no ACE exists for the associated + /// identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to set the ACE on.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, GenericAce<StoreFolderPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given user. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folder">The folder to remove the ACE from.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, string identifier); + + /// <summary> + /// Gets the ACL for the given folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to get the ACL for.</param> + /// <returns>The folder ACL or null if insufficient privileges.</returns> + StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, int folderId); + #endregion + + #region Load and Save Object + /// <summary> + /// Gets a serialized object that can be used by either an validation or a delivery action. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="type">The requesting class' type.</param> + /// <param name="key">A key to identify which object to get.</param> + /// <returns>The object.</returns> + object LoadOjbect(IAuthenticationToken authToken, Type type, string key); + + /// <summary> + /// Serializes an object that can be used later by either an validation or a delivery action. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="type">The requesting class' type.</param> + /// <param name="key">A key to identify the object at load time.</param> + void SaveObject(IAuthenticationToken authToken, object o, Type type, string key); + #endregion + + #region User Management + /// <summary> + /// Gets the user for the given username. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="username">The username to look up.</param> + /// <returns>The matching user or null if non is found.</returns> + LocalStoreUser GetUser(IAuthenticationToken authToken, string username); + + /// <summary> + /// Gets the user for the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to look up.</param> + /// <returns>The matching user or null if non is found.</returns> + LocalStoreUser GetUser(IAuthenticationToken authToken, int userId); + + /// <summary> + /// Gets the list of users that currently exist in the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of users.</returns> + LocalStoreUser[] GetUsers(IAuthenticationToken authToken); + + /// <summary> + /// Creates a new user in the local store and creates an initial folder. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userName">The name of the new user.</param> + /// <param name="warnQuota">The warning quota level.</param> + /// <param name="hardQuota">The hard quota.</param> + /// <returns>The result of the attemp to create a new user.</returns> + LocalStoreUserResult CreateUser(IAuthenticationToken authToken, string userName, int? warnQuota, int? hardQuota); + + /// <summary> + /// Removes a user from the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to delete.</param> + /// <returns>The result of the attempt to delete a user.</returns> + LocalStoreUserResult DeleteUser(IAuthenticationToken authToken, int userId); + + /// <summary> + /// Updates the any changes to the user into the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="user">The user details to update.</param> + /// <returns>The result of the attempt to update the user.</returns> + LocalStoreUserResult UpdateUser(IAuthenticationToken authToken, LocalStoreUser user); + + /// <summary> + /// Gets the list of email addresses that map to the given user. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to look up the addresses for.</param> + /// <returns>The user's email addresses.</returns> + EmailAddress[] GetUserAddresses(IAuthenticationToken authToken, int userId); + + /// <summary> + /// Adds the given address the to list of addresses for the user. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to add the address for.</param> + /// <param name="address">The address to add.</param> + void AddUserAddress(IAuthenticationToken authToken, int userId, EmailAddress address); + + /// <summary> + /// Removes the given address from the list of addresses for the user. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to remove the address from.</param> + /// <param name="address">The address to remove.</param> + void RemoveUserAddress(IAuthenticationToken authToken, int userId, EmailAddress address); + + /// <summary> + /// Adds a user to the given mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to add.</param> + /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> + /// <returns>The result of the attempt to add the user to the mail domain.</returns> + LocalStoreUserResult AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + + /// <summary> + /// Removes user from the given mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to remove.</param> + /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> + /// <returns>The result of the attempt to remove the user from the mail domain.</returns> + LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid or unauthorized.</returns> + StoreFolder[] GetUserFolders(IAuthenticationToken authToken, int userId); + #endregion + + #region Group Management + /// <summary> + /// Gets the group for the given name. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="name">The name to look up.</param> + /// <returns>The matching group or null if non is found.</returns> + LocalStoreGroup GetGroup(IAuthenticationToken authToken, string name); + + /// <summary> + /// Gets the group for the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to look up.</param> + /// <returns>The matching group or null if non is found.</returns> + LocalStoreGroup GetGroup(IAuthenticationToken authToken, int groupId); + + /// <summary> + /// Gets the list of groups that currently exist in the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of groups.</returns> + LocalStoreGroup[] GetGroups(IAuthenticationToken authToken); + + /// <summary> + /// Creates a new group in the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="name">The name of the new group.</param> + /// <returns>The result of the attemp to create a new group.</returns> + LocalStoreGroupResult CreateGroup(IAuthenticationToken authToken, string name); + + /// <summary> + /// Removes a group from the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to delete.</param> + /// <returns>The result of the attempt to delete a group.</returns> + LocalStoreGroupResult DeleteGroup(IAuthenticationToken authToken, int groupId); + + /// <summary> + /// Renames the group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + LocalStoreGroupResult RenameGroup(IAuthenticationToken authToken, LocalStoreGroup group); + + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToGroup(IAuthenticationToken authToken, int parentId, int groupId); + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromGroup(IAuthenticationToken authToken, int parentId, int groupId); + + /// <summary> + /// Adds a group to the given mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to add.</param> + /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> + LocalStoreGroupResult AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + + /// <summary> + /// Removes group from the given mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to remove.</param> + /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> + LocalStoreGroupResult RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + #endregion + + #region Mail Domain Management + /// <summary> + /// Gets all mail domains associated with this local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The mail domains.</returns> + MailDomain[] GetMailDomains(IAuthenticationToken authToken); + + /// <summary> + /// Creates a new mail domain for the given host. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="host">The primary host for the mail domain.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host host); + + /// <summary> + /// Deletes a mail domain from the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomainId">The Id of the mail domain to delete.</param> + /// <returns>The result of the attempt to delete the domain.</returns> + LocalStoreMailDomainResult DeleteMailDomain(IAuthenticationToken authToken, int mailDomainId); + + /// <summary> + /// Updates a mail domain in the local store. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="updatedMailDomain">The updated mail domain.</param> + /// <returns>The result of the attempt to update the mail domain.</returns> + LocalStoreMailDomainResult UpdateMailDomain(IAuthenticationToken authToken, MailDomain updatedMailDomain); + + /// <summary> + /// Gets a list of group Ids for groups that are associated with the given + /// mail domain Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomainId">The mail domain to look up the groups for.</param> + /// <returns>The list of group Ids.</returns> + int[] GetMailDomainGroups(IAuthenticationToken authToken, int mailDomainId); + + /// <summary> + /// Gets a list of user Ids for groups that are associated with the given + /// mail domain Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomainId">The mail domain to look up the users for.</param> + /// <returns>The list of user Ids.</returns> + int[] GetMailDomainUsers(IAuthenticationToken authToken, int mailDomainId); + #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetSystemPrivilegeAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveSystemPrivilegeAce(IAuthenticationToken authToken, string identifier); + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The system ACL or null if insufficient privileges.</returns> + GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(IAuthenticationToken authToken); + #endregion + + #region User and Group Administration + /// <summary> + /// Get the ACL that lists user's privileges for user and group administration. + /// </summary> + /// <param name="user">The user trying to get the admin ACL.</param> + /// <returns>The ACL or null if insufficient privileges.</returns> + GenericAcl<UserGroupAdminPrivilege> GetAdministrationAcl(IAuthenticationToken user); + + /// <summary> + /// Sets the administration privileges for the associated identifier. + /// If no ACE exists for the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetAdministrationAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveAdministrationAce(IAuthenticationToken authToken, string identifier); + #endregion + } + + /// <summary> + /// Possible return results for local store folder operations. + /// </summary> + public enum LocalStoreFolderResult { + /// <summary> + /// The operation was completed successfully. + /// </summary> + OkSuccessful = 0, + + /// <summary> + /// The create or rename failed because a folder with the same name already existed. + /// </summary> + AlreadyExists = 1, + + /// <summary> + /// The folder was not deleted because it contained child folders. + /// </summary> + HasChildren = 2, + + /// <summary> + /// The operation failed because the source folder was not found on the server. + /// If the operation is on a subfolder that the user can't see due to permissions + /// this will be returned. + /// </summary> + NonExistent = 3, + + /// <summary> + /// The user is not permitted to perform the operation. + /// </summary> + NotPermitted = 4 + } + + /// <summary> + /// Possible return results for local store user operations. + /// </summary> + public enum LocalStoreUserResult { + /// <summary> + /// The operation completed successfully. + /// </summary> + OkSuccessful = 0, + + /// <summary> + /// A user with the same name already exists. + /// </summary> + AlreadyExists = 1, + + /// <summary> + /// No matching user exists in the local store. + /// </summary> + NoSuchUser = 2, + + /// <summary> + /// Cannot add or remove the user from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> + /// The user cannot be deleted because they still own folders. + /// </summary> + UserStillHasFolders = 4, + + /// <summary> + /// The user is not permitted to perform the operation. + /// </summary> + NotPermitted = 5, + + /// <summary> + /// The user cannot be created because there is existing folders with the same details. + /// </summary> + FoldersAlreadyExist = 6, + + /// <summary> + /// An unknown error occurred trying to perform the operation. + /// </summary> + UnkownError = 7 + } + + /// <summary> + /// Possible return results for local store group operations. + /// </summary> + public enum LocalStoreGroupResult { + /// <summary> + /// The operation completed successfully. + /// </summary> + OkSuccessful = 0, + + /// <summary> + /// A group with the same name already exists. + /// </summary> + AlreadyExists = 1, + + /// <summary> + /// No matching group exists in the local store. + /// </summary> + NoSuchGroup = 2, + + /// <summary> + /// Cannot add or remove the group from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> + /// The user is not permitted to perform the operation. + /// </summary> + NotPermitted = 4 + } + + /// <summary> + /// Possible return results for local store mail domain operations. + /// </summary> + public enum LocalStoreMailDomainResult { + /// <summary> + /// The operation completed successfully. + /// </summary> + OkSuccessful = 0, + + /// <summary> + /// A mail domain with the same primary host already exists. + /// </summary> + AlreadyExists = 1, + + /// <summary> + /// No matching mail domain exists in the local store. + /// </summary> + NoSuchMailDomain = 2, + + /// <summary> + /// The user is not permitted to perform the operation. + /// </summary> + NotPermitted = 3 + } +} Copied: NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreData.cs (from rev 49, NMail/branches/luke-dev/NMail/ILocalStoreData.cs) =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreData.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2006-07-01 15:34:40 UTC (rev 55) @@ -0,0 +1,521 @@ +/* + * 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.Data; + +using NMail.DataTypes; +using NMail.DataTypes.ACLs; + +namespace NMail.DataTypes.LocalStore { + /// <summary> + /// The interface for a local store data provider. + /// </summary> + public interface ILocalStoreData { + #region Message Delivery + /// <summary> + /// Delivers the message into the given folder. + /// </summary> + /// <param name="message">The details of the delivery.</param> + void DeliverMessage(LocalStoreDelivery message); + + /// <summary> + /// Delivers the message into the given folder. + /// </summary> + /// <param name="message">The message data.</param> + /// <param name="folder">The folder to deliver into.</param> + void DeliverMessage(Message message, StoreFolder folder); + #endregion + + #region Folder Retrieval and Manipulation + /// <summary> + /// Gets the nominal folder for the given user name. + /// </summary> + /// <param name="userName">The user to get the folder for.</param> + /// <returns>The nominal store folder or null if the username is invalid.</returns> + StoreFolder GetNominalStoreFolder(string userName); + + /// <summary> + /// Gets the store folder from the given folder name. + /// </summary> + /// <param name="folder">The folder to lookup.</param> + /// <returns>The store folder or null if the folder name is invalid.</returns> + StoreFolder GetStoreFolder(Folder folder); + + /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invali... [truncated message content] |
|
From: <tmy...@us...> - 2006-07-01 09:42:41
|
Revision: 54 Author: tmyroadctfig Date: 2006-07-01 02:39:32 -0700 (Sat, 01 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=54&view=rev Log Message: ----------- Merged in changes from development branch. Modified Paths: -------------- NMail/trunk/Installer/NMail-Installer.wxs NMail/trunk/Installer/NMail-installer.build NMail/trunk/NDns/NDns.xml NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs NMail/trunk/NMail/Authentication/NullAuthentication.cs NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs NMail/trunk/NMail/DataTypes/ACLs/GenericAcl.cs NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAcl.cs NMail/trunk/NMail/DataTypes/ACLs/StoreFolderPrivilege.cs NMail/trunk/NMail/DataTypes/LocalStore/MailDomain.cs NMail/trunk/NMail/DataTypes/Message.cs NMail/trunk/NMail/DataTypes/StoreFolder.cs NMail/trunk/NMail/ILocalStore.cs NMail/trunk/NMail/ILocalStoreData.cs NMail/trunk/NMail/ISpoolData.cs NMail/trunk/NMail/NMail.csproj NMail/trunk/NMail.Administration.Console/Command/AddMailDomainCommand.cs NMail/trunk/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/trunk/NMail.Administration.Web/App_Code/MailDomainDataSource.cs NMail/trunk/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/trunk/NMail.Administration.Web/CreateFolder.aspx NMail/trunk/NMail.Administration.Web/CreateFolder.aspx.cs NMail/trunk/NMail.Administration.Web/CreateUser.aspx NMail/trunk/NMail.Administration.Web/CreateUser.aspx.cs NMail/trunk/NMail.Administration.Web/FolderDetails.aspx NMail/trunk/NMail.Administration.Web/FolderDetails.aspx.cs NMail/trunk/NMail.Administration.Web/Login.aspx NMail/trunk/NMail.Administration.Web/Login.aspx.cs NMail/trunk/NMail.Administration.Web/MailDomainDetails.aspx NMail/trunk/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/trunk/NMail.Administration.Web/MasterPage.master NMail/trunk/NMail.Administration.Web/StyleSheet.css NMail/trunk/NMail.Administration.Web/UserDetails.aspx NMail/trunk/NMail.Administration.Web/UserDetails.aspx.cs NMail/trunk/NMail.Administration.Web/ViewFolders.aspx NMail/trunk/NMail.Administration.Web/ViewFolders.aspx.cs NMail/trunk/NMail.Administration.Web/ViewMailDomains.aspx NMail/trunk/NMail.Administration.Web/ViewMailDomains.aspx.cs NMail/trunk/NMail.Administration.Web/ViewUsers.aspx NMail/trunk/NMail.Administration.Web/Web.sitemap NMail/trunk/NMail.ImapService/State/AuthenticatedState.cs NMail/trunk/NMail.ImapService/State/ExamineState.cs NMail/trunk/NMail.LocalStore/LocalStore.cs NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/trunk/NMail.Server/NMail.Server.csproj NMail/trunk/NMail.Server/RemoteAdministration.cs NMail/trunk/NMail.SmtpService/SmtpService.cs NMail/trunk/NMail.build NMail/trunk/NMail.sln NMail/trunk/doc/NMail User's Guide.doc Added Paths: ----------- NMail/trunk/Installer/WixLib/sca.wixlib NMail/trunk/Installer/WixLib/scaexec.dll NMail/trunk/Installer/WixLib/scasched.dll NMail/trunk/Installer/WixLib/wixui_featuretree.wixlib NMail/trunk/NMail/DataTypes/Envelope.cs NMail/trunk/NMail.Administration.Web/Bin/NMail.Server.dll.refresh NMail/trunk/NMail.Administration.Web/Bin/NMail.dll.refresh NMail/trunk/NMail.Administration.Web/Bin/log4net.dll.refresh NMail/trunk/NMail.Administration.Web/CreateMailDomain.aspx NMail/trunk/NMail.Administration.Web/CreateMailDomain.aspx.cs NMail/trunk/NMail.Administration.Web/Images/GreenLight.png NMail/trunk/NMail.Administration.Web/Images/Tango/ NMail/trunk/NMail.Administration.Web/Images/Tango/Delete.png NMail/trunk/NMail.Administration.Web/Images/Tango/Error.png NMail/trunk/NMail.Administration.Web/Images/Tango/Group.png NMail/trunk/NMail.Administration.Web/Images/Tango/License.txt NMail/trunk/NMail.Administration.Web/Images/Tango/MailDomain.png NMail/trunk/NMail.Administration.Web/Images/Tango/NewFolder.png NMail/trunk/NMail.Administration.Web/Images/Tango/OpenFolder.png NMail/trunk/NMail.Administration.Web/Images/Tango/Question.png NMail/trunk/NMail.Administration.Web/Images/Tango/Thumbs.db NMail/trunk/NMail.Administration.Web/Images/Tango/User.png NMail/trunk/NMail.Administration.Web/Images/Tango/Warning.png NMail/trunk/NMail.Administration.Web/Images/nmail-logo-white.png NMail/trunk/NMail.Administration.Web/SetPasswordPanel.ascx NMail/trunk/NMail.Administration.Web/SetPasswordPanel.ascx.cs NMail/trunk/NMail.Administration.Web/SpoolDetails.aspx NMail/trunk/NMail.Administration.Web/SpoolDetails.aspx.cs NMail/trunk/NMail.Administration.Web/TaskList.ascx NMail/trunk/NMail.Administration.Web/TaskList.ascx.cs NMail/trunk/NMail.PostInstall/ NMail/trunk/NMail.PostInstall/NMail.PostInstall.csproj NMail/trunk/NMail.PostInstall/PostInstallForm.Designer.cs NMail/trunk/NMail.PostInstall/PostInstallForm.cs NMail/trunk/NMail.PostInstall/PostInstallForm.resx NMail/trunk/NMail.PostInstall/Program.cs NMail/trunk/NMail.PostInstall/Properties/ NMail/trunk/NMail.PostInstall/Properties/AssemblyInfo.cs NMail/trunk/NMail.PostInstall/Properties/Resources.Designer.cs NMail/trunk/NMail.PostInstall/Properties/Resources.resx NMail/trunk/NMail.PostInstall/Properties/Settings.Designer.cs NMail/trunk/NMail.PostInstall/Properties/Settings.settings Removed Paths: ------------- NMail/trunk/Installer/WixLib/wixui_minimal.wixlib NMail/trunk/NMail.Administration.Web/Images/Tango/Delete.png NMail/trunk/NMail.Administration.Web/Images/Tango/Error.png NMail/trunk/NMail.Administration.Web/Images/Tango/Group.png NMail/trunk/NMail.Administration.Web/Images/Tango/License.txt NMail/trunk/NMail.Administration.Web/Images/Tango/MailDomain.png NMail/trunk/NMail.Administration.Web/Images/Tango/NewFolder.png NMail/trunk/NMail.Administration.Web/Images/Tango/OpenFolder.png NMail/trunk/NMail.Administration.Web/Images/Tango/Question.png NMail/trunk/NMail.Administration.Web/Images/Tango/Thumbs.db NMail/trunk/NMail.Administration.Web/Images/Tango/User.png NMail/trunk/NMail.Administration.Web/Images/Tango/Warning.png NMail/trunk/NMail.PostInstall/NMail.PostInstall.csproj NMail/trunk/NMail.PostInstall/PostInstallForm.Designer.cs NMail/trunk/NMail.PostInstall/PostInstallForm.cs NMail/trunk/NMail.PostInstall/PostInstallForm.resx NMail/trunk/NMail.PostInstall/Program.cs NMail/trunk/NMail.PostInstall/Properties/ NMail/trunk/NMail.PostInstall/Properties/AssemblyInfo.cs NMail/trunk/NMail.PostInstall/Properties/Resources.Designer.cs NMail/trunk/NMail.PostInstall/Properties/Resources.resx NMail/trunk/NMail.PostInstall/Properties/Settings.Designer.cs NMail/trunk/NMail.PostInstall/Properties/Settings.settings Property Changed: ---------------- NMail/trunk/ NMail/trunk/NMail.Administration.Web/Bin/ NMail/trunk/NMail.Administration.Web/Images/ Property changes on: NMail/trunk ___________________________________________________________________ Name: svn:ignore - NMail.suo NMail.Administration.Web.suo + NMail.suo NMail.Administration.Web.suo NMail.Administration.Web.Compiled Modified: NMail/trunk/Installer/NMail-Installer.wxs =================================================================== --- NMail/trunk/Installer/NMail-Installer.wxs 2006-07-01 08:36:49 UTC (rev 53) +++ NMail/trunk/Installer/NMail-Installer.wxs 2006-07-01 09:39:32 UTC (rev 54) @@ -3,7 +3,7 @@ <Product Id="3EEDBE2D-3E7A-44b1-B4AA-1DDD2EB0068E" UpgradeCode="01CC30D2-B022-4e6c-A63B-7DD7ACCCCCE2" - Name="NMail Server" + Name="NMail Server 1.0" Language="1033" Version="1.0.0.0" Manufacturer="NMailServer.SourceForge.net"> @@ -72,7 +72,133 @@ <!-- Account="NetworkService" --> </Component> + + <!-- + == + == Webpage + == + --> + + <Directory Id="D_NMail.Administration.Web" Name="NMAILA_1.COM" LongName="NMail.Administration.Web"> + <Component Id="component0" DiskId="1" Guid="1BC3A682-453C-4a9d-8505-C683C88B18EC"> + <File Id="file0" Name="CREATE_1.ASP" LongName="CreateFolder.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateFolder.aspx" /> + </Component> + <Component Id="component1" DiskId="1" Guid="58B1F639-1053-425a-9C3E-8C474766C8AA"> + <File Id="file1" Name="CREATE_2.ASP" LongName="CreateMailDomain.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateMailDomain.aspx" /> + </Component> + <Component Id="component2" DiskId="1" Guid="62FF02F4-8B59-42d0-88A0-A1B6D9D3CB7B"> + <File Id="file2" Name="CREATE_3.ASP" LongName="CreateUser.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateUser.aspx" /> + </Component> + <Component Id="component3" DiskId="1" Guid="3D8F8DB0-EEF4-4a18-8C5E-877C81FA2DC9"> + <File Id="file3" Name="DEFAUL_1.ASP" LongName="Default.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Default.aspx" /> + </Component> + <Component Id="component4" DiskId="1" Guid="F373F057-4FD0-42a1-965B-D128A78D2417"> + <File Id="file4" Name="FOLDER_1.ASP" LongName="FolderDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\FolderDetails.aspx" /> + </Component> + <Component Id="component5" DiskId="1" Guid="E09BDDD2-672E-4c51-8113-EF0204DAF0CC"> + <File Id="file5" Name="LOGIN_1.ASP" LongName="Login.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Login.aspx" /> + </Component> + <Component Id="component6" DiskId="1" Guid="DB8F981C-974F-4e6b-A783-7D69B22AD4ED"> + <File Id="file6" Name="MAILDO_1.ASP" LongName="MailDomainDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\MailDomainDetails.aspx" /> + </Component> + <Component Id="component7" DiskId="1" Guid="F1329BF3-66A9-45cb-B278-D0DD59A1E0E2"> + <File Id="file7" Name="MASTER_1.MAS" LongName="MasterPage.master" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\MasterPage.master" /> + </Component> + <Component Id="component8" DiskId="1" Guid="A57703A5-14A6-4a50-8677-793088C9D110"> + <File Id="file8" Name="PRECOM_1.CON" LongName="PrecompiledApp.config" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\PrecompiledApp.config" /> + </Component> + <Component Id="component9" DiskId="1" Guid="0A419E0E-4A82-4d97-AB36-AFBB1829F9EC"> + <File Id="file9" Name="STYLES_1.CSS" LongName="StyleSheet.css" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\StyleSheet.css" /> + </Component> + <Component Id="component10" DiskId="1" Guid="901C7F89-7965-4f37-A42A-47F9EB1607FB"> + <File Id="file10" Name="USERDE_1.ASP" LongName="UserDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\UserDetails.aspx" /> + </Component> + <Component Id="component11" DiskId="1" Guid="0FBFBD37-7C67-42b5-BDD3-129960FB366B"> + <File Id="file11" Name="VIEWFO_1.ASP" LongName="ViewFolders.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewFolders.aspx" /> + </Component> + <Component Id="component12" DiskId="1" Guid="C54A6CB9-71E1-45e8-8E1A-B88CA863EF4B"> + <File Id="file12" Name="VIEWMA_1.ASP" LongName="ViewMailDomains.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewMailDomains.aspx" /> + </Component> + <Component Id="component13" DiskId="1" Guid="C936C25B-CCCB-436d-87CE-A1D54E10707E"> + <File Id="file13" Name="VIEWUS_1.ASP" LongName="ViewUsers.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewUsers.aspx" /> + </Component> + <Component Id="component14" DiskId="1" Guid="837D56B3-D38C-4331-A681-27E8E11AA9F4"> + <File Id="file14" Name="WEB_1.CON" LongName="web.config" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\web.config" /> + </Component> + <Component Id="component15" DiskId="1" Guid="3E8F5756-8B2B-44dc-BCAB-CDBA16EF695E"> + <File Id="file15" Name="WEB_1.SIT" LongName="Web.sitemap" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Web.sitemap" /> + </Component> + <Directory Id="directory1" Name="bin"> + <Component Id="component16" DiskId="1" Guid="F1DDFAF8-BB62-45d2-BEAA-CCF24A85B6AE"> + <File Id="file40" Name="APP_CO_1.COM" LongName="App_Code.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Code.compiled" /> + <File Id="file41" Name="App_Code.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Code.dll" /> + <File Id="file42" Name="APP_GL_1.COM" LongName="App_global.asax.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_global.asax.compiled" /> + <File Id="file43" Name="APP_GL_1.DLL" LongName="App_global.asax.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_global.asax.dll" /> + <File Id="file44" Name="APAF9A_1.DLL" LongName="App_Web_createfolder.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createfolder.aspx.cdcab7d2.dll" /> + <File Id="file45" Name="APP_WE_4.DLL" LongName="App_Web_createmaildomain.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createmaildomain.aspx.cdcab7d2.dll" /> + <File Id="file46" Name="AP65FC_1.DLL" LongName="App_Web_createuser.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createuser.aspx.cdcab7d2.dll" /> + <File Id="file47" Name="APD8FB_1.DLL" LongName="App_Web_folderdetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_folderdetails.aspx.cdcab7d2.dll" /> + <File Id="file48" Name="APP_WE_3.DLL" LongName="App_Web_login.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_login.aspx.cdcab7d2.dll" /> + <File Id="file49" Name="APEDBC_1.DLL" LongName="App_Web_maildomaindetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_maildomaindetails.aspx.cdcab7d2.dll" /> + <File Id="file50" Name="AP71CE_1.DLL" LongName="App_Web_userdetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_userdetails.aspx.cdcab7d2.dll" /> + <File Id="file51" Name="APP_WE_2.DLL" LongName="App_Web_viewfolders.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_viewfolders.aspx.cdcab7d2.dll" /> + <File Id="file52" Name="APP_WE_1.DLL" LongName="App_Web_viewmaildomains.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_viewmaildomains.aspx.cdcab7d2.dll" /> + <File Id="file53" Name="log4net.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\log4net.dll" /> + <File Id="file54" Name="NMail.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\NMail.dll" /> + <File Id="file55" Name="NMAILS_1.DLL" LongName="NMail.Server.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\NMail.Server.dll" /> + </Component> + </Directory> + <Directory Id="directory2" Name="Images"> + <Component Id="component24" DiskId="1" Guid="4FDC7813-EFB1-4d67-AAE1-059F12D28124"> + <File Id="file24" Name="GREENL_1.PNG" LongName="GreenLight.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\GreenLight.png" /> + </Component> + <Component Id="component25" DiskId="1" Guid="36A40106-5C2D-4a8e-860C-810B80017A14"> + <File Id="file25" Name="NMAIL-_2.PNG" LongName="nmail-logo-white.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\nmail-logo-white.png" /> + </Component> + <Component Id="component26" DiskId="1" Guid="630CCA29-88EF-4822-A66B-4DD007B303FE"> + <File Id="file26" Name="NMAIL-_1.PNG" LongName="nmail-logo.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\nmail-logo.png" /> + </Component> + <Directory Id="directory3" Name="Tango"> + <Component Id="component27" DiskId="1" Guid="429427BF-BDD7-4580-9A4B-9F81A86C50CF"> + <File Id="file27" Name="Delete.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Delete.png" /> + </Component> + <Component Id="component28" DiskId="1" Guid="DD3F20E9-0F8F-4886-A12A-B87CDF0825ED"> + <File Id="file28" Name="Error.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Error.png" /> + </Component> + <Component Id="component29" DiskId="1" Guid="B80FA867-3CAB-4738-92BB-940A03DF037F"> + <File Id="file29" Name="Group.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Group.png" /> + </Component> + <Component Id="component30" DiskId="1" Guid="DFBFF8C5-B46F-429f-BDAB-23E8C52A70B6"> + <File Id="file30" Name="License.txt" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\License.txt" /> + </Component> + <Component Id="component31" DiskId="1" Guid="685A6306-9351-4b13-9CCC-6A003EF84066"> + <File Id="file31" Name="MAILDO_1.PNG" LongName="MailDomain.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\MailDomain.png" /> + </Component> + <Component Id="component32" DiskId="1" Guid="E4843991-0C95-4a91-94C8-42B012558CFF"> + <File Id="file32" Name="NEWFOL_1.PNG" LongName="NewFolder.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\NewFolder.png" /> + </Component> + <Component Id="component33" DiskId="1" Guid="11E1F4EC-00EE-4f75-9870-2125D5721A18"> + <File Id="file33" Name="OPENFO_1.PNG" LongName="OpenFolder.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\OpenFolder.png" /> + </Component> + <Component Id="component34" DiskId="1" Guid="EFFE59E3-03A6-4b0c-B95A-C2AF83DBFCC8"> + <File Id="file34" Name="Question.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Question.png" /> + </Component> + <Component Id="component35" DiskId="1" Guid="EFFA585C-6A2A-43cb-B14B-2BE9D6110C18"> + <File Id="file35" Name="User.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\User.png" /> + </Component> + <Component Id="component36" DiskId="1" Guid="E7A5CA36-4DAB-40c6-A7D0-B24249DCFFCC"> + <File Id="file36" Name="Warning.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Warning.png" /> + </Component> + </Directory> + </Directory> + </Directory> + <Component Id="C_VirtualWebDir" Guid="45A1A00F-7CAB-462f-A361-18566149FEBF"> + <WebVirtualDir Id="WebVirtualDir" Alias="NMailAdmin" Directory="D_NMail.Administration.Web" WebSite="DefaultWebSite"> + <WebApplication Id="WebApplication" Name="NMailAdmin" /> + </WebVirtualDir> + </Component> + <!-- == == Core DLLs @@ -170,7 +296,7 @@ </Component> <Component Id="C_NMail.config" Guid="FEB536D0-BB1A-47b9-9C1C-0142A210DD72"> - <File Id="NMail.config" Name="NMail.cfg" LongName="NMail.config" DiskId="1" Source="obj\NMail.config" Vital="yes" /> + <File Id="NMail.config" Name="NMail.cfg" LongName="NMail.config.Sample" DiskId="1" Source="obj\NMail.config" Vital="yes" /> </Component> <Component Id="C_NMail.pfx" Guid="93D43655-6B2D-4539-850E-9063F20B0E69"> @@ -210,45 +336,102 @@ </Directory> <Directory Id="DesktopFolder" Name="Desktop" /> - </Directory> - - <Feature Id="MainFeature" Title="Complete" Level="1"> - <!-- Core EXEs --> - <ComponentRef Id="C_NMail.Server.Console.exe" /> - <ComponentRef Id="C_NMail.Administration.Console.exe" /> - <ComponentRef Id="C_NMail.Server.Service.exe" /> + </Directory> + <WebSite Id="DefaultWebSite" Description="Default Web Site"> + <WebAddress Id="AllUnassigned" Port="443" Secure="yes"/> + </WebSite> + + <Feature Id="F_Base" Absent="disallow" Title="NMail" Level="1" + ConfigurableDirectory="INSTALLDIR" Display="expand" + Description="The components required in a NMail installation."> + <!-- Core DLLs --> - <ComponentRef Id="C_MonoPrivileges.dll" /> - <ComponentRef Id="C_NDns.dll" /> <ComponentRef Id="C_NMail.dll" /> - <ComponentRef Id="C_NMail.DnsClient.dll" /> - <ComponentRef Id="C_NMail.ImapService.dll" /> - <ComponentRef Id="C_NMail.LocalStore.dll" /> - <ComponentRef Id="C_NMail.LocalStoreData.MySql.dll" /> - <ComponentRef Id="C_NMail.MessageRouter.dll" /> <ComponentRef Id="C_NMail.Server.dll" /> - <ComponentRef Id="C_NMail.SmtpClient.dll" /> - <ComponentRef Id="C_NMail.SmtpService.dll" /> - <ComponentRef Id="C_NMail.SpoolData.MySql.dll" /> - <ComponentRef Id="C_NMail.SpoolFilter.dll" /> - <ComponentRef Id="C_NMail.SpoolFilter.RegexAddressRewriter.dll" /> - <ComponentRef Id="C_NMail.SpoolService.dll" /> - <!-- Non-NMail core DLLs --> + <!-- Non-NMail DLLs --> <ComponentRef Id="C_log4net.dll" /> - <ComponentRef Id="C_Mono.Security.dll" /> + + <Feature Id="F_Server" Display="expand" Title="NMail Server" Level="1" + Description="The NMail mail server."> + + <!-- NMail Server EXEs --> + <ComponentRef Id="C_NMail.Server.Console.exe" /> + <ComponentRef Id="C_NMail.Administration.Console.exe" /> + <ComponentRef Id="C_NMail.Server.Service.exe" /> + + <!-- NMail Server DLLs --> + <ComponentRef Id="C_MonoPrivileges.dll" /> + <ComponentRef Id="C_NDns.dll" /> + <ComponentRef Id="C_NMail.DnsClient.dll" /> + <ComponentRef Id="C_NMail.ImapService.dll" /> + <ComponentRef Id="C_NMail.LocalStore.dll" /> + <ComponentRef Id="C_NMail.LocalStoreData.MySql.dll" /> + <ComponentRef Id="C_NMail.MessageRouter.dll" /> + <ComponentRef Id="C_NMail.SmtpClient.dll" /> + <ComponentRef Id="C_NMail.SmtpService.dll" /> + <ComponentRef Id="C_NMail.SpoolData.MySql.dll" /> + <ComponentRef Id="C_NMail.SpoolFilter.dll" /> + <ComponentRef Id="C_NMail.SpoolFilter.RegexAddressRewriter.dll" /> + <ComponentRef Id="C_NMail.SpoolService.dll" /> + + <!-- Non-NMail DLLs --> + <ComponentRef Id="C_Mono.Security.dll" /> + + <!-- Other core files --> + <ComponentRef Id="C_Warning.txt" /> + <ComponentRef Id="C_Bounce.txt" /> + <ComponentRef Id="C_NMail.config" /> + <ComponentRef Id="C_NMail.pfx" /> + <ComponentRef Id="C_MySqlLocalStore.sql" /> + <ComponentRef Id="C_MySqlSpoolData.sql" /> + </Feature> - <!-- Other core files --> - <ComponentRef Id="C_Warning.txt" /> - <ComponentRef Id="C_Bounce.txt" /> - <ComponentRef Id="C_NMail.config" /> - <ComponentRef Id="C_NMail.pfx" /> - <ComponentRef Id="C_MySqlLocalStore.sql" /> - <ComponentRef Id="C_MySqlSpoolData.sql" /> + <Feature Id="F_AdminWebsite" Display="expand" Title="Administration Website" Level="1" + Description="NMail's ASP.net administration website."> - <!-- Documentation files --> - <ComponentRef Id="C_DevGuide.doc"/> + <ComponentRef Id="C_VirtualWebDir"/> + + <!-- Admin website files --> + <ComponentRef Id="component0"/> + <ComponentRef Id="component1"/> + <ComponentRef Id="component2"/> + <ComponentRef Id="component3"/> + <ComponentRef Id="component4"/> + <ComponentRef Id="component5"/> + <ComponentRef Id="component6"/> + <ComponentRef Id="component7"/> + <ComponentRef Id="component8"/> + <ComponentRef Id="component9"/> + <ComponentRef Id="component10"/> + <ComponentRef Id="component11"/> + <ComponentRef Id="component12"/> + <ComponentRef Id="component13"/> + <ComponentRef Id="component14"/> + <ComponentRef Id="component15"/> + <ComponentRef Id="component16"/> + <ComponentRef Id="component24"/> + <ComponentRef Id="component25"/> + <ComponentRef Id="component26"/> + <ComponentRef Id="component27"/> + <ComponentRef Id="component28"/> + <ComponentRef Id="component29"/> + <ComponentRef Id="component30"/> + <ComponentRef Id="component31"/> + <ComponentRef Id="component32"/> + <ComponentRef Id="component33"/> + <ComponentRef Id="component34"/> + <ComponentRef Id="component35"/> + <ComponentRef Id="component36"/> + </Feature> + + <Feature Id="F_DeveloperDoc" Display="expand" Title="Developer Documentation" Level="3" + Description="Documentation for NMail developers."> + + <!-- Developer documentation files --> + <ComponentRef Id="C_DevGuide.doc"/> + </Feature> </Feature> <UIRef Id="WixUI" /> Modified: NMail/trunk/Installer/NMail-installer.build =================================================================== --- NMail/trunk/Installer/NMail-installer.build 2006-07-01 08:36:49 UTC (rev 53) +++ NMail/trunk/Installer/NMail-installer.build 2006-07-01 09:39:32 UTC (rev 54) @@ -35,11 +35,13 @@ <include name="MySql.Data.dll" /> </fileset> </copy> + <!-- Copy NMail assemblies --> <copy todir="${build.dir}"> <fileset basedir="../References/NMail/${project.config}"> <include name="*" /> </fileset> </copy> + <!-- Copy other required files --> <copy todir="${build.dir}"> <fileset basedir="../NMail.Server.Console/"> <include name="Warning.txt" /> @@ -58,6 +60,12 @@ <include name="MySqlSpoolData.sql" /> </fileset> </copy> + <!-- Copy NMail administration website --> + <copy todir="${build.dir}"> + <fileset basedir="../"> + <include name="NMail.Administration.Web.Compiled/**" /> + </fileset> + </copy> <!-- Make a date stamp to include in the filename --> <tstamp property="build.date" pattern="yyyy-MM-dd" verbose="true" /> @@ -82,7 +90,9 @@ <arg value="-loc"/> <arg><path><pathelement file="WixLib/WixUI_en-us.wxl" /></path></arg> - <arg><path><pathelement file="WixLib/wixui_minimal.wixlib" /></path></arg> + <arg><path><pathelement file="WixLib/wixui_featuretree.wixlib" /></path></arg> + + <arg><path><pathelement file="WixLib/sca.wixlib" /></path></arg> <arg><path><pathelement file="${build.dir}/NMail-Installer.wixobj" /></path></arg> </exec> Copied: NMail/trunk/Installer/WixLib/sca.wixlib (from rev 53, NMail/branches/luke-dev/Installer/WixLib/sca.wixlib) =================================================================== --- NMail/trunk/Installer/WixLib/sca.wixlib (rev 0) +++ NMail/trunk/Installer/WixLib/sca.wixlib 2006-07-01 09:39:32 UTC (rev 54) @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><wixLibrary xmlns="http://schemas.microsoft.com/wix/2003/11/libraries" version="2.0.2207.0"><wixObject xmlns="http://schemas.microsoft.com/wix/2003/04/objects" src="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs" version="2.0.2207.0"><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureIIs" /><ignoreModularization name="RollbackMetabaseTransaction" type="Action" /><ignoreModularization name="CommitMetabaseTransaction" type="Action" /><ignoreModularization name="StartMetabaseTransaction" type="Action" /><ignoreModularization name="DeleteCertificate" type="Action" /><ignoreModularization name="AddCertificate" type="Action" /><ignoreModularization name="ConfigureIIs" type="Action" /><ignoreModularization name="WriteMetabaseChanges" type="Action" /><table name="ActionText"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*51"><field>ConfigureIIs</field><field>Configuring IIS</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*52"><field>StartMetabaseTransaction</field><field>Starting IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*53"><field>RollbackMetabaseTransaction</field><field>Rolling back IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*54"><field>CommitMetabaseTransaction</field><field>Committing IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*55"><field>WriteMetabaseChanges</field><field>Installing Metabase Keys and Values</field><field /></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*58"><field>ConfigureIIs</field><field>1</field><field>ScaSchedule</field><field>ConfigureIIs</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*59"><field>StartMetabaseTransaction</field><field>3073</field><field>ScaExecute</field><field>StartMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*60"><field>RollbackMetabaseTransaction</field><field>3329</field><field>ScaExecute</field><field>RollbackMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*61"><field>CommitMetabaseTransaction</field><field>3585</field><field>ScaExecute</field><field>CommitMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*62"><field>WriteMetabaseChanges</field><field>3073</field><field>ScaExecute</field><field>WriteMetabaseChanges</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*63"><field>AddCertificate</field><field>3073</field><field>ScaExecute</field><field>AddCertificate</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*64"><field>DeleteCertificate</field><field>3073</field><field>ScaExecute</field><field>DeleteCertificate</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*17"><field>26001</field><field><![CDATA[Cannot connect to Internet Information Server. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*18"><field>26002</field><field><![CDATA[Failed to read IIsWebs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*19"><field>26003</field><field><![CDATA[Failed to read IIsWebDirs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*20"><field>26004</field><field><![CDATA[Failed to read IIsVirtualDirs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*21"><field>26005</field><field><![CDATA[Failed to read IIsFilters table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*22"><field>26007</field><field><![CDATA[Failed to read IIsMimeMap table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*23"><field>26006</field><field><![CDATA[Failed to read IIsAppPool table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*24"><field>26008</field><field><![CDATA[Failed to read the IIsProperty table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*25"><field>26009</field><field><![CDATA[Failed to read the IIsWebServiceExtension table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*27"><field>26031</field><field><![CDATA[Failed to schedule transaction for changes to IIS. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*28"><field>26032</field><field><![CDATA[Failed to schedule install of IIS Web Sites. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*29"><field>26033</field><field><![CDATA[Failed to schedule install of IIS Web Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*30"><field>26034</field><field><![CDATA[Failed to schedule install of IIS Virtual Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*31"><field>26035</field><field><![CDATA[Failed to schedule install of IIS Filters. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*32"><field>26036</field><field><![CDATA[Failed to schedule install of IIS AppPools. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*33"><field>26037</field><field><![CDATA[Failed to schedule install of IIS Properties. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*34"><field>26038</field><field><![CDATA[Failed to schedule install of IIS Web Service Extensions. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*36"><field>26051</field><field><![CDATA[Failed to schedule uninstall of IIS Web Sites. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*37"><field>26052</field><field><![CDATA[Failed to schedule uninstall of IIS Web Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*38"><field>26053</field><field><![CDATA[Failed to schedule uninstall of IIS Virtual Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*39"><field>26054</field><field><![CDATA[Failed to schedule uninstall of IIS Filters. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*40"><field>26055</field><field><![CDATA[Failed to schedule uninstall of IIS AppPools. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*41"><field>26056</field><field><![CDATA[Failed to schedule uninstall of IIS Properties. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*42"><field>26057</field><field><![CDATA[Failed to schedule uninstall of IIS Web Service Extensions. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*44"><field>26101</field><field><![CDATA[Failed to start IIS transaction. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*45"><field>26102</field><field><![CDATA[Failed to open metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*46"><field>26103</field><field><![CDATA[Failed to create metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*47"><field>26104</field><field><![CDATA[Failed to write data to metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*48"><field>26105</field><field><![CDATA[Failed to create web application. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*49"><field>26106</field><field><![CDATA[Failed to delete metabase key. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*67"><field>InstallExecuteSequence</field><field>ConfigureIIs</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureSql" /><ignoreModularization name="RollbackExecuteSqlStrings" type="Action" /><ignoreModularization name="ConfigureSql" type="Action" /><ignoreModularization name="CreateDatabase" type="Action" /><ignoreModularization name="ExecuteSqlStrings" type="Action" /><ignoreModularization name="DropDatabase" type="Action" /><ignoreModularization name="RollbackCreateDatabase" type="Action" /><table name="ActionText"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*86"><field>ConfigureSql</field><field>Configuring SQL Server</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*87"><field>CreateDatabase</field><field>Creating Databases</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*88"><field>DropDatabase</field><field>Dropping Databases</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*89"><field>ExecuteSqlStrings</field><field>Executing SQL Strings</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*90"><field>RollbackExecuteSqlStrings</field><field>Rolling back SQL Strings</field><field /></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*94"><field>ConfigureSql</field><field>1</field><field>ScaSchedule</field><field>ConfigureSql</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*95"><field>CreateDatabase</field><field>1025</field><field>ScaExecute</field><field>CreateDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*96"><field>RollbackCreateDatabase</field><field>1281</field><field>ScaExecute</field><field>DropDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*97"><field>DropDatabase</field><field>1025</field><field>ScaExecute</field><field>DropDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*98"><field>ExecuteSqlStrings</field><field>1025</field><field>ScaExecute</field><field>ExecuteSqlStrings</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*99"><field>RollbackExecuteSqlStrings</field><field>1281</field><field>ScaExecute</field><field>ExecuteSqlStrings</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*80"><field>26201</field><field><![CDATA[Error [2]: failed to create SQL database: [3], error detail: [4].]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*81"><field>26202</field><field><![CDATA[Error [2]: failed to drop SQL database: [3], error detail: [4].]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*82"><field>26203</field><field><![CDATA[Failed to connect to SQL database. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*83"><field>26204</field><field><![CDATA[Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5]]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*84"><field>26205</field><field><![CDATA[The database [3] already exists do you wish to continue?]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*102"><field>InstallExecuteSequence</field><field>ConfigureSql</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureUsers" /><ignoreModularization name="ConfigureUsers" type="Action" /><ignoreModularization name="CreateUser" type="Action" /><ignoreModularization name="RemoveUser" type="Action" /><ignoreModularization name="CreateUserRollback" type="Action" /><table name="Property"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*120"><field>CreateUser</field><field>nothing</field><field>0</field><field>0</field><field>1</field></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*122"><field>ConfigureUsers</field><field>1</field><field>ScaSchedule</field><field>ConfigureUsers</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*123"><field>CreateUser</field><field>11265</field><field>ScaExecute</field><field>CreateUser</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*124"><field>CreateUserRollback</field><field>3329</field><field>ScaExecute</field><field>RemoveUser</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*126"><field>RemoveUser</field><field>3585</field><field>ScaExecute</field><field>RemoveUser</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*113"><field>26401</field><field><![CDATA[Failed to create user. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*114"><field>26402</field><field><![CDATA[Failed to create user due to invalid password. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*115"><field>26403</field><field><![CDATA[Failed to add user to group. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*116"><field>26404</field><field><![CDATA[Failed to create user because it already exists. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*129"><field>InstallExecuteSequence</field><field>ConfigureUsers</field><field /><field /><field>InstallFiles</field><field /><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureSmb" /><ignoreModularization name="CreateSmbRollback" type="Action" /><ignoreModularization name="ConfigureSmb" type="Action" /><ignoreModularization name="DropSmb" type="Action" /><ignoreModularization name="CreateSmb" type="Action" /><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*144"><field>ConfigureSmb</field><field>1</field><field>ScaSchedule</field><field>ConfigureSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*145"><field>CreateSmb</field><field>3073</field><field>ScaExecute</field><field>CreateSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*146"><field>CreateSmbRollback</field><field>3393</field><field>ScaExecute</field><field>DropSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*148"><field>DropSmb</field><field>3585</field><field>ScaExecute</field><field>DropSmb</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*140"><field>26301</field><field><![CDATA[Failed to create network share. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*141"><field>26302</field><field><![CDATA[Failed to drop network share. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*151"><field>InstallExecuteSequence</field><field>ConfigureSmb</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/RemoveRegistryValues" /><reference table="Actions" symbol="InstallExecuteSequence/WriteRegistryValues" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigurePerfmonInstall" /><reference table="CustomAction" symbol="ConfigurePerfmonUninstall" /><ignoreModularization name="UnregisterPerfmon" type="Action" /><ignoreModularization name="RegisterPerfmon" type="Action" /><ignoreModularization name="RollbackRegisterPerfmon" type="Action" /><ignoreModularization name="ConfigurePerfmonUninstall" type="Action" /><ignoreModularization name="RollbackUnregisterPerfmon" type="Action" /><ignoreModularization name="ConfigurePerfmonInstall" type="Action" /><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*168"><field>ConfigurePerfmonInstall</field><field>1</field><field>ScaSchedule</field><field>ConfigurePerfmonInstall</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*169"><field>ConfigurePerfmonUninstall</field><field>1</field><field>ScaSchedule</field><field>ConfigurePerfmonUninstall</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*170"><field>RegisterPerfmon</field><field>3073</field><field>ScaExecute</field><field>RegisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*171"><field>UnregisterPerfmon</field><field>3073</field><field>ScaExecute</field><field>UnregisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*172"><field>RollbackRegisterPerfmon</field><field>3329</field><field>ScaExecute</field><field>UnregisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*173"><field>RollbackUnregisterPerfmon</field><field>3329</field><field>ScaExecute</field><field>RegisterPerfmon</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*164"><field>26251</field><field><![CDATA[Failed to register DLL with PerfMon. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*165"><field>26252</field><field><![CDATA[Failed to unregister DLL with PerfMon. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*176"><field>InstallExecuteSequence</field><field>ConfigurePerfmonInstall</field><field /><field /><field /><field>WriteRegistryValues</field><field>0</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*177"><field>InstallExecuteSequence</field><field>ConfigurePerfmonUninstall</field><field /><field /><field /><field>RemoveRegistryValues</field><field>0</field></tuple></table></section><section type="fragment"><table name="Binary"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*184"><field>ScaSchedule</field><field>scasched.dll</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*185"><field>ScaExecute</field><field>scaexec.dll</field></tuple></table></section></wixObject></wixLibrary> \ No newline at end of file Copied: NMail/trunk/Installer/WixLib/scaexec.dll (from rev 53, NMail/branches/luke-dev/Installer/WixLib/scaexec.dll) =================================================================== (Binary files differ) Copied: NMail/trunk/Installer/WixLib/scasched.dll (from rev 53, NMail/branches/luke-dev/Installer/WixLib/scasched.dll) =================================================================== (Binary files differ) Copied: NMail/trunk/Installer/WixLib/wixui_featuretree.wixlib (from rev 53, NMail/branches/luke-dev/Installer/WixLib/wixui_featuretree.wixlib) =================================================================== --- NMail/trunk/Installer/WixLib/wixui_featuretree.wixlib (rev 0) +++ NMail/trunk/Installer/WixLib/wixui_featuretree.wixlib 2006-07-01 09:39:32 UTC (rev 54) @@ -0,0 +1 @@ @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-07-01 08:37:31
|
Revision: 53 Author: tmyroadctfig Date: 2006-07-01 01:36:49 -0700 (Sat, 01 Jul 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=53&view=rev Log Message: ----------- Added a post install project. Added an initial performance counter. Work on developing an admin interface for the spool. Modified Paths: -------------- NMail/branches/luke-dev/NDns/NDns.xml NMail/branches/luke-dev/NMail/DataTypes/Message.cs NMail/branches/luke-dev/NMail/ISpoolData.cs NMail/branches/luke-dev/NMail/NMail.csproj NMail/branches/luke-dev/NMail.ImapService/State/ExamineState.cs NMail/branches/luke-dev/NMail.SmtpService/SmtpService.cs NMail/branches/luke-dev/NMail.sln NMail/branches/luke-dev/doc/NMail User's Guide.doc Added Paths: ----------- NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs NMail/branches/luke-dev/NMail.PostInstall/ NMail/branches/luke-dev/NMail.PostInstall/NMail.PostInstall.csproj NMail/branches/luke-dev/NMail.PostInstall/PostInstallForm.Designer.cs NMail/branches/luke-dev/NMail.PostInstall/PostInstallForm.cs NMail/branches/luke-dev/NMail.PostInstall/PostInstallForm.resx NMail/branches/luke-dev/NMail.PostInstall/Program.cs NMail/branches/luke-dev/NMail.PostInstall/Properties/ NMail/branches/luke-dev/NMail.PostInstall/Properties/AssemblyInfo.cs NMail/branches/luke-dev/NMail.PostInstall/Properties/Resources.Designer.cs NMail/branches/luke-dev/NMail.PostInstall/Properties/Resources.resx NMail/branches/luke-dev/NMail.PostInstall/Properties/Settings.Designer.cs NMail/branches/luke-dev/NMail.PostInstall/Properties/Settings.settings Modified: NMail/branches/luke-dev/NDns/NDns.xml =================================================================== --- NMail/branches/luke-dev/NDns/NDns.xml 2006-06-28 11:16:34 UTC (rev 52) +++ NMail/branches/luke-dev/NDns/NDns.xml 2006-07-01 08:36:49 UTC (rev 53) @@ -4,5 +4,918 @@ <name>NDns</name> </assembly> <members> + <member name="T:NDns.Message.Header"> + <summary> + Represents the header component of a DNS message. + </summary> + </member> + <member name="F:NDns.Message.Header.id"> + <summary> + A 16 bit Id number to identify this message. + </summary> + </member> + <member name="F:NDns.Message.Header.response"> + <summary> + Was this message a query or a response? + </summary> + </member> + <member name="F:NDns.Message.Header.opcode"> + <summary> + A four bit field that specifies query type in the message. + </summary> + </member> + <member name="F:NDns.Message.Header.authoritative"> + <summary> + Is the answer authoritative? + </summary> + </member> + <member name="F:NDns.Message.Header.truncated"> + <summary> + Was the message truncated due to size constraints? + </summary> + </member> + <member name="F:NDns.Message.Header.recursionDesired"> + <summary> + Is recursion desired? + </summary> + </member> + <member name="F:NDns.Message.Header.recursionAvailable"> + <summary> + Is recursion available? + </summary> + </member> + <member name="F:NDns.Message.Header.rcode"> + <summary> + The response code for this message. + </summary> + </member> + <member name="F:NDns.Message.Header.questionEntries"> + <summary> + An unsigned 16 bit integer specifying the number of entries in the + question section. + </summary> + </member> + <member name="F:NDns.Message.Header.answerEntries"> + <summary> + An unsigned 16 bit integer specifying the number of resource + records in the answer section. + </summary> + </member> + <member name="F:NDns.Message.Header.nameServerEntries"> + <summary> + An unsigned 16 bit integer specifying the number of name server + resource records in the authority records section. + </summary> + </member> + <member name="F:NDns.Message.Header.additionalEntries"> + <summary> + An unsigned 16 bit integer specifying the number of resource records in + the additional records section. + </summary> + </member> + <member name="F:NDns.Message.Header.lastId"> + <summary> + The last Id number assigned to a DNS message. + </summary> + </member> + <member name="M:NDns.Message.Header.#ctor"> + <summary> + Creates a new DNS message header with a unique Id number. + </summary> + </member> + <member name="M:NDns.Message.Header.#ctor(System.Byte[],System.UInt16,System.UInt16@)"> + <summary> + Creates a new DNS message header using the given data. This data is + typically the response from a DNS server. + </summary> + <param name="data">The data to create the message header from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + </member> + <member name="M:NDns.Message.Header.GetId"> + <summary> + Gets the next available Id number. + </summary> + <returns>The Id number.</returns> + </member> + <member name="M:NDns.Message.Header.ToByteArray"> + <summary> + Converts the header to a byte array ready to send in a DNS message. + </summary> + <returns>The header as a byte array.</returns> + </member> + <member name="M:NDns.Message.Header.CreateOpCode(System.Byte)"> + <summary> + Creates the opcode that corresponds to the given byte. + </summary> + <param name="opcode">The data to create the opcode from.</param> + <returns>The opcode.</returns> + </member> + <member name="M:NDns.Message.Header.CreateResponseCode(System.Byte)"> + <summary> + Creates the response code that corresponds to the given byte. + </summary> + <param name="rcode">The data to create the response code from.</param> + <returns>The response code.</returns> + </member> + <member name="P:NDns.Message.Header.Id"> + <summary> + Gets the Id number for this header (and thus message). + </summary> + </member> + <member name="T:NDns.Message.AnswerSection"> + <summary> + A answer section entry in a DNS message. + </summary> + </member> + <member name="F:NDns.Message.AnswerSection.answerName"> + <summary> + The string name in this answer. + </summary> + </member> + <member name="F:NDns.Message.AnswerSection.answerType"> + <summary> + The type of record. + </summary> + </member> + <member name="F:NDns.Message.AnswerSection.answerClass"> + <summary> + The query class. + </summary> + </member> + <member name="F:NDns.Message.AnswerSection.answerTTL"> + <summary> + The time to live for the answer. + </summary> + </member> + <member name="F:NDns.Message.AnswerSection.answerRecord"> + <summary> + The record data associated with this record. + </summary> + </member> + <member name="M:NDns.Message.AnswerSection.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a answer section from the given byte data. + </summary> + <param name="data">The data to create the answer section from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="P:NDns.Message.AnswerSection.Record"> + <summary> + The answer record associated with this answer entry. + </summary> + </member> + <member name="T:NDns.Message.Records.CNameRecord"> + <summary> + A DNS Canonical NAME record. + </summary> + </member> + <member name="T:NDns.Message.Records.Record"> + <summary> + A DNS record. + </summary> + </member> + <member name="F:NDns.Message.Records.Record.type"> + <summary> + The type of this record. + </summary> + </member> + <member name="F:NDns.Message.Records.Record.recordTTL"> + <summary> + The time to live for this record (in seconds). + </summary> + </member> + <member name="F:NDns.Message.Records.Record.creationTime"> + <summary> + The time this record was created. + </summary> + </member> + <member name="M:NDns.Message.Records.Record.#ctor"> + <summary> + Creates a new DNS record. + </summary> + </member> + <member name="P:NDns.Message.Records.Record.Type"> + <summary> + Returns the type for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.Record.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="P:NDns.Message.Records.Record.TTL"> + <summary> + Gets and sets the time to live for this record (in seconds). + </summary> + </member> + <member name="F:NDns.Message.Records.CNameRecord.cName"> + <summary> + The canonical name for this record. + </summary> + </member> + <member name="M:NDns.Message.Records.CNameRecord.#ctor(System.String)"> + <summary> + Creates a CName record from the given domain. + </summary> + <param name="cName">The string of the canonical name.</param> + </member> + <member name="M:NDns.Message.Records.CNameRecord.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a CName record from the given byte data. + </summary> + <param name="data">The data to create the CName record from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="P:NDns.Message.Records.CNameRecord.CName"> + <summary> + Returns the canonical name for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.CNameRecord.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="T:NDns.QueryFactory"> + <summary> + A factory class for creating DNS query and response messages. + </summary> + </member> + <member name="M:NDns.QueryFactory.CreateQuery(System.String,NDns.Message.QType)"> + <summary> + Creates a new DNS query to look up the record for the query string and type. + </summary> + <param name="queryString">The query string to pack.</param> + <param name="queryType">The type of the query.</param> + <returns>The DNS message.</returns> + </member> + <member name="T:NDns.Message.Records.PTRRecord"> + <summary> + A DNS PTR record. + </summary> + </member> + <member name="F:NDns.Message.Records.PTRRecord.name"> + <summary> + The name for this record. + </summary> + </member> + <member name="M:NDns.Message.Records.PTRRecord.#ctor(System.String)"> + <summary> + Creates a PTR record from the given domain. + </summary> + <param name="name">The string of the name.</param> + </member> + <member name="M:NDns.Message.Records.PTRRecord.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a PTR record from the given byte data. + </summary> + <param name="data">The data to create the CName record from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="P:NDns.Message.Records.PTRRecord.Name"> + <summary> + Returns the name for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.PTRRecord.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="T:NDns.DnsCache"> + <summary> + Provides a cache for DNS information. + </summary> + </member> + <member name="F:NDns.DnsCache.DnsPort"> + <summary> + The port to query remote dns servers on. + </summary> + </member> + <member name="F:NDns.DnsCache.log"> + <summary> + Logging support for this class. + </summary> + </member> + <member name="F:NDns.DnsCache.mxServers"> + <summary> + A hash table of arrays of MX records indexed by string name + (e.g. an array of MX records for "anu.edu.au"). + </summary> + </member> + <member name="F:NDns.DnsCache.mxQueue"> + <summary> + A list of MX records ordered according to last use. + </summary> + </member> + <member name="F:NDns.DnsCache.domains"> + <summary> + A hash table of string records indexed by IP address + </summary> + </member> + <member name="F:NDns.DnsCache.domainQueue"> + <summary> + A list of string records ordered according to last use. + </summary> + </member> + <member name="F:NDns.DnsCache.addresses"> + <summary> + A hash table of ip address record arrays indexed by string name + (e.g. an array of A records for "www.anu.edu.au"). + </summary> + </member> + <member name="F:NDns.DnsCache.addressQueue"> + <summary> + A list of address records ordered according to last use. + </summary> + </member> + <member name="F:NDns.DnsCache.MXCacheSize"> + <summary> + The maximum number of MX record arrays to store. + </summary> + </member> + <member name="F:NDns.DnsCache.DomainCacheSize"> + <summary> + The maximum number of string names to store. + </summary> + </member> + <member name="F:NDns.DnsCache.AddressCacheSize"> + <summary> + The maximum number of A record arrays to store. + </summary> + </member> + <member name="F:NDns.DnsCache.config"> + <summary> + The configuration for this DNS cache. + </summary> + </member> + <member name="M:NDns.DnsCache.#ctor(NDns.Configuration.NDnsConfiguration)"> + <summary> + Creates a new instance of the DNS this. + </summary> + </member> + <member name="M:NDns.DnsCache.DomainMatchesAddress(System.Net.IPAddress,System.String)"> + <summary> + Checks if the given string and address match. + </summary> + <param name="address">The address to check.</param> + <param name="domain">The string to check.</param> + <returns>True if the string corresponds to the address.</returns> + </member> + <member name="M:NDns.DnsCache.GetHostName(System.Net.EndPoint)"> + <summary> + Gets a hostname for the specified end point. + </summary> + <param name="endPoint">The end point to lookup</param> + <returns>The hostname.</returns> + </member> + <member name="M:NDns.DnsCache.GetHostName(System.Net.IPAddress)"> + <summary> + Gets a hostname for the specified address. + </summary> + <param name="address">The address to lookup</param> + <returns>The hostname.</returns> + </member> + <member name="M:NDns.DnsCache.GetHostNames(System.Net.IPAddress)"> + <summary> + Gets a hostnames for the specified address. + </summary> + <param name="address">The address to lookup</param> + <returns>The address.</returns> + </member> + <member name="M:NDns.DnsCache.GetIPAddress(System.String)"> + <summary> + Gets the first IP address associated with the given domain name. + </summary> + <param name="domainName">The domain name to resolve.</param> + <returns>The IP address.</returns> + </member> + <member name="M:NDns.DnsCache.GetIPAddresses(System.String)"> + <summary> + Looks up IP addresses for the given string name. + </summary> + <param name="domainName">The string name to lookup the addresses for.</param> + <returns>The IP addresses for the string name.</returns> + </member> + <member name="M:NDns.DnsCache.LookupRecords(System.String,NDns.Message.QType)"> + <summary> + Looks up DNS records using the specified query string and query type. + </summary> + <param name="queryString">The query to send.</param> + <param name="queryType">The query type.</param> + <returns>The array of records from the DNS server.</returns> + </member> + <member name="M:NDns.DnsCache.GetPTRRecords(System.Net.IPAddress)"> + <summary> + Gets the PTR records for the specified IP address caching the results. + This method also respects TTL for the records. + </summary> + <param name="address">The address to lookup</param> + <returns>The PTR records.</returns> + </member> + <member name="M:NDns.DnsCache.GetARecords(System.String)"> + <summary> + Gets address records for the specified hostname caching the results. + This method also respects TTL for the records. + </summary> + <param name="domainName">The hostname to lookup</param> + <returns>The address records.</returns> + </member> + <member name="M:NDns.DnsCache.GetMXRecords(System.String)"> + <summary> + Looks up MX records for the given string name caching the results. + This method also respects TTL for the records. + </summary> + <param name="domainName">The string to get the MX records for.</param> + <returns>The MX records</returns> + </member> + <member name="M:NDns.DnsCache.LookupMXRecords(System.String)"> + <summary> + Looks up MX records from the DNS server handling empty answer + sections but not caching records. + </summary> + <param name="domainName">The string to look up the MX records for.</param> + <returns>The MX records for the given domain.</returns> + </member> + <member name="M:NDns.DnsCache.LookupPTRRecords(System.Net.IPAddress)"> + <summary> + Looks up PTR records from the DNS server but does not cache records. + </summary> + <param name="address">The string to look up the PTR records for.</param> + <returns>The PTR records for the given domain.</returns> + </member> + <member name="M:NDns.DnsCache.LookupARecords(System.String)"> + <summary> + Looks up address records from the DNS server but does not cache records. + </summary> + <param name="domainName">The string name to lookup the addresses for.</param> + <returns>The addresses records for the given domain.</returns> + </member> + <member name="M:NDns.DnsCache.ConvertToIPAddresses(NDns.Message.Records.ARecord[])"> + <summary> + Converts an array of address records into an array of IP addresses. + </summary> + <param name="records">The records to convert.</param> + <returns>The IP addresses.</returns> + </member> + <member name="M:NDns.DnsCache.ConvertToHostnames(NDns.Message.Records.PTRRecord[])"> + <summary> + Converts an array of PTR records into an array of hostnames. + </summary> + <param name="records">The records to convert.</param> + <returns>The hostnames.</returns> + </member> + <member name="M:NDns.DnsCache.PerformQuery(NDns.Message.DNSMessage)"> + <summary> + Queries a DNS server using the given DNS query. + </summary> + <param name="queryMessage">The query to send to the server.</param> + <returns>The response from the server.</returns> + </member> + <member name="T:NDns.Message.ResponseCode"> + <summary> + The response code is a 4 bit field is set as part of responses. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.NoError"> + <summary> + No error condition. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.FormatError"> + <summary> + The name server was unable to interpret the query. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.ServerFailure"> + <summary> + The name server was unable to process this query due to a problem + with the name server. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.NameError"> + <summary> + Meaningful only for responses from an authoritative name server, + this code signifies that the string name referenced in the query + does not exist. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.NotImplemented"> + <summary> + The name server does not support the requested kind of query. + </summary> + </member> + <member name="F:NDns.Message.ResponseCode.Refused"> + <summary> + The name server refuses to perform the specified operation for + policy reasons. + </summary> + </member> + <member name="T:NDns.Message.Records.MXRecord"> + <summary> + A DNS Mail eXchanger record. + </summary> + </member> + <member name="F:NDns.Message.Records.MXRecord.preference"> + <summary> + The preference associated with this MX record. + </summary> + </member> + <member name="F:NDns.Message.Records.MXRecord.mxName"> + <summary> + The name of the MX server. + </summary> + </member> + <member name="M:NDns.Message.Records.MXRecord.#ctor(System.String,System.UInt16)"> + <summary> + Creates a MX record from the given string and preference. + </summary> + <param name="mxName">The string of the MX record.</param> + <param name="perference">The preference of the MX record.</param> + </member> + <member name="M:NDns.Message.Records.MXRecord.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a MX record from the given byte data. + </summary> + <param name="data">The data to create the MX record from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="M:NDns.Message.Records.MXRecord.CompareTo(System.Object)"> + <summary> + Compares this MX record to another MX record, sorting by perference. + </summary> + <param name="obj">The other MX to compare to.</param> + <returns>-1 if this MX is perferable, 1 otherwise.</returns> + </member> + <member name="P:NDns.Message.Records.MXRecord.MX"> + <summary> + Returns the MX string for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.MXRecord.Preference"> + <summary> + Returns the preference for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.MXRecord.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="T:NDns.Message.QType"> + <summary> + The DNS query type. + </summary> + </member> + <member name="F:NDns.Message.QType.A"> + <summary> + A host address. + </summary> + </member> + <member name="F:NDns.Message.QType.NS"> + <summary> + An authoritative name server. + </summary> + </member> + <member name="F:NDns.Message.QType.CNAME"> + <summary> + The canonical name for an alias. + </summary> + </member> + <member name="F:NDns.Message.QType.SOA"> + <summary> + Marks the start of a zone of authority. + </summary> + </member> + <member name="F:NDns.Message.QType.PTR"> + <summary> + A string name pointer. + </summary> + </member> + <member name="F:NDns.Message.QType.HINFO"> + <summary> + Host information. + </summary> + </member> + <member name="F:NDns.Message.QType.MINFO"> + <summary> + Mailbox or mail list information. + </summary> + </member> + <member name="F:NDns.Message.QType.MX"> + <summary> + Mail exchange. + </summary> + </member> + <member name="F:NDns.Message.QType.TXT"> + <summary> + Text strings. + </summary> + </member> + <member name="T:NDns.Configuration.NDnsConfiguration"> + <summary> + Provides configuration settings for this package. + </summary> + </member> + <member name="M:NDns.Configuration.NDnsConfiguration.#ctor(System.Net.IPAddress[],System.Int32,System.Int32,System.Int32)"> + <summary> + Creates a new NDns configuration from the arguments. + </summary> + <param name="dnsServers">The list of DNS servers to query (in order).</param> + <param name="maxMXCacheSize">The maximum number of MX records to the cache.</param> + <param name="maxDomainCacheSize">The maximum number of domain records to the cache.</param> + <param name="maxAddressCacheSize">The maximum number of address records to the cache.</param> + </member> + <member name="P:NDns.Configuration.NDnsConfiguration.DnsServers"> + <summary> + The list of DNS servers to query (in order of perference). + </summary> + </member> + <member name="P:NDns.Configuration.NDnsConfiguration.MaximumMXCacheSize"> + <summary> + Returns the maximum cache for MX records size in entries. + </summary> + </member> + <member name="P:NDns.Configuration.NDnsConfiguration.MaximumDomainCacheSize"> + <summary> + Returns the maximum cache for domain records size in entries. + </summary> + </member> + <member name="P:NDns.Configuration.NDnsConfiguration.MaximumAddressCacheSize"> + <summary> + Returns the maximum cache for address records size in entries. + </summary> + </member> + <member name="T:NDns.Message.Records.ARecord"> + <summary> + A DNS Address record. + </summary> + </member> + <member name="F:NDns.Message.Records.ARecord.address"> + <summary> + The address for this record. + </summary> + </member> + <member name="M:NDns.Message.Records.ARecord.#ctor(System.Net.IPAddress)"> + <summary> + Creates an address record using the address record. + </summary> + <param name="address">The address to create the record from.</param> + </member> + <member name="M:NDns.Message.Records.ARecord.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates an Address record from the given byte data. + </summary> + <param name="data">The data to create the Address record from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="P:NDns.Message.Records.ARecord.Address"> + <summary> + The address for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.ARecord.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="T:NDns.Message.Records.NSRecord"> + <summary> + A DNS NS record. + </summary> + </member> + <member name="F:NDns.Message.Records.NSRecord.ns"> + <summary> + The name server name for this record. + </summary> + </member> + <member name="M:NDns.Message.Records.NSRecord.#ctor(System.String)"> + <summary> + Creates a NS record from the given domain. + </summary> + <param name="ns">The string of the name server name.</param> + </member> + <member name="M:NDns.Message.Records.NSRecord.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a NS record from the given byte data. + </summary> + <param name="data">The data to create the CName record from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="P:NDns.Message.Records.NSRecord.NS"> + <summary> + Returns the name server name for this record. + </summary> + </member> + <member name="P:NDns.Message.Records.NSRecord.Data"> + <summary> + The data associated with this record as a user readable string. + </summary> + </member> + <member name="T:NDns.Message.OpCode"> + <summary> + The opcode is a four bit field that specifies query type in the message. + This value is set by the originator of a query and copied into the response. + </summary> + </member> + <member name="F:NDns.Message.OpCode.StandardQuery"> + <summary> + A standard query (QUERY). + </summary> + </member> + <member name="F:NDns.Message.OpCode.InverseQuery"> + <summary> + An inverse query (IQUERY). + </summary> + </member> + <member name="F:NDns.Message.OpCode.StatusRequest"> + <summary> + A server status request (STATUS). + </summary> + </member> + <member name="T:NDns.Message.DNSMessage"> + <summary> + A DNS message used in DNS communications. + </summary> + </member> + <member name="F:NDns.Message.DNSMessage.header"> + <summary> + The header for this DNS message. + </summary> + </member> + <member name="F:NDns.Message.DNSMessage.questionEntries"> + <summary> + The question sections associated with this DNS message. + </summary> + </member> + <member name="F:NDns.Message.DNSMessage.answerEntries"> + <summary> + The answer sections associated with the DNS message. + </summary> + </member> + <member name="M:NDns.Message.DNSMessage.#ctor"> + <summary> + Creates a new DNS message. + </summary> + </member> + <member name="M:NDns.Message.DNSMessage.#ctor(System.Byte[])"> + <summary> + Creates a new DNS message using the given data. This data is typically the + response from a DNS server. + </summary> + <param name="data">The data to create the message from.</param> + </member> + <member name="M:NDns.Message.DNSMessage.ToByteArray"> + <summary> + Converts the DNS message into a byte array. + </summary> + <returns>The DNS message as a byte array.</returns> + </member> + <member name="P:NDns.Message.DNSMessage.QuestionEntries"> + <summary> + Gets and sets the question section entries for this DNS message. + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.AnswerEntries"> + <summary> + Gets and sets the answer section entries for this DNS message. + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Id"> + <summary> + Gets the Id for this DNS message. + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Response"> + <summary> + Was this message a response or a query? + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Authoritative"> + <summary> + Is the answer authoritative? + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Truncated"> + <summary> + Was the message truncated due to size constraints? + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Recursive"> + <summary> + Is recursion desired? + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.RecursionAvailable"> + <summary> + Is recursion available? + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Opcode"> + <summary> + A four bit field that specifies query type in the message. + </summary> + </member> + <member name="P:NDns.Message.DNSMessage.Rcode"> + <summary> + The response code for this message. + </summary> + </member> + <member name="T:NDns.Message.QuestionSection"> + <summary> + A question section entry in a DNS message. + </summary> + </member> + <member name="F:NDns.Message.QuestionSection.queryName"> + <summary> + The string name being looked up. + </summary> + </member> + <member name="F:NDns.Message.QuestionSection.queryType"> + <summary> + The type of query being performed. + </summary> + </member> + <member name="F:NDns.Message.QuestionSection.queryClass"> + <summary> + The class of query. + </summary> + </member> + <member name="M:NDns.Message.QuestionSection.#ctor(System.String,NDns.Message.QType)"> + <summary> + Creates a new question section with the given string and type. + </summary> + <param name="queryName">The string to query.</param> + <param name="queryType">The type of query to perform.</param> + </member> + <member name="M:NDns.Message.QuestionSection.#ctor(System.Byte[],System.UInt16,System.UInt16@,NDns.Message.DomainCoder)"> + <summary> + Creates a question section from the given byte data. + </summary> + <param name="data">The data to create the question section from.</param> + <param name="start">The position to start reading the byte array from.</param> + <param name="length">The number of bytes read from the byte array.</param> + <param name="coder">The coder to use when parsing the data.</param> + </member> + <member name="M:NDns.Message.QuestionSection.ToByteArray(NDns.Message.DomainCoder,System.UInt16)"> + <summary> + Converts the question section into a byte array. + </summary> + <param name="coder">The string coder used to compress queries with.</param> + <param name="reference">A reference to the location of this entry in the message.</param> + <returns>The question section as a byte array.</returns> + </member> + <member name="T:NDns.Message.QClass"> + <summary> + The class of records. + </summary> + </member> + <member name="F:NDns.Message.QClass.IN"> + <summary> + The Internet. + </summary> + </member> + <member name="T:NDns.Message.DomainCoder"> + <summary> + This class encodes and decodes DNS string names in or for DNS messages. + </summary> + </member> + <member name="F:NDns.Message.DomainCoder.references"> + <summary> + A hash table of references indexed by string names. + </summary> + </member> + <member name="M:NDns.Message.DomainCoder.EncodeDomain(System.String,System.UInt16)"> + <summary> + Encodes a string entry or a reference to the string entry for the given + domain. + </summary> + <param name="domainName">The string to create the entry for.</param> + <param name="start">The reference to the start of this entry in the message.</param> + <returns>The string name or a reference to the first occurence.</returns> + </member> + <member name="M:NDns.Message.DomainCoder.DecodeDomain(System.Byte[],System.UInt16,System.UInt16@)"> + <summary> + Decodes the data to retrieve a string name. + </summary> + <param name="data">The data to process.</param> + <param name="start">The position to start processing from.</param> + <param name="length">The length of data read.</param> + <returns>The string decoded.</returns> + </member> </members> </doc> Added: NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/Envelope.cs 2006-07-01 08:36:49 UTC (rev 53) @@ -0,0 +1,361 @@ +/* + * 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> + /// A message envelope. This includes the From, To, Cc, Bcc, Subject + /// </summary> + [Serializable] + public class Envelope { + /// <summary> + /// Creates a new envelope from the message headers. + /// </summary> + /// <param name="messageHeaders">The headers containing the envelope information.</param> + public Envelope(MessageHeaders messageHeaders) { + // These fields should never be null + this.from = messageHeaders["From"]; + this.date = messageHeaders["Date"]; + this.subject = messageHeaders["Subject"]; + + this.sender = messageHeaders["Sender"]; + if (this.sender == null || this.sender.Trim() == string.Empty) { + this.sender = this.from; + } + this.replyTo = messageHeaders["Rely-To"]; + if (this.replyTo == null || this.replyTo.Trim() == string.Empty) { + this.replyTo = this.from; + } + + // These fields can be null + this.messageId = messageHeaders["Message-Id"]; + if (this.messageId != null && this.messageId.Trim() == string.Empty) { + this.messageId = null; + } + this.to = messageHeaders["To"]; + if (this.to != null && this.to.Trim() == string.Empty) { + this.to = null; + } + this.inReplyTo = messageHeaders["In-Reply-To"]; + if (this.inReplyTo != null && this.inReplyTo.Trim() == string.Empty) { + this.inReplyTo = null; + } + this.bcc = messageHeaders["Bcc"]; + if (this.bcc != null && this.inReplyTo.Trim() == string.Empty) { + this.bcc = null; + } + this.cc = messageHeaders["Cc"]; + if (this.cc != null && this.cc.Trim() == string.Empty) { + this.cc = null; + } + } + + /// <summary> + /// Creates a new envelope with the minimum required fields. + /// </summary> + /// <param name="from">The sender of the message.</param> + /// <param name="date">The date the message was sent.</param> + /// <param name="subject">The message's subject.</param> + public Envelope(string from, string date, string subject) { + this.from = from; + this.sender = from; + this.replyTo = from; + + this.subject = subject; + this.date = date; + } + + #region Properties + + private string messageId; + + /// <summary> + /// Extracted from the Message-Id header. + /// </summary> + public string MessageId { + get { + return this.messageId; + } + set { + this.messageId = value; + } + } + + private string from; + + /// <summary> + /// The value extracted from the From header field. + /// </summary> + public string From { + get { + return this.from; + } + set { + this.from = value; + } + } + + private string sender; + + /// <summary> + /// The value extracted from the Sender header field. + /// </summary> + public string Sender { + get { + return this.sender; + } + set { + this.sender = value; + } + } + + private string to; + + /// <summary> + /// The value extracted from the To header field. + /// </summary> + public string To { + get { + return this.to; + } + set { + this.to = value; + } + } + + + private string inReplyTo; + + /// <summary> + /// The value extracted from the In-Reply-To header field. + /// </summary> + public string InReplyTo { + get { + return this.inReplyTo; + } + set { + this.inReplyTo = value; + } + } + + + private string replyTo; + + /// <summary> + /// The value extracted from the Reply-To header field. + /// </summary> + public string ReplyTo { + get { + return this.replyTo; + } + set { + this.replyTo = value; + } + } + + + private string bcc; + + /// <summary> + /// The value extracted from the Bcc header field. + /// </summary> + public string Bcc { + get { + return this.bcc; + } + set { + this.bcc = value; + } + } + + + private string cc; + + /// <summary> + /// The value extracted from the Cc header field. + /// </summary> + public string Cc { + get { + return this.cc; + } + set { + this.cc = value; + } + } + + + private string subject; + + /// <summary> + /// The value extracted from the Subject header field. + /// </summary> + public string Subject { + get { + return this.subject; + } + set { + this.subject = value; + } + } + + + private string date; + + /// <summary> + /// The value extracted from the Date header field. + /// </summary> + public string Date { + get { + return this.date; + } + set { + this.date = value; + } + } + #endregion + + #region getEnvelopeImapAddress + private string getEnvelopeImapAddress(string data) { + // TODO: handle groups + + StringBuilder output = new StringBuilder(); + string[] addresses = StringTokenizer.GetQuotedTokens(data, ",".ToCharArray(), Int32.MaxValue, false); + + output.Append("("); + + foreach (string address in addresses) { + string[] tokens = StringTokenizer.GetQuotedTokens(address, " ".ToCharArray(), Int32.MaxValue, true); + string emailAddress = null; + string personalName = null; + string host = null; + string mailbox = null; + + if (tokens.Length > 0) { + if (tokens[0][0] != '<') { + personalName = tokens[0]; + + if (tokens.Length > 1) { + emailAddress = tokens[1]; + } + } else { + // No personal name + emailAddress = tokens[0]; + } + } + + if (emailAddress != null) { + try { + EmailAddress tmpAddress = new EmailAddress(emailAddress, true); + host = tmpAddress.Host.ToString(); + mailbox = tmpAddress.Mailbox.ToString(); + } catch { + } + } + + // Append the personal name and source route + if (personalName != null) { + output.Append("(\""); + output.Append(personalName); + output.Append("\" NIL "); + } else { + output.Append("(NIL NIL "); + } + + // Append the mailbox + if (mailbox != null) { + output.Append("\""); + output.Append(mailbox); + output.Append("\" "); + } else { + output.Append("NIL "); + } + + // Append the host + if (host != null) { + output.Append("\""); + output.Append(host); + output.Append("\")"); + } else { + output.Append("NIL)"); + } + } + + output.Append(")"); + + return output.ToString(); + } + #endregion + + #region ToImapEnvelopeString + /// <summary> + /// Converts this envelope into a string that can be used in an IMAP envelope + /// response. + /// </summary> + /// <returns>The IMAP envelope string.</returns> + public string ToImapEnvelopeString() { + StringBuilder envelope = new StringBuilder(); + + envelope.Append("ENVELOPE (\""); + envelope.Append(this.date); + envelope.Append("\" \""); + envelope.Append(this.subject); + envelope.Append("\" "); + + // From + envelope.Append(getEnvelopeImapAddress(this.from)); + envelope.Append(" "); + + // Sender + envelope.Append(getEnvelopeImapAddress(this.sender)); + envelope.Append(" "); + + // Reply-To + envelope.Append(getEnvelopeImapAddress(this.replyTo)); + envelope.Append(" "); + + // To + envelope.Append((this.to == null) ? "NIL" : getEnvelopeImapAddress(this.to)); + envelope.Append(" "); + + // Cc + envelope.Append((this.cc == null) ? "NIL" : getEnvelopeImapAddress(this.cc)); + envelope.Append(" "); + + // Bcc + envelope.Append((this.bcc == null) ? "NIL" : getEnvelopeImapAddress(this.bcc)); + envelope.Append(" "); + + // In-Reply-To + envelope.Append("\""); + envelope.Append((this.inReplyTo == null) ? "NIL" : this.inReplyTo); + envelope.Append("\" "); + + // Message-Id + envelope.Append("\""); + envelope.Append((this.messageId == null) ? "NIL" : this.messageId); + envelope.Append("\")"); + + return envelope.ToString(); + } + #endregion + } +} Modified: NMail/branches/luke-dev/NMail/DataTypes/Message.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Message.cs 2006-06-28 11:16:34 UTC (rev 52) +++ NMail/branches/luke-dev/NMail/DataTypes/Message.cs 2006-07-01 08:36:49 UTC (rev 53) @@ -60,6 +60,14 @@ this.data = bodyData; } + /// <summary> + /// Gets an envelope for this message. + /// </summary> + /// <returns>The envelope.</returns> + public Envelope GetEnvelope() { + return new Envelope(this.Headers); + } + private bool parsed { get { if (this.MultipartBody) { Modified: NMail/branches/luke-dev/NMail/ISpoolData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ISpoolData.cs 2006-06-28 11:16:34 UTC (rev 52) +++ NMail/branches/luke-dev/NMail/ISpoolData.cs 2006-07-01 08:36:49 UTC (rev 53) @@ -21,7 +21,7 @@ namespace NMail { /// <summary> - /// Stores the data for the spool. The implementors of this interface must be thread + /// Stores the data for the spool. The implementations of this interface must be thread /// safe. /// </summary> public interface ISpoolData { Modified: NMail/branches/luke-dev/NMail/NMail.csproj =================================================================== --- NMail/branches/luke-dev/NMail/NMail.csproj 2006-06-28 11:16:34 UTC (rev 52) +++ NMail/branches/luke-dev/NMail/NMail.csproj 2006-07-01 08:36:49 UTC (rev 53) @@ -129,6 +129,7 @@ <Compile Include="DataTypes\ACLs\StoreFolderAcl.cs" /> <Compile Include="DataTypes\ACLs\StoreFolderPrivilege.cs" /> <Compile Include="DataTypes\ACLs\UserGroupAdminPrivilege.cs" /> + <Compile Include="DataTypes\Envelope.cs" /> <Compile Include="DataTypes\LocalStoreGroup.cs" /> <Compile Include="DataTypes\ByteString.cs"> <SubType>Code</SubType> Added: NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx 2006-07-01 08:36:49 UTC (rev 53) @@ -0,0 +1,6 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="SpoolDetails.aspx.cs" Inherits="SpoolDetails" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="SiteContentPlaceHolder" Runat="Server"> +</asp:Content> +<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/SpoolDetails.aspx.cs 2006-07-01 08:36:49 UTC (rev 53) @@ -0,0 +1,20 @@ +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 SpoolDetails : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + NMail.Server.RemoteAdministration ra; + // ra.NMailServer.Services[0].Service + + } +} Modified: NMail/branches/luke-dev/NMail.ImapService/State/ExamineState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/ExamineState.cs 2006-06-28 11:16:34 UTC (rev 52) +++ NMail/branches/luke-dev/NMail.ImapService/State/ExamineState.cs 2006-07-01 08:36:49 UTC (rev 53) @@ -174,149 +174,10 @@ } #endregion - #region getEnvelopeAddress - protected virtual string getEnvelopeAddress(string headerData) { - // TODO: handle groups - - StringBuilder output = new StringBuilder(); - string[] addresses = StringTokenizer.GetQuotedTokens(headerData, ",".ToCharArray(), Int32.MaxValue, false); - - output.Append("("); - - foreach (string address in addresses) { - string[] tokens = StringTokenizer.GetQuotedTokens(address, " ".ToCharArray(), Int32.MaxValue, true); - string emailAddress = null; - string personalName = null; - string host = null; - string mailbox = null; - - if (tokens.Length > 0) { - if (tokens[0][0] != '<') { - personalName = tokens[0]; - - if (tokens.Length > 1) { - emailAddress = tokens[1]; - } - } else { - // No personal name - emailAddress = tokens[0]; - } - } - - if (emailAddress != null) { - try { - EmailAddress tmpAddress = new EmailAddress(emailAddress, true); - host = tmpAddress.Host.ToString(); - mailbox = tmpAddress.Mailbox.ToString(); - } catch { - } - } - - // Append the personal name and source route - if (personalName != null) { - output.Append("(\""); - output.Append(personalName); - output.Append("\" NIL "); - } else { - output.Append("(NIL NIL "); - } - - // Append the mailbox - if (mailbox != null) { - output.Append("\""); - output.Append(mailbox); - output.Append("\" "); - } else { - output.Append("NIL "); - } - - // Append the host - if (host != null) { - output.Append("\""); - output.Append(host); - output.Append("\")"); - } else { - output.Append("NIL)"); - } - } - - output.Append(")"); - - return output.ToString(); - } - #endregion - #region sendEnvelope protected virtual void sendEnvelope(FetchResponse response, MessageHeaders messageHeaders) { - StringBuilder envelope = new StringBuilder(); - - envelope.Append("ENVELOPE (\""); - envelope.Append(messageHeaders["Date"].Trim()); - envelope.Append("\" \""); - envelope.Append(messageHeaders["Subject"]); - envelope.Append("\" "); - - // From - envelope.Append(getEnvelopeAddress(messageHeaders["From"])); - envelope.Append(" "); - - // Sender - if (messageHeaders["Sender"] == null) { - envelope.Append(getEnvelopeAddress(messageHeaders["From"])); - } else { - envelope.Append(getEnvelopeAddress(messageHeaders["Sender"])); - } - envelope.Append(" "); - - // Reply-To - if (messageHeaders["Rely-To"] == null) { - envelope.Append(getEnvelopeAddress(messageHeaders["From"])); - } else { - envelope.Append(getEnvelopeAddress(messageHeaders["Rely-To"])); - } - envelope.Append(" "); - - // To - if (messageHeaders["To"] == null || messageHeaders["To"].Trim() == string.Empty) { - envelope.Append("NIL"); - } else { - envelope.Append(getEnvelopeAddress(messageHeaders["To"])); - } - envelope.Append(" "); - - // Cc - if (messageHeaders["Cc"] == null || messageHeaders["Cc"].Trim() == string.Empty) { - envelope.Append("NIL"); - } else { - envelope.Append(getEnvelopeAddress(messageHeaders["Cc"])); - } - envelope.Append(" "); - - // Bcc - if (messageHeaders["Bcc"] == null || messageHeaders["Bcc"].Trim() == string.Empty) { - envelope.Append("NIL"); - } else { - envelope.Append(getEnvelopeAddress(messageHeaders["Bcc"])); - } - envelope.Append(" "); - - // In-Reply-To - if (messageHeaders["In-Reply-To"] == null) { - envelope.Append("NIL"); - } else { - envelope.Append("\"" + messageHeaders["In-Reply-To"] + "\""); - } - envelope.Append(" "); - - // Message-Id - if (messageHeaders["Message-Id"] == null) { - envelope.Append("NIL"); - } else { - envelope.Append("\"" + messageHeaders["Message-Id"].Trim() + "\""); - } - envelope.Append(")"); - - response.AppendResponseItem(envelope.ToString()); + Envelope envelope = new Envelope(messageHeaders); + response.AppendResponseItem(envelope.ToImapEnvelopeString()); } #endregion Added: NMail/branches/luke-dev/NMail.PostInstall/NMail.PostInstall.csproj =================================================================== --- NMail/branches/luke-dev/NMail.PostInstall/NMail.PostInstall.csproj (rev 0) +++ NMail/branches/luke-dev/NMail.PostInstall/NMail.PostInstall.csproj 2006-07-01 08:36:49 UTC (rev 53) @@ -0,0 +1,88 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{906413B5-1C7D-4072-B5CF-FDCED1F6CA7C}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>NMail.PostInstall</RootNamespace> + <AssemblyName>NMail.PostInstall</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Deployment" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="PostInstallForm.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="PostInstallForm.Designer.cs"> + <DependentUpon>PostInstallForm.cs</DependentUpon> + </Compile> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <EmbeddedResource Include="PostInstallForm.resx"> + <SubType>Designer</SubType> + <DependentUpon>PostInstallForm.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </EmbeddedResource> + <Compile Include=... [truncated message content] |
|
From: <tmy...@us...> - 2006-06-28 11:17:06
|
Revision: 52 Author: tmyroadctfig Date: 2006-06-28 04:16:34 -0700 (Wed, 28 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=52&view=rev Log Message: ----------- Added task list and password setting via the admin webpage. Modified Paths: -------------- NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs NMail/branches/luke-dev/NMail/Authentication/NullAuthentication.cs NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx.cs NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx.cs Modified: NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs =================================================================== --- NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -73,6 +73,14 @@ /// <returns>True if their account is locked out.</returns> bool IsLockedOut(IAuthenticationToken user); + /// <summary> + /// Changes the user's password. + /// </summary> + /// <param name="user">The user to change the password for.</param> + /// <param name="newPassword">The new password.</param> + /// <returns>True on success, false otherwise.</returns> + bool ChangePassword(IAuthenticationToken user, string newPassword); + // TODO: reset password & others } } Modified: NMail/branches/luke-dev/NMail/Authentication/NullAuthentication.cs =================================================================== --- NMail/branches/luke-dev/NMail/Authentication/NullAuthentication.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail/Authentication/NullAuthentication.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -50,6 +50,10 @@ public bool IsLockedOut(IAuthenticationToken user) { return false; } + + public bool ChangePassword(IAuthenticationToken user, string newPassword) { + return true; + } #endregion } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -33,6 +33,7 @@ { e.Authenticated = true; Session["AuthToken"] = authToken; + Session["RemoteAdministration"] = ra; Session["LocalStore"] = ra.NMailServer.LocalStore; } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-06-28 11:16:34 UTC (rev 52) @@ -1,4 +1,4 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="Untitled Page" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="Mail Domain Details" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> Modified: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-28 11:16:34 UTC (rev 52) @@ -1,4 +1,5 @@ <%@ Master Language="C#" %> +<%@ Register Src="TaskList.ascx" TagName="TaskList" TagPrefix="uc1" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> @@ -62,6 +63,10 @@ </asp:TreeView> <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> </div> + + <uc1:TaskList ID="TaskList" runat="server" /> + <asp:ContentPlaceHolder ID="SiteContentPlaceHolder" runat="server"> + </asp:ContentPlaceHolder> </td> <td style="width: 100%; vertical-align: top;"> <div style="padding: 0.5em"> Added: NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx 2006-06-28 11:16:34 UTC (rev 52) @@ -0,0 +1,12 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SetPasswordPanel.ascx.cs" Inherits="SetPasswordPanel" %> +<div class="box"> + <h3>Set a new password</h3> + <asp:Image ID="StatusImg" runat="server" /> + <asp:Label ID="StatusMessageLbl" runat="server" /> + + New Password: + <input id="PasswordBox" type="password" runat="server" /> + <br /> + <asp:Button ID="OkBtn" runat="Server" Text="Set" OnClick="OkBtn_Click" /> + <asp:Button ID="CancelBtn" runat="Server" Text="Cancel" OnClick="CancelBtn_Click" /> +</div> \ No newline at end of file Added: NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/SetPasswordPanel.ascx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -0,0 +1,97 @@ +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 SetPasswordPanel : System.Web.UI.UserControl +{ + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + + this.OkBtn.Click += new EventHandler(OkBtn_Click); + this.CancelBtn.Click += new EventHandler(CancelBtn_Click); + } + + protected void OkBtn_Click(object sender, EventArgs e) + { + if (this.setClicked != null) + { + this.setClicked(this, e); + } + } + + protected void CancelBtn_Click(object sender, EventArgs e) + { + if (this.cancelClicked != null) + { + this.cancelClicked(this, e); + } + } + + private event EventHandler setClicked; + + public event EventHandler SetClicked + { + add + { + this.setClicked += value; + } + remove + { + this.setClicked -= value; + } + } + + private event EventHandler cancelClicked; + + public event EventHandler CancelClicked + { + add + { + this.cancelClicked += value; + } + remove + { + this.cancelClicked -= value; + } + } + + public string Password + { + get + { + return this.PasswordBox.Value; + } + } + + public string StatusMessage + { + get + { + return this.StatusMessageLbl.Text; + } + set + { + this.StatusMessageLbl.Text = value; + } + } + + public string StatusImageUrl + { + get + { + return this.StatusImg.ImageUrl; + } + set + { + this.StatusImg.ImageUrl = value; + } + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-28 11:16:34 UTC (rev 52) @@ -5,7 +5,7 @@ h1 { - font-size: larger; + font-size: large; } h2 @@ -15,6 +15,14 @@ margin-top: 1em; } +h3 +{ + font-style: italic; + font-size: medium; + margin-bottom: 0.25em; + margin-top: 0.5em; +} + .box { background-color: #eff3fb; Added: NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx 2006-06-28 11:16:34 UTC (rev 52) @@ -0,0 +1,15 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TaskList.ascx.cs" Inherits="TaskList" %> +<div class="box"> + <asp:Repeater ID="TaskRepeater" runat="server"> + <HeaderTemplate><ul></HeaderTemplate> + + <ItemTemplate> + <li> + <asp:Image runat="server" ID="Image" ImageUrl='<%# Eval("ImageUrl") %>' /> + <asp:LinkButton runat="server" ID="LinkButton" Text='<%# Eval("Text") %>' /> + </li> + </ItemTemplate> + + <FooterTemplate></ul></FooterTemplate> + </asp:Repeater> +</div> \ No newline at end of file Added: NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/TaskList.ascx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -0,0 +1,79 @@ +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 TaskList : System.Web.UI.UserControl +{ + protected override void OnInit(EventArgs e) + { + base.OnLoad(e); + this.TaskRepeater.ItemDataBound += new RepeaterItemEventHandler(TaskRepeater_ItemDataBound); + } + + void TaskRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + Control control = e.Item.FindControl("LinkButton"); + Task task = (Task)e.Item.DataItem; + + if (control != null && task != null && task.ClickHandler != null) + { + // Link this task's button with its click handler + LinkButton button = (LinkButton)control; + button.Click += task.ClickHandler; + } + } + + public void SetTaskList(ArrayList taskList) + { + RepeaterItemCollection dataSource = new RepeaterItemCollection(taskList); + this.TaskRepeater.DataSource = dataSource; + this.TaskRepeater.DataBind(); + } +} + +public class Task +{ + public Task(string text, string imageUrl, EventHandler clickHandler) + { + this.text = text; + this.imageUrl = imageUrl; + this.clickHandler = clickHandler; + } + + private string text; + + public string Text + { + get + { + return this.text; + } + } + + private string imageUrl; + + public string ImageUrl + { + get + { + return this.imageUrl; + } + } + + private EventHandler clickHandler; + + public EventHandler ClickHandler + { + get + { + return this.clickHandler; + } + } +} \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-28 11:16:34 UTC (rev 52) @@ -1,5 +1,9 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="Untitled Page" %> -<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + +<%@ Register Src="SetPasswordPanel.ascx" TagName="SetPasswordPanel" TagPrefix="uc1" %> +<%@ Reference Control="~/TaskList.ascx" %> + +<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> <asp:Label ID="StatusMessage" runat="server"></asp:Label> @@ -15,7 +19,7 @@ <asp:Panel ID="MainPanel" runat="server"> <h2>User Details</h2> <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="UserDetailsView_ItemDeleting"> + DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> <EditRowStyle BackColor="#2461BF" /> @@ -27,7 +31,6 @@ <asp:BoundField DataField="UserFolderId" HeaderText="User Initial Folder Id" SortExpression="UserFolderId" /> <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Quota Warn Limit" SortExpression="QuotaWarnLimit" /> <asp:BoundField DataField="QuotaHardLimit" HeaderText="Quota Hard Limit" SortExpression="QuotaHardLimit" /> - <asp:CommandField ShowDeleteButton="True" /> </Fields> <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> @@ -42,7 +45,7 @@ <asp:Parameter Name="userId" Type="Int32" /> </DeleteParameters> </asp:ObjectDataSource> - + <h2>User's Folders</h2> <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> @@ -73,4 +76,7 @@ </asp:ObjectDataSource> </asp:Panel> </asp:Content> +<asp:Content ID="SiteContent" runat="server" ContentPlaceHolderID="SiteContentPlaceHolder"> + <uc1:SetPasswordPanel ID="SetPasswordPanel" runat="server" Visible="false" /> +</asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -10,9 +10,30 @@ using System.Web.UI.HtmlControls; using NMail; +using NMail.Authentication; +using NMail.Server; public partial class UserDetails : System.Web.UI.Page { + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Setup the task list + ArrayList tasks = new ArrayList(); + tasks.Add(new Task("Delete User", Request.ApplicationPath + @"/Images/Tango/Delete.png", new EventHandler(DeleteUser_Click))); + tasks.Add(new Task("Set Password", string.Empty, new EventHandler(ShowPasswordChanger_Click))); + + TaskList taskList = (TaskList) this.Master.FindControl("TaskList"); + taskList.SetTaskList(tasks); + + // Setup the password changer + this.SetPasswordPanel.CancelClicked += new EventHandler(SetPasswordPanel_CancelClicked); + this.SetPasswordPanel.SetClicked += new EventHandler(SetPasswordPanel_SetClicked); + } + + #region User Deletion + protected void UserDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) { e.InputParameters["userId"] = Request.QueryString["UserId"]; @@ -46,6 +67,12 @@ this.StatusImage.Visible = true; } + + protected void DeleteUser_Click(object sender, EventArgs e) + { + // Display the confirmation panel and canel the event + this.ConfirmPanel.Visible = true; + } protected void noBtn_Click(object sender, EventArgs e) { @@ -59,11 +86,41 @@ this.UserDataSource.Delete(); this.ConfirmPanel.Visible = false; } + #endregion - protected void UserDetailsView_ItemDeleting(object sender, DetailsViewDeleteEventArgs e) + #region Password Related Events + + protected void ShowPasswordChanger_Click(object sender, EventArgs e) { - // Display the confirmation panel and canel the event - this.ConfirmPanel.Visible = true; - e.Cancel = true; + this.SetPasswordPanel.Visible = true; } + + void SetPasswordPanel_CancelClicked(object sender, EventArgs e) + { + this.SetPasswordPanel.Visible = false; + } + + void SetPasswordPanel_SetClicked(object sender, EventArgs e) + { + RemoteAdministration ra = (RemoteAdministration)Session["RemoteAdministration"]; + IAuthenticationToken authToken = (IAuthenticationToken)Session["AuthToken"]; + IAuthenticationProvider authProvider = ra.NMailServer.AuthenticationProvider; + string password = this.SetPasswordPanel.Password; + + // Attempt to set the password + bool result = authProvider.ChangePassword(authToken, password); + + // Display the result + if (result) + { + this.SetPasswordPanel.StatusMessage = "Password changed successfully.<br /><br />"; + this.SetPasswordPanel.StatusImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; + } + else + { + this.SetPasswordPanel.StatusMessage = "Failed to set password for the user.<br /><br />"; + this.SetPasswordPanel.StatusImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + } + } + #endregion } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-28 11:16:34 UTC (rev 52) @@ -1,4 +1,4 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="Untitled Page" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="Folders" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <h2>Folders</h2> <asp:GridView ID="FoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" @@ -25,7 +25,5 @@ </asp:GridView> <asp:ObjectDataSource ID="FoldersDataSource" runat="server" SelectMethod="GetFolders" TypeName="NMail.Administration.Web.FolderDataSource"></asp:ObjectDataSource> - <br /> - <a href="CreateFolder.aspx">Create new folder</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -10,5 +10,21 @@ using System.Web.UI.HtmlControls; public partial class ViewFolders : System.Web.UI.Page -{ +{ + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Setup the task list + ArrayList tasks = new ArrayList(); + tasks.Add(new Task("Create Folder", string.Empty, new EventHandler(CreateFolder_Click))); + + TaskList taskList = (TaskList)this.Master.FindControl("TaskList"); + taskList.SetTaskList(tasks); + } + + protected void CreateFolder_Click(object sender, EventArgs e) + { + Response.Redirect("CreateFolder.aspx"); + } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-28 11:16:34 UTC (rev 52) @@ -1,4 +1,4 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Untitled Page" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Mail Domains" %> <asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <h2>Mail Domains</h2> <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource"> @@ -22,7 +22,5 @@ There are no mail domains currently defined in the system. </EmptyDataTemplate> </asp:GridView> - <br /> - <a href="CreateMailDomain.aspx">Create new mail domain</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -16,4 +16,20 @@ public partial class ViewMailDomains : System.Web.UI.Page { + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Setup the task list + ArrayList tasks = new ArrayList(); + tasks.Add(new Task("Create Mail Domain", string.Empty, new EventHandler(CreateMailDomain_Click))); + + TaskList taskList = (TaskList)this.Master.FindControl("TaskList"); + taskList.SetTaskList(tasks); + } + + protected void CreateMailDomain_Click(object sender, EventArgs e) + { + Response.Redirect("CreateMailDomain.aspx"); + } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-28 11:16:34 UTC (rev 52) @@ -1,5 +1,24 @@ -<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %> +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Users" %> +<script runat="server"> + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Setup the task list + ArrayList tasks = new ArrayList(); + tasks.Add(new Task("Create New User", string.Empty, new EventHandler(CreateUser_Click))); + + TaskList taskList = (TaskList)this.Master.FindControl("TaskList"); + taskList.SetTaskList(tasks); + } + + protected void CreateUser_Click(object sender, EventArgs e) + { + Response.Redirect("CreateUser.aspx"); + } +</script> + <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <h2>Users</h2> <asp:GridView ID="GridView1" runat="server" DataSourceID="UserDataSource" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> @@ -24,7 +43,5 @@ </asp:GridView> <asp:ObjectDataSource ID="UserDataSource" runat="server" SelectMethod="GetUsers" TypeName="NMail.Administration.Web.UserDataSource"></asp:ObjectDataSource> - <br /> - <a href="CreateUser.aspx">Create new user</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -1874,6 +1874,19 @@ // TODO: fix this! return false; } + + public bool ChangePassword(IAuthenticationToken user, string newPassword) { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandText = "UPDATE `User` SET Password = ?Password WHERE Username = ?Username"; + cmd.Parameters.Add("Username", user.Username); + cmd.Parameters.Add("Password", newPassword); + int count = cmd.ExecuteNonQuery(); + + return (count == 1); + } + } + } #endregion #region IHashAuthProvider Members Modified: NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs =================================================================== --- NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs 2006-06-24 11:21:25 UTC (rev 51) +++ NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs 2006-06-28 11:16:34 UTC (rev 52) @@ -21,6 +21,7 @@ using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; +using System.Runtime.Remoting.Lifetime; using System.Runtime.Serialization.Formatters; using System.Security.Cryptography.X509Certificates; @@ -69,21 +70,37 @@ // Setup the remoting channel IDictionary props = new Hashtable(); props["port"] = "7877"; -// props["isServer"] = "yes"; -// props["certificate"] = new X509Certificate2("NMail.pfx", ""); -// props["authProvider"] = NMailConfiguration.Current.AuthenticationProvider; -//#if DEBUG -// props["useTls"] = false; -//#endif channel = new TcpChannel(props, null, provider); ChannelServices.RegisterChannel(channel, false); // Register our remote administration interface RemoteAdministration ra = new RemoteAdministration(); ra.NMailServer = server; - RemotingServices.Marshal(ra, "RemoteAdministration.rem", typeof(RemoteAdministration)); + ObjRef obj = RemotingServices.Marshal(ra, "RemoteAdministration.rem", typeof(RemoteAdministration)); + // Register a sponsor for this remote admin interface to keep it alive + ILease lease = (ILease) RemotingServices.GetLifetimeService(ra); + remoteAdminSponsor = new RemoteAdminSponsor(); + lease.Register(remoteAdminSponsor); + return ra; } + + /// <summary> + /// A helper object used to keep the remote admin interface alive. + /// </summary> + private static RemoteAdminSponsor remoteAdminSponsor; } + + /// <summary> + /// A simple helper class used to keep the remote admin interface alive. + /// </summary> + internal class RemoteAdminSponsor : ISponsor { + #region ISponsor Members + + public TimeSpan Renewal(ILease lease) { + return TimeSpan.FromHours(24); + } + #endregion + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-24 11:21:36
|
Revision: 51 Author: tmyroadctfig Date: 2006-06-24 04:21:25 -0700 (Sat, 24 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=51&view=rev Log Message: ----------- Fixed installer for the ASP.net pages. Modified Paths: -------------- NMail/branches/luke-dev/Installer/NMail-Installer.wxs NMail/branches/luke-dev/NMail.build Modified: NMail/branches/luke-dev/Installer/NMail-Installer.wxs =================================================================== --- NMail/branches/luke-dev/Installer/NMail-Installer.wxs 2006-06-23 11:13:31 UTC (rev 50) +++ NMail/branches/luke-dev/Installer/NMail-Installer.wxs 2006-06-24 11:21:25 UTC (rev 51) @@ -130,29 +130,23 @@ </Component> <Directory Id="directory1" Name="bin"> <Component Id="component16" DiskId="1" Guid="F1DDFAF8-BB62-45d2-BEAA-CCF24A85B6AE"> - <File Id="file16" Name="APP_CO_1.COM" LongName="App_Code.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Code.compiled" /> - </Component> - <Component Id="component17" DiskId="1" Guid="F1DDFAF8-BB62-45d2-BEAA-CCF24A85B6AE"> - <File Id="file17" Name="App_Code.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Code.dll" /> - </Component> - <Component Id="component18" DiskId="1" Guid="6F2A42EB-D5EC-4389-B2FC-EB7021DC9F76"> - <File Id="file18" Name="APP_GL_1.COM" LongName="App_global.asax.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_global.asax.compiled" /> - </Component> - <Component Id="component19" DiskId="1" Guid="3B5D79E0-0E7E-44b2-B2D4-E7B380611008"> - <File Id="file19" Name="APP_GL_1.DLL" LongName="App_global.asax.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_global.asax.dll" /> - </Component> - <Component Id="component20" DiskId="1" Guid="9402A5D4-F663-4b13-A4A2-5BD3F5524F3A"> - <File Id="file20" Name="APP_WE_1.DLL" LongName="App_Web_o0selcem.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Web_o0selcem.dll" /> - </Component> - <Component Id="component21" DiskId="1" Guid="418989CB-19E6-4a60-AC5B-150528CDC66E"> - <File Id="file21" Name="log4net.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\log4net.dll" /> - </Component> - <Component Id="component22" DiskId="1" Guid="CAB5235F-B298-4fba-AE24-EFB8A9EF95FB"> - <File Id="file22" Name="NMail.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\NMail.dll" /> - </Component> - <Component Id="component23" DiskId="1" Guid="B6191132-3778-4db7-A9B7-BEFA10DAB79B"> - <File Id="file23" Name="NMAILS_1.DLL" LongName="NMail.Server.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\NMail.Server.dll" /> - </Component> + <File Id="file40" Name="APP_CO_1.COM" LongName="App_Code.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Code.compiled" /> + <File Id="file41" Name="App_Code.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Code.dll" /> + <File Id="file42" Name="APP_GL_1.COM" LongName="App_global.asax.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_global.asax.compiled" /> + <File Id="file43" Name="APP_GL_1.DLL" LongName="App_global.asax.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_global.asax.dll" /> + <File Id="file44" Name="APAF9A_1.DLL" LongName="App_Web_createfolder.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createfolder.aspx.cdcab7d2.dll" /> + <File Id="file45" Name="APP_WE_4.DLL" LongName="App_Web_createmaildomain.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createmaildomain.aspx.cdcab7d2.dll" /> + <File Id="file46" Name="AP65FC_1.DLL" LongName="App_Web_createuser.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_createuser.aspx.cdcab7d2.dll" /> + <File Id="file47" Name="APD8FB_1.DLL" LongName="App_Web_folderdetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_folderdetails.aspx.cdcab7d2.dll" /> + <File Id="file48" Name="APP_WE_3.DLL" LongName="App_Web_login.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_login.aspx.cdcab7d2.dll" /> + <File Id="file49" Name="APEDBC_1.DLL" LongName="App_Web_maildomaindetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_maildomaindetails.aspx.cdcab7d2.dll" /> + <File Id="file50" Name="AP71CE_1.DLL" LongName="App_Web_userdetails.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_userdetails.aspx.cdcab7d2.dll" /> + <File Id="file51" Name="APP_WE_2.DLL" LongName="App_Web_viewfolders.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_viewfolders.aspx.cdcab7d2.dll" /> + <File Id="file52" Name="APP_WE_1.DLL" LongName="App_Web_viewmaildomains.aspx.cdcab7d2.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\App_Web_viewmaildomains.aspx.cdcab7d2.dll" /> + <File Id="file53" Name="log4net.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\log4net.dll" /> + <File Id="file54" Name="NMail.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\NMail.dll" /> + <File Id="file55" Name="NMAILS_1.DLL" LongName="NMail.Server.dll" Checksum="yes" Compressed="yes" Vital="yes" src="C:\Documents and Settings\Luke\Desktop\NMail-trunk\branches\luke-dev\Installer\obj\NMail.Administration.Web.Compiled\bin\NMail.Server.dll" /> + </Component> </Directory> <Directory Id="directory2" Name="Images"> <Component Id="component24" DiskId="1" Guid="4FDC7813-EFB1-4d67-AAE1-059F12D28124"> @@ -417,13 +411,6 @@ <ComponentRef Id="component14"/> <ComponentRef Id="component15"/> <ComponentRef Id="component16"/> - <ComponentRef Id="component17"/> - <ComponentRef Id="component18"/> - <ComponentRef Id="component19"/> - <ComponentRef Id="component20"/> - <ComponentRef Id="component21"/> - <ComponentRef Id="component22"/> - <ComponentRef Id="component23"/> <ComponentRef Id="component24"/> <ComponentRef Id="component25"/> <ComponentRef Id="component26"/> Modified: NMail/branches/luke-dev/NMail.build =================================================================== --- NMail/branches/luke-dev/NMail.build 2006-06-23 11:13:31 UTC (rev 50) +++ NMail/branches/luke-dev/NMail.build 2006-06-24 11:21:25 UTC (rev 51) @@ -222,6 +222,7 @@ <arg value="-f" /> <arg><path><pathelement file="NMail.Administration.Web.Compiled" /></path></arg> <arg value="-errorstack" /> + <arg value="-fixednames" /> </exec> </target> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-23 11:14:06
|
Revision: 50 Author: tmyroadctfig Date: 2006-06-23 04:13:31 -0700 (Fri, 23 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=50&view=rev Log Message: ----------- Further work on installer. Modified Paths: -------------- NMail/branches/luke-dev/Installer/NMail-Installer.wxs NMail/branches/luke-dev/Installer/NMail-installer.build NMail/branches/luke-dev/NMail.build Added Paths: ----------- NMail/branches/luke-dev/Installer/WixLib/sca.wixlib NMail/branches/luke-dev/Installer/WixLib/scaexec.dll NMail/branches/luke-dev/Installer/WixLib/scasched.dll NMail/branches/luke-dev/Installer/WixLib/wixui_featuretree.wixlib Removed Paths: ------------- NMail/branches/luke-dev/Installer/WixLib/wixui_minimal.wixlib Property Changed: ---------------- NMail/branches/luke-dev/ NMail/branches/luke-dev/NMail.Administration.Web/Bin/ Property changes on: NMail/branches/luke-dev ___________________________________________________________________ Name: svn:ignore - NMail.suo NMail.Administration.Web.suo + NMail.suo NMail.Administration.Web.suo NMail.Administration.Web.Compiled Modified: NMail/branches/luke-dev/Installer/NMail-Installer.wxs =================================================================== --- NMail/branches/luke-dev/Installer/NMail-Installer.wxs 2006-06-23 11:10:20 UTC (rev 49) +++ NMail/branches/luke-dev/Installer/NMail-Installer.wxs 2006-06-23 11:13:31 UTC (rev 50) @@ -3,7 +3,7 @@ <Product Id="3EEDBE2D-3E7A-44b1-B4AA-1DDD2EB0068E" UpgradeCode="01CC30D2-B022-4e6c-A63B-7DD7ACCCCCE2" - Name="NMail Server" + Name="NMail Server 1.0" Language="1033" Version="1.0.0.0" Manufacturer="NMailServer.SourceForge.net"> @@ -72,7 +72,139 @@ <!-- Account="NetworkService" --> </Component> + + <!-- + == + == Webpage + == + --> + + <Directory Id="D_NMail.Administration.Web" Name="NMAILA_1.COM" LongName="NMail.Administration.Web"> + <Component Id="component0" DiskId="1" Guid="1BC3A682-453C-4a9d-8505-C683C88B18EC"> + <File Id="file0" Name="CREATE_1.ASP" LongName="CreateFolder.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateFolder.aspx" /> + </Component> + <Component Id="component1" DiskId="1" Guid="58B1F639-1053-425a-9C3E-8C474766C8AA"> + <File Id="file1" Name="CREATE_2.ASP" LongName="CreateMailDomain.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateMailDomain.aspx" /> + </Component> + <Component Id="component2" DiskId="1" Guid="62FF02F4-8B59-42d0-88A0-A1B6D9D3CB7B"> + <File Id="file2" Name="CREATE_3.ASP" LongName="CreateUser.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\CreateUser.aspx" /> + </Component> + <Component Id="component3" DiskId="1" Guid="3D8F8DB0-EEF4-4a18-8C5E-877C81FA2DC9"> + <File Id="file3" Name="DEFAUL_1.ASP" LongName="Default.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Default.aspx" /> + </Component> + <Component Id="component4" DiskId="1" Guid="F373F057-4FD0-42a1-965B-D128A78D2417"> + <File Id="file4" Name="FOLDER_1.ASP" LongName="FolderDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\FolderDetails.aspx" /> + </Component> + <Component Id="component5" DiskId="1" Guid="E09BDDD2-672E-4c51-8113-EF0204DAF0CC"> + <File Id="file5" Name="LOGIN_1.ASP" LongName="Login.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Login.aspx" /> + </Component> + <Component Id="component6" DiskId="1" Guid="DB8F981C-974F-4e6b-A783-7D69B22AD4ED"> + <File Id="file6" Name="MAILDO_1.ASP" LongName="MailDomainDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\MailDomainDetails.aspx" /> + </Component> + <Component Id="component7" DiskId="1" Guid="F1329BF3-66A9-45cb-B278-D0DD59A1E0E2"> + <File Id="file7" Name="MASTER_1.MAS" LongName="MasterPage.master" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\MasterPage.master" /> + </Component> + <Component Id="component8" DiskId="1" Guid="A57703A5-14A6-4a50-8677-793088C9D110"> + <File Id="file8" Name="PRECOM_1.CON" LongName="PrecompiledApp.config" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\PrecompiledApp.config" /> + </Component> + <Component Id="component9" DiskId="1" Guid="0A419E0E-4A82-4d97-AB36-AFBB1829F9EC"> + <File Id="file9" Name="STYLES_1.CSS" LongName="StyleSheet.css" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\StyleSheet.css" /> + </Component> + <Component Id="component10" DiskId="1" Guid="901C7F89-7965-4f37-A42A-47F9EB1607FB"> + <File Id="file10" Name="USERDE_1.ASP" LongName="UserDetails.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\UserDetails.aspx" /> + </Component> + <Component Id="component11" DiskId="1" Guid="0FBFBD37-7C67-42b5-BDD3-129960FB366B"> + <File Id="file11" Name="VIEWFO_1.ASP" LongName="ViewFolders.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewFolders.aspx" /> + </Component> + <Component Id="component12" DiskId="1" Guid="C54A6CB9-71E1-45e8-8E1A-B88CA863EF4B"> + <File Id="file12" Name="VIEWMA_1.ASP" LongName="ViewMailDomains.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewMailDomains.aspx" /> + </Component> + <Component Id="component13" DiskId="1" Guid="C936C25B-CCCB-436d-87CE-A1D54E10707E"> + <File Id="file13" Name="VIEWUS_1.ASP" LongName="ViewUsers.aspx" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\ViewUsers.aspx" /> + </Component> + <Component Id="component14" DiskId="1" Guid="837D56B3-D38C-4331-A681-27E8E11AA9F4"> + <File Id="file14" Name="WEB_1.CON" LongName="web.config" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\web.config" /> + </Component> + <Component Id="component15" DiskId="1" Guid="3E8F5756-8B2B-44dc-BCAB-CDBA16EF695E"> + <File Id="file15" Name="WEB_1.SIT" LongName="Web.sitemap" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Web.sitemap" /> + </Component> + <Directory Id="directory1" Name="bin"> + <Component Id="component16" DiskId="1" Guid="F1DDFAF8-BB62-45d2-BEAA-CCF24A85B6AE"> + <File Id="file16" Name="APP_CO_1.COM" LongName="App_Code.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Code.compiled" /> + </Component> + <Component Id="component17" DiskId="1" Guid="F1DDFAF8-BB62-45d2-BEAA-CCF24A85B6AE"> + <File Id="file17" Name="App_Code.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Code.dll" /> + </Component> + <Component Id="component18" DiskId="1" Guid="6F2A42EB-D5EC-4389-B2FC-EB7021DC9F76"> + <File Id="file18" Name="APP_GL_1.COM" LongName="App_global.asax.compiled" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_global.asax.compiled" /> + </Component> + <Component Id="component19" DiskId="1" Guid="3B5D79E0-0E7E-44b2-B2D4-E7B380611008"> + <File Id="file19" Name="APP_GL_1.DLL" LongName="App_global.asax.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_global.asax.dll" /> + </Component> + <Component Id="component20" DiskId="1" Guid="9402A5D4-F663-4b13-A4A2-5BD3F5524F3A"> + <File Id="file20" Name="APP_WE_1.DLL" LongName="App_Web_o0selcem.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\App_Web_o0selcem.dll" /> + </Component> + <Component Id="component21" DiskId="1" Guid="418989CB-19E6-4a60-AC5B-150528CDC66E"> + <File Id="file21" Name="log4net.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\log4net.dll" /> + </Component> + <Component Id="component22" DiskId="1" Guid="CAB5235F-B298-4fba-AE24-EFB8A9EF95FB"> + <File Id="file22" Name="NMail.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\NMail.dll" /> + </Component> + <Component Id="component23" DiskId="1" Guid="B6191132-3778-4db7-A9B7-BEFA10DAB79B"> + <File Id="file23" Name="NMAILS_1.DLL" LongName="NMail.Server.dll" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\bin\NMail.Server.dll" /> + </Component> + </Directory> + <Directory Id="directory2" Name="Images"> + <Component Id="component24" DiskId="1" Guid="4FDC7813-EFB1-4d67-AAE1-059F12D28124"> + <File Id="file24" Name="GREENL_1.PNG" LongName="GreenLight.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\GreenLight.png" /> + </Component> + <Component Id="component25" DiskId="1" Guid="36A40106-5C2D-4a8e-860C-810B80017A14"> + <File Id="file25" Name="NMAIL-_2.PNG" LongName="nmail-logo-white.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\nmail-logo-white.png" /> + </Component> + <Component Id="component26" DiskId="1" Guid="630CCA29-88EF-4822-A66B-4DD007B303FE"> + <File Id="file26" Name="NMAIL-_1.PNG" LongName="nmail-logo.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\nmail-logo.png" /> + </Component> + <Directory Id="directory3" Name="Tango"> + <Component Id="component27" DiskId="1" Guid="429427BF-BDD7-4580-9A4B-9F81A86C50CF"> + <File Id="file27" Name="Delete.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Delete.png" /> + </Component> + <Component Id="component28" DiskId="1" Guid="DD3F20E9-0F8F-4886-A12A-B87CDF0825ED"> + <File Id="file28" Name="Error.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Error.png" /> + </Component> + <Component Id="component29" DiskId="1" Guid="B80FA867-3CAB-4738-92BB-940A03DF037F"> + <File Id="file29" Name="Group.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Group.png" /> + </Component> + <Component Id="component30" DiskId="1" Guid="DFBFF8C5-B46F-429f-BDAB-23E8C52A70B6"> + <File Id="file30" Name="License.txt" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\License.txt" /> + </Component> + <Component Id="component31" DiskId="1" Guid="685A6306-9351-4b13-9CCC-6A003EF84066"> + <File Id="file31" Name="MAILDO_1.PNG" LongName="MailDomain.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\MailDomain.png" /> + </Component> + <Component Id="component32" DiskId="1" Guid="E4843991-0C95-4a91-94C8-42B012558CFF"> + <File Id="file32" Name="NEWFOL_1.PNG" LongName="NewFolder.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\NewFolder.png" /> + </Component> + <Component Id="component33" DiskId="1" Guid="11E1F4EC-00EE-4f75-9870-2125D5721A18"> + <File Id="file33" Name="OPENFO_1.PNG" LongName="OpenFolder.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\OpenFolder.png" /> + </Component> + <Component Id="component34" DiskId="1" Guid="EFFE59E3-03A6-4b0c-B95A-C2AF83DBFCC8"> + <File Id="file34" Name="Question.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Question.png" /> + </Component> + <Component Id="component35" DiskId="1" Guid="EFFA585C-6A2A-43cb-B14B-2BE9D6110C18"> + <File Id="file35" Name="User.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\User.png" /> + </Component> + <Component Id="component36" DiskId="1" Guid="E7A5CA36-4DAB-40c6-A7D0-B24249DCFFCC"> + <File Id="file36" Name="Warning.png" Checksum="yes" Compressed="yes" Vital="yes" src="obj\NMail.Administration.Web.Compiled\Images\Tango\Warning.png" /> + </Component> + </Directory> + </Directory> + </Directory> + <Component Id="C_VirtualWebDir" Guid="45A1A00F-7CAB-462f-A361-18566149FEBF"> + <WebVirtualDir Id="WebVirtualDir" Alias="NMailAdmin" Directory="D_NMail.Administration.Web" WebSite="DefaultWebSite"> + <WebApplication Id="WebApplication" Name="NMailAdmin" /> + </WebVirtualDir> + </Component> + <!-- == == Core DLLs @@ -170,7 +302,7 @@ </Component> <Component Id="C_NMail.config" Guid="FEB536D0-BB1A-47b9-9C1C-0142A210DD72"> - <File Id="NMail.config" Name="NMail.cfg" LongName="NMail.config" DiskId="1" Source="obj\NMail.config" Vital="yes" /> + <File Id="NMail.config" Name="NMail.cfg" LongName="NMail.config.Sample" DiskId="1" Source="obj\NMail.config" Vital="yes" /> </Component> <Component Id="C_NMail.pfx" Guid="93D43655-6B2D-4539-850E-9063F20B0E69"> @@ -210,45 +342,109 @@ </Directory> <Directory Id="DesktopFolder" Name="Desktop" /> - </Directory> - - <Feature Id="MainFeature" Title="Complete" Level="1"> - <!-- Core EXEs --> - <ComponentRef Id="C_NMail.Server.Console.exe" /> - <ComponentRef Id="C_NMail.Administration.Console.exe" /> - <ComponentRef Id="C_NMail.Server.Service.exe" /> + </Directory> + <WebSite Id="DefaultWebSite" Description="Default Web Site"> + <WebAddress Id="AllUnassigned" Port="443" Secure="yes"/> + </WebSite> + + <Feature Id="F_Base" Absent="disallow" Title="NMail" Level="1" + ConfigurableDirectory="INSTALLDIR" Display="expand" + Description="The components required in a NMail installation."> + <!-- Core DLLs --> - <ComponentRef Id="C_MonoPrivileges.dll" /> - <ComponentRef Id="C_NDns.dll" /> <ComponentRef Id="C_NMail.dll" /> - <ComponentRef Id="C_NMail.DnsClient.dll" /> - <ComponentRef Id="C_NMail.ImapService.dll" /> - <ComponentRef Id="C_NMail.LocalStore.dll" /> - <ComponentRef Id="C_NMail.LocalStoreData.MySql.dll" /> - <ComponentRef Id="C_NMail.MessageRouter.dll" /> <ComponentRef Id="C_NMail.Server.dll" /> - <ComponentRef Id="C_NMail.SmtpClient.dll" /> - <ComponentRef Id="C_NMail.SmtpService.dll" /> - <ComponentRef Id="C_NMail.SpoolData.MySql.dll" /> - <ComponentRef Id="C_NMail.SpoolFilter.dll" /> - <ComponentRef Id="C_NMail.SpoolFilter.RegexAddressRewriter.dll" /> - <ComponentRef Id="C_NMail.SpoolService.dll" /> - <!-- Non-NMail core DLLs --> + <!-- Non-NMail DLLs --> <ComponentRef Id="C_log4net.dll" /> - <ComponentRef Id="C_Mono.Security.dll" /> + + <Feature Id="F_Server" Display="expand" Title="NMail Server" Level="1" + Description="The NMail mail server."> + + <!-- NMail Server EXEs --> + <ComponentRef Id="C_NMail.Server.Console.exe" /> + <ComponentRef Id="C_NMail.Administration.Console.exe" /> + <ComponentRef Id="C_NMail.Server.Service.exe" /> + + <!-- NMail Server DLLs --> + <ComponentRef Id="C_MonoPrivileges.dll" /> + <ComponentRef Id="C_NDns.dll" /> + <ComponentRef Id="C_NMail.DnsClient.dll" /> + <ComponentRef Id="C_NMail.ImapService.dll" /> + <ComponentRef Id="C_NMail.LocalStore.dll" /> + <ComponentRef Id="C_NMail.LocalStoreData.MySql.dll" /> + <ComponentRef Id="C_NMail.MessageRouter.dll" /> + <ComponentRef Id="C_NMail.SmtpClient.dll" /> + <ComponentRef Id="C_NMail.SmtpService.dll" /> + <ComponentRef Id="C_NMail.SpoolData.MySql.dll" /> + <ComponentRef Id="C_NMail.SpoolFilter.dll" /> + <ComponentRef Id="C_NMail.SpoolFilter.RegexAddressRewriter.dll" /> + <ComponentRef Id="C_NMail.SpoolService.dll" /> + + <!-- Non-NMail DLLs --> + <ComponentRef Id="C_Mono.Security.dll" /> + + <!-- Other core files --> + <ComponentRef Id="C_Warning.txt" /> + <ComponentRef Id="C_Bounce.txt" /> + <ComponentRef Id="C_NMail.config" /> + <ComponentRef Id="C_NMail.pfx" /> + <ComponentRef Id="C_MySqlLocalStore.sql" /> + <ComponentRef Id="C_MySqlSpoolData.sql" /> + </Feature> - <!-- Other core files --> - <ComponentRef Id="C_Warning.txt" /> - <ComponentRef Id="C_Bounce.txt" /> - <ComponentRef Id="C_NMail.config" /> - <ComponentRef Id="C_NMail.pfx" /> - <ComponentRef Id="C_MySqlLocalStore.sql" /> - <ComponentRef Id="C_MySqlSpoolData.sql" /> + <Feature Id="F_AdminWebsite" Display="expand" Title="Administration Website" Level="1" + Description="NMail's ASP.net administration website."> - <!-- Documentation files --> - <ComponentRef Id="C_DevGuide.doc"/> + <ComponentRef Id="C_VirtualWebDir"/> + + <!-- Admin website files --> + <ComponentRef Id="component0"/> + <ComponentRef Id="component1"/> + <ComponentRef Id="component2"/> + <ComponentRef Id="component3"/> + <ComponentRef Id="component4"/> + <ComponentRef Id="component5"/> + <ComponentRef Id="component6"/> + <ComponentRef Id="component7"/> + <ComponentRef Id="component8"/> + <ComponentRef Id="component9"/> + <ComponentRef Id="component10"/> + <ComponentRef Id="component11"/> + <ComponentRef Id="component12"/> + <ComponentRef Id="component13"/> + <ComponentRef Id="component14"/> + <ComponentRef Id="component15"/> + <ComponentRef Id="component16"/> + <ComponentRef Id="component17"/> + <ComponentRef Id="component18"/> + <ComponentRef Id="component19"/> + <ComponentRef Id="component20"/> + <ComponentRef Id="component21"/> + <ComponentRef Id="component22"/> + <ComponentRef Id="component23"/> + <ComponentRef Id="component24"/> + <ComponentRef Id="component25"/> + <ComponentRef Id="component26"/> + <ComponentRef Id="component27"/> + <ComponentRef Id="component28"/> + <ComponentRef Id="component29"/> + <ComponentRef Id="component30"/> + <ComponentRef Id="component31"/> + <ComponentRef Id="component32"/> + <ComponentRef Id="component33"/> + <ComponentRef Id="component34"/> + <ComponentRef Id="component35"/> + <ComponentRef Id="component36"/> + </Feature> + + <Feature Id="F_DeveloperDoc" Display="expand" Title="Developer Documentation" Level="3" + Description="Documentation for NMail developers."> + + <!-- Developer documentation files --> + <ComponentRef Id="C_DevGuide.doc"/> + </Feature> </Feature> <UIRef Id="WixUI" /> Modified: NMail/branches/luke-dev/Installer/NMail-installer.build =================================================================== --- NMail/branches/luke-dev/Installer/NMail-installer.build 2006-06-23 11:10:20 UTC (rev 49) +++ NMail/branches/luke-dev/Installer/NMail-installer.build 2006-06-23 11:13:31 UTC (rev 50) @@ -35,11 +35,13 @@ <include name="MySql.Data.dll" /> </fileset> </copy> + <!-- Copy NMail assemblies --> <copy todir="${build.dir}"> <fileset basedir="../References/NMail/${project.config}"> <include name="*" /> </fileset> </copy> + <!-- Copy other required files --> <copy todir="${build.dir}"> <fileset basedir="../NMail.Server.Console/"> <include name="Warning.txt" /> @@ -58,6 +60,12 @@ <include name="MySqlSpoolData.sql" /> </fileset> </copy> + <!-- Copy NMail administration website --> + <copy todir="${build.dir}"> + <fileset basedir="../"> + <include name="NMail.Administration.Web.Compiled/**" /> + </fileset> + </copy> <!-- Make a date stamp to include in the filename --> <tstamp property="build.date" pattern="yyyy-MM-dd" verbose="true" /> @@ -82,7 +90,9 @@ <arg value="-loc"/> <arg><path><pathelement file="WixLib/WixUI_en-us.wxl" /></path></arg> - <arg><path><pathelement file="WixLib/wixui_minimal.wixlib" /></path></arg> + <arg><path><pathelement file="WixLib/wixui_featuretree.wixlib" /></path></arg> + + <arg><path><pathelement file="WixLib/sca.wixlib" /></path></arg> <arg><path><pathelement file="${build.dir}/NMail-Installer.wixobj" /></path></arg> </exec> Added: NMail/branches/luke-dev/Installer/WixLib/sca.wixlib =================================================================== --- NMail/branches/luke-dev/Installer/WixLib/sca.wixlib (rev 0) +++ NMail/branches/luke-dev/Installer/WixLib/sca.wixlib 2006-06-23 11:13:31 UTC (rev 50) @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><wixLibrary xmlns="http://schemas.microsoft.com/wix/2003/11/libraries" version="2.0.2207.0"><wixObject xmlns="http://schemas.microsoft.com/wix/2003/04/objects" src="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs" version="2.0.2207.0"><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureIIs" /><ignoreModularization name="RollbackMetabaseTransaction" type="Action" /><ignoreModularization name="CommitMetabaseTransaction" type="Action" /><ignoreModularization name="StartMetabaseTransaction" type="Action" /><ignoreModularization name="DeleteCertificate" type="Action" /><ignoreModularization name="AddCertificate" type="Action" /><ignoreModularization name="ConfigureIIs" type="Action" /><ignoreModularization name="WriteMetabaseChanges" type="Action" /><table name="ActionText"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*51"><field>ConfigureIIs</field><field>Configuring IIS</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*52"><field>StartMetabaseTransaction</field><field>Starting IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*53"><field>RollbackMetabaseTransaction</field><field>Rolling back IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*54"><field>CommitMetabaseTransaction</field><field>Committing IIS Metabase Transaction</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*55"><field>WriteMetabaseChanges</field><field>Installing Metabase Keys and Values</field><field /></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*58"><field>ConfigureIIs</field><field>1</field><field>ScaSchedule</field><field>ConfigureIIs</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*59"><field>StartMetabaseTransaction</field><field>3073</field><field>ScaExecute</field><field>StartMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*60"><field>RollbackMetabaseTransaction</field><field>3329</field><field>ScaExecute</field><field>RollbackMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*61"><field>CommitMetabaseTransaction</field><field>3585</field><field>ScaExecute</field><field>CommitMetabaseTransaction</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*62"><field>WriteMetabaseChanges</field><field>3073</field><field>ScaExecute</field><field>WriteMetabaseChanges</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*63"><field>AddCertificate</field><field>3073</field><field>ScaExecute</field><field>AddCertificate</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*64"><field>DeleteCertificate</field><field>3073</field><field>ScaExecute</field><field>DeleteCertificate</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*17"><field>26001</field><field><![CDATA[Cannot connect to Internet Information Server. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*18"><field>26002</field><field><![CDATA[Failed to read IIsWebs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*19"><field>26003</field><field><![CDATA[Failed to read IIsWebDirs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*20"><field>26004</field><field><![CDATA[Failed to read IIsVirtualDirs table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*21"><field>26005</field><field><![CDATA[Failed to read IIsFilters table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*22"><field>26007</field><field><![CDATA[Failed to read IIsMimeMap table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*23"><field>26006</field><field><![CDATA[Failed to read IIsAppPool table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*24"><field>26008</field><field><![CDATA[Failed to read the IIsProperty table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*25"><field>26009</field><field><![CDATA[Failed to read the IIsWebServiceExtension table. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*27"><field>26031</field><field><![CDATA[Failed to schedule transaction for changes to IIS. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*28"><field>26032</field><field><![CDATA[Failed to schedule install of IIS Web Sites. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*29"><field>26033</field><field><![CDATA[Failed to schedule install of IIS Web Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*30"><field>26034</field><field><![CDATA[Failed to schedule install of IIS Virtual Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*31"><field>26035</field><field><![CDATA[Failed to schedule install of IIS Filters. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*32"><field>26036</field><field><![CDATA[Failed to schedule install of IIS AppPools. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*33"><field>26037</field><field><![CDATA[Failed to schedule install of IIS Properties. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*34"><field>26038</field><field><![CDATA[Failed to schedule install of IIS Web Service Extensions. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*36"><field>26051</field><field><![CDATA[Failed to schedule uninstall of IIS Web Sites. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*37"><field>26052</field><field><![CDATA[Failed to schedule uninstall of IIS Web Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*38"><field>26053</field><field><![CDATA[Failed to schedule uninstall of IIS Virtual Directories. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*39"><field>26054</field><field><![CDATA[Failed to schedule uninstall of IIS Filters. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*40"><field>26055</field><field><![CDATA[Failed to schedule uninstall of IIS AppPools. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*41"><field>26056</field><field><![CDATA[Failed to schedule uninstall of IIS Properties. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*42"><field>26057</field><field><![CDATA[Failed to schedule uninstall of IIS Web Service Extensions. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*44"><field>26101</field><field><![CDATA[Failed to start IIS transaction. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*45"><field>26102</field><field><![CDATA[Failed to open metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*46"><field>26103</field><field><![CDATA[Failed to create metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*47"><field>26104</field><field><![CDATA[Failed to write data to metabase key. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*48"><field>26105</field><field><![CDATA[Failed to create web application. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*49"><field>26106</field><field><![CDATA[Failed to delete metabase key. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*67"><field>InstallExecuteSequence</field><field>ConfigureIIs</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureSql" /><ignoreModularization name="RollbackExecuteSqlStrings" type="Action" /><ignoreModularization name="ConfigureSql" type="Action" /><ignoreModularization name="CreateDatabase" type="Action" /><ignoreModularization name="ExecuteSqlStrings" type="Action" /><ignoreModularization name="DropDatabase" type="Action" /><ignoreModularization name="RollbackCreateDatabase" type="Action" /><table name="ActionText"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*86"><field>ConfigureSql</field><field>Configuring SQL Server</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*87"><field>CreateDatabase</field><field>Creating Databases</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*88"><field>DropDatabase</field><field>Dropping Databases</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*89"><field>ExecuteSqlStrings</field><field>Executing SQL Strings</field><field /></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*90"><field>RollbackExecuteSqlStrings</field><field>Rolling back SQL Strings</field><field /></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*94"><field>ConfigureSql</field><field>1</field><field>ScaSchedule</field><field>ConfigureSql</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*95"><field>CreateDatabase</field><field>1025</field><field>ScaExecute</field><field>CreateDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*96"><field>RollbackCreateDatabase</field><field>1281</field><field>ScaExecute</field><field>DropDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*97"><field>DropDatabase</field><field>1025</field><field>ScaExecute</field><field>DropDatabase</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*98"><field>ExecuteSqlStrings</field><field>1025</field><field>ScaExecute</field><field>ExecuteSqlStrings</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*99"><field>RollbackExecuteSqlStrings</field><field>1281</field><field>ScaExecute</field><field>ExecuteSqlStrings</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*80"><field>26201</field><field><![CDATA[Error [2]: failed to create SQL database: [3], error detail: [4].]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*81"><field>26202</field><field><![CDATA[Error [2]: failed to drop SQL database: [3], error detail: [4].]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*82"><field>26203</field><field><![CDATA[Failed to connect to SQL database. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*83"><field>26204</field><field><![CDATA[Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5]]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*84"><field>26205</field><field><![CDATA[The database [3] already exists do you wish to continue?]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*102"><field>InstallExecuteSequence</field><field>ConfigureSql</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureUsers" /><ignoreModularization name="ConfigureUsers" type="Action" /><ignoreModularization name="CreateUser" type="Action" /><ignoreModularization name="RemoveUser" type="Action" /><ignoreModularization name="CreateUserRollback" type="Action" /><table name="Property"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*120"><field>CreateUser</field><field>nothing</field><field>0</field><field>0</field><field>1</field></tuple></table><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*122"><field>ConfigureUsers</field><field>1</field><field>ScaSchedule</field><field>ConfigureUsers</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*123"><field>CreateUser</field><field>11265</field><field>ScaExecute</field><field>CreateUser</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*124"><field>CreateUserRollback</field><field>3329</field><field>ScaExecute</field><field>RemoveUser</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*126"><field>RemoveUser</field><field>3585</field><field>ScaExecute</field><field>RemoveUser</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*113"><field>26401</field><field><![CDATA[Failed to create user. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*114"><field>26402</field><field><![CDATA[Failed to create user due to invalid password. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*115"><field>26403</field><field><![CDATA[Failed to add user to group. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*116"><field>26404</field><field><![CDATA[Failed to create user because it already exists. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*129"><field>InstallExecuteSequence</field><field>ConfigureUsers</field><field /><field /><field>InstallFiles</field><field /><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/InstallFiles" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigureSmb" /><ignoreModularization name="CreateSmbRollback" type="Action" /><ignoreModularization name="ConfigureSmb" type="Action" /><ignoreModularization name="DropSmb" type="Action" /><ignoreModularization name="CreateSmb" type="Action" /><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*144"><field>ConfigureSmb</field><field>1</field><field>ScaSchedule</field><field>ConfigureSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*145"><field>CreateSmb</field><field>3073</field><field>ScaExecute</field><field>CreateSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*146"><field>CreateSmbRollback</field><field>3393</field><field>ScaExecute</field><field>DropSmb</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*148"><field>DropSmb</field><field>3585</field><field>ScaExecute</field><field>DropSmb</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*140"><field>26301</field><field><![CDATA[Failed to create network share. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*141"><field>26302</field><field><![CDATA[Failed to drop network share. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*151"><field>InstallExecuteSequence</field><field>ConfigureSmb</field><field /><field /><field /><field>InstallFiles</field><field>0</field></tuple></table></section><section type="fragment"><reference table="Actions" symbol="InstallExecuteSequence/RemoveRegistryValues" /><reference table="Actions" symbol="InstallExecuteSequence/WriteRegistryValues" /><reference table="Binary" symbol="ScaExecute" /><reference table="Binary" symbol="ScaSchedule" /><reference table="CustomAction" symbol="ConfigurePerfmonInstall" /><reference table="CustomAction" symbol="ConfigurePerfmonUninstall" /><ignoreModularization name="UnregisterPerfmon" type="Action" /><ignoreModularization name="RegisterPerfmon" type="Action" /><ignoreModularization name="RollbackRegisterPerfmon" type="Action" /><ignoreModularization name="ConfigurePerfmonUninstall" type="Action" /><ignoreModularization name="RollbackUnregisterPerfmon" type="Action" /><ignoreModularization name="ConfigurePerfmonInstall" type="Action" /><table name="CustomAction"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*168"><field>ConfigurePerfmonInstall</field><field>1</field><field>ScaSchedule</field><field>ConfigurePerfmonInstall</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*169"><field>ConfigurePerfmonUninstall</field><field>1</field><field>ScaSchedule</field><field>ConfigurePerfmonUninstall</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*170"><field>RegisterPerfmon</field><field>3073</field><field>ScaExecute</field><field>RegisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*171"><field>UnregisterPerfmon</field><field>3073</field><field>ScaExecute</field><field>UnregisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*172"><field>RollbackRegisterPerfmon</field><field>3329</field><field>ScaExecute</field><field>UnregisterPerfmon</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*173"><field>RollbackUnregisterPerfmon</field><field>3329</field><field>ScaExecute</field><field>RegisterPerfmon</field></tuple></table><table name="Error"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*164"><field>26251</field><field><![CDATA[Failed to register DLL with PerfMon. ([2] [3] [4] [5])]]></field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*165"><field>26252</field><field><![CDATA[Failed to unregister DLL with PerfMon. ([2] [3] [4] [5])]]></field></tuple></table><table name="Actions"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*176"><field>InstallExecuteSequence</field><field>ConfigurePerfmonInstall</field><field /><field /><field /><field>WriteRegistryValues</field><field>0</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*177"><field>InstallExecuteSequence</field><field>ConfigurePerfmonUninstall</field><field /><field /><field /><field>RemoveRegistryValues</field><field>0</field></tuple></table></section><section type="fragment"><table name="Binary"><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*184"><field>ScaSchedule</field><field>scasched.dll</field></tuple><tuple sourceLineNumber="e:\delivery\Dev\wix2.0_public\src\ca\serverca\scawixlib\sca.wxs*185"><field>ScaExecute</field><field>scaexec.dll</field></tuple></table></section></wixObject></wixLibrary> \ No newline at end of file Added: NMail/branches/luke-dev/Installer/WixLib/scaexec.dll =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/Installer/WixLib/scaexec.dll ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/Installer/WixLib/scasched.dll =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/Installer/WixLib/scasched.dll ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/Installer/WixLib/wixui_featuretree.wixlib =================================================================== --- NMail/branches/luke-dev/Installer/WixLib/wixui_featuretree.wixlib (rev 0) +++ NMail/branches/luke-dev/Installer/WixLib/wixui_featuretree.wixlib 2006-06-23 11:13:31 UTC (rev 50) @@ -0,0 +1 @@ @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-23 11:11:11
|
Revision: 49 Author: tmyroadctfig Date: 2006-06-23 04:10:20 -0700 (Fri, 23 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=49&view=rev Log Message: ----------- Added parent folder to store folders. Other work on admin web pages. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs NMail/branches/luke-dev/NMail/NMail.csproj NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.Server/NMail.Server.csproj NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.Server.dll.refresh NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.dll.refresh NMail/branches/luke-dev/NMail.Administration.Web/Bin/log4net.dll.refresh Modified: NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -28,7 +28,7 @@ /// A mail domain maps users and administrators to a set of hosts that the store /// accepts mail for. /// </summary> - [Serializable] + [Serializable] public class MailDomain { public MailDomain(int mailDomainId, Host primaryHost) { this.mailDomainId = mailDomainId; @@ -73,8 +73,8 @@ return this.additionalHosts.ToArray(); } set { - this.additionalHosts.Clear(); - this.additionalHosts.AddRange(value); + this.additionalHosts.Clear(); + this.additionalHosts.AddRange(value); } } @@ -89,7 +89,7 @@ } set { this.mailboxMappings.Clear(); - this.mailboxMappings.AddRange(value); + this.mailboxMappings.AddRange(value); } } @@ -102,10 +102,10 @@ get { return this.allowedActions.ToArray(); } - set { - this.allowedActions.Clear(); - this.allowedActions.AddRange(value); - } + set { + this.allowedActions.Clear(); + this.allowedActions.AddRange(value); + } } private List<ILocalStoreRecipientValidator> allowedValidators = new List<ILocalStoreRecipientValidator>(); @@ -119,7 +119,7 @@ } set { this.allowedValidators.Clear(); - this.allowedValidators.AddRange(value); + this.allowedValidators.AddRange(value); } } @@ -134,76 +134,78 @@ } set { this.defaultActions.Clear(); - this.defaultActions.AddRange(value); + this.defaultActions.AddRange(value); } } // TODO: add in a recipient validator tree here - /// <summary> - /// Maps a given mailbox to a user. - /// </summary> - /// <param name="mailbox">The mailbox to lookup.</param> - /// <returns>The username or null.</returns> - public string MapMailboxToUser(string mailbox) { - string result = null; + /// <summary> + /// Maps a given mailbox to a user. + /// </summary> + /// <param name="mailbox">The mailbox to lookup.</param> + /// <returns>The username or null.</returns> + public string MapMailboxToUser(string mailbox) { + string result = null; - // Search for a valid mapping for the mailbox - for (int i = 0; result == null && i < this.mailboxMappings.Count; i++) { - result = this.mailboxMappings[i].MapMailboxToUser(mailbox); - } + // Search for a valid mapping for the mailbox + for (int i = 0; result == null && i < this.mailboxMappings.Count; i++) { + result = this.mailboxMappings[i].MapMailboxToUser(mailbox); + } - return result; - } + // TODO: this should also check if the user belongs to the given mail domain - public ILocalStoreRecipientValidator GetRecipientValidator(string name) { - name = name.Trim().ToLower(); + return result; + } - foreach (ILocalStoreRecipientValidator validator in this.allowedValidators) { - if (validator.Name.Trim().ToLower() == name) { - return validator; - } - } + public ILocalStoreRecipientValidator GetRecipientValidator(string name) { + name = name.Trim().ToLower(); - return null; - } + foreach (ILocalStoreRecipientValidator validator in this.allowedValidators) { + if (validator.Name.Trim().ToLower() == name) { + return validator; + } + } + return null; + } - public ILocalStoreDeliveryAction GetDeliveryAction(string name) { - name = name.Trim().ToLower(); - foreach (ILocalStoreDeliveryAction action in this.allowedActions) { - if (action.Name.Trim().ToLower() == name) { - return action; - } - } + public ILocalStoreDeliveryAction GetDeliveryAction(string name) { + name = name.Trim().ToLower(); - return null; - } + foreach (ILocalStoreDeliveryAction action in this.allowedActions) { + if (action.Name.Trim().ToLower() == name) { + return action; + } + } - /// <summary> - /// Processes the incomming message against the list of delivery actions. - /// </summary> - /// <param name="delivery">The delivery in progress.</param> - /// <param name="username">The associated username.</param> - /// <returns>The result of the delivery attempt.</returns> - public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username) { - for (int i = 0; i < this.defaultActions.Count; i++) { - string name = this.defaultActions[i].Name; - string data = null; - if (delivery.Recipient != null) { - data = delivery.Recipient.Mailbox.GetDataPairValue(name); - } + return null; + } - DeliveryResult result = this.defaultActions[i].ProcessDelivery(delivery, username, data); + /// <summary> + /// Processes the incomming message against the list of delivery actions. + /// </summary> + /// <param name="delivery">The delivery in progress.</param> + /// <param name="username">The associated username.</param> + /// <returns>The result of the delivery attempt.</returns> + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username) { + for (int i = 0; i < this.defaultActions.Count; i++) { + string name = this.defaultActions[i].Name; + string data = null; + if (delivery.Recipient != null) { + data = delivery.Recipient.Mailbox.GetDataPairValue(name); + } - if (result.Type != DeliveryResultType.Success) { - return result; - } - } + DeliveryResult result = this.defaultActions[i].ProcessDelivery(delivery, username, data); - return new DeliveryResult(DeliveryResultType.Success, null); - } + if (result.Type != DeliveryResultType.Success) { + return result; + } + } + + return new DeliveryResult(DeliveryResultType.Success, null); + } } } Modified: NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -30,9 +30,11 @@ /// </summary> /// <param name="newFolder">The folder name.</param> /// <param name="folderId">The folder Id.</param> + /// <param name="parentId">The Id of this folder's parent or null if non.</param> /// <param name="hasChildren">A flag indicating if this folder has subfolder.s</param> - public StoreFolder(string newFolder, int folderId, bool hasChildren) : base(newFolder) { + public StoreFolder(string newFolder, int folderId, int? parentId, bool hasChildren) : base(newFolder) { this.folderId = folderId; + this.parentId = parentId; this.hasChildren = hasChildren; } @@ -42,9 +44,11 @@ /// <param name="newNameSpace">The namespace the folder belongs to.</param> /// <param name="newFolder">The folder name.</param> /// <param name="folderId">The folder Id.</param> + /// <param name="parentId">The Id of this folder's parent or null if non.</param> /// <param name="hasChildren">A flag indicating if this folder has subfolder.s</param> - public StoreFolder(string newNameSpace, string newFolder, int folderId, bool hasChildren) : base(newNameSpace, newFolder) { + public StoreFolder(string newNameSpace, string newFolder, int folderId, int? parentId, bool hasChildren) : base(newNameSpace, newFolder) { this.folderId = folderId; + this.parentId = parentId; this.hasChildren = hasChildren; } @@ -61,6 +65,20 @@ this.folderId = value; } } + + private int? parentId; + + /// <summary> + /// The Id of this folder's parent or null if non. + /// </summary> + public int? ParentId { + get { + return this.parentId; + } + set { + this.parentId = value; + } + } private bool hasChildren; Modified: NMail/branches/luke-dev/NMail/NMail.csproj =================================================================== --- NMail/branches/luke-dev/NMail/NMail.csproj 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail/NMail.csproj 2006-06-23 11:10:20 UTC (rev 49) @@ -290,7 +290,10 @@ <PropertyGroup> <PreBuildEvent> </PreBuildEvent> - <PostBuildEvent> - </PostBuildEvent> + <PostBuildEvent>if not exist "$(SolutionDir)References\NMail\$(ConfigurationName)" ( + mkdir "$(SolutionDir)References\NMail\$(ConfigurationName)"; +) + +copy "$(TargetPath)" "$(SolutionDir)References\NMail\$(ConfigurationName)";</PostBuildEvent> </PropertyGroup> </Project> \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -52,7 +52,7 @@ return null; } - public static void UpdateMailDomain(int mailDomainId, string primaryHost) + public static LocalStoreMailDomainResult UpdateMailDomain(int mailDomainId, string primaryHost) { MailDomain updatedMailDomain = new MailDomain(mailDomainId, new Host(primaryHost)); @@ -60,7 +60,7 @@ IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; - localStore.UpdateMailDomain(authToken, updatedMailDomain); + return localStore.UpdateMailDomain(authToken, updatedMailDomain); } public static LocalStoreMailDomainResult CreateMailDomain(Host primaryHost) @@ -71,5 +71,14 @@ return localStore.CreateMailDomain(authToken, primaryHost); } + + public static LocalStoreMailDomainResult DeleteMailDomain(int mailDomainId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.DeleteMailDomain(authToken, mailDomainId); + } } } Added: NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.Server.dll.refresh =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.Server.dll.refresh ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.dll.refresh =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Bin/NMail.dll.refresh ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Bin/log4net.dll.refresh =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Bin/log4net.dll.refresh ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-23 11:10:20 UTC (rev 49) @@ -22,6 +22,8 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <Fields> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> + <asp:HyperLinkField DataNavigateUrlFields="ParentId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + DataTextField="ParentId" HeaderText="Parent Id" /> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" InsertVisible="False" /> <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" ReadOnly="True" /> @@ -77,7 +79,7 @@ <asp:Label ID="AclStatusLabel" runat="server"></asp:Label> <h2>Folder ACL</h2> - <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True" DataKeyNames="Identifier" OnRowDeleting="AclGridView_RowDeleting"> + <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True" DataKeyNames="Identifier"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx 2006-06-23 11:10:20 UTC (rev 49) @@ -1,4 +1,4 @@ -<%@ Page Language="C#" CodeFile="Login.aspx.cs" Inherits="Login" MasterPageFile="~/MasterPage.master" Title="NMail Administration - Login" %> +<%@ Page Language="C#" CodeFile="Login.aspx.cs" Inherits="NMail.Administration.Web.Login" MasterPageFile="~/MasterPage.master" Title="NMail Administration - Login" %> <asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:LoginView ID="LoginView" runat="server"> Modified: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -18,20 +18,23 @@ using NMail.IO; using NMail.Server; -public partial class Login : System.Web.UI.Page +namespace NMail.Administration.Web { - protected void Login_Authenticate(object sender, AuthenticateEventArgs e) - { - System.Web.UI.WebControls.Login login = (System.Web.UI.WebControls.Login)this.LoginView.FindControl("Login"); + public partial class Login : System.Web.UI.Page + { + 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"); - IAuthenticationToken authToken = ra.NMailServer.AuthenticationProvider.Authenticate(login.UserName, login.Password); + RemoteAdministration ra = (RemoteAdministration)Activator.GetObject(typeof(RemoteAdministration), "tcp://localhost:7877/RemoteAdministration.rem"); + IAuthenticationToken authToken = ra.NMailServer.AuthenticationProvider.Authenticate(login.UserName, login.Password); - if (authToken != null) - { - e.Authenticated = true; - Session["AuthToken"] = authToken; - Session["LocalStore"] = ra.NMailServer.LocalStore; + if (authToken != null) + { + e.Authenticated = true; + Session["AuthToken"] = authToken; + Session["LocalStore"] = ra.NMailServer.LocalStore; + } } - } + } } \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-06-23 11:10:20 UTC (rev 49) @@ -1,21 +1,49 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <asp:DetailsView ID="DetailsView1" runat="server" CellPadding="4" DataSourceID="MailDomainDataSource" - ForeColor="#333333" GridLines="None" Height="50px" Width="125px"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - </asp:DetailsView> - <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomain" - TypeName="NMail.Administration.Web.MailDomainDataSource"> - <SelectParameters> - <asp:QueryStringParameter Name="mailDomainId" QueryStringField="MailDomainId" Type="Int32" /> - </SelectParameters> - </asp:ObjectDataSource> + <asp:Image ID="StatusImage" runat="server" Visible="false" /> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> + + <asp:Panel ID="ConfirmPanel" runat="server" Visible="false"> + <br /> + <div style="border-right: black thin solid; padding-right: 0.5em; border-top: black thin solid; padding-left: 0.5em; padding-bottom: 0.5em; border-left: black thin solid; color: red; padding-top: 0.5em; border-bottom: black thin solid;"> + <img src="Images/Tango/Question.png" /> + Really delete this mail domain? + <asp:Button ID="yesBtn" runat="server" Text="Yes" OnClick="yesBtn_Click" /> + <asp:Button ID="noBtn" runat="server" Text="No" OnClick="noBtn_Click" /></div> + </asp:Panel> + + <asp:Panel ID="MainPanel" runat="server"> + <h2>Mail Domain Details</h2> + <asp:DetailsView ID="MailDomainDetailsView" runat="server" CellPadding="4" DataSourceID="MailDomainDataSource" + ForeColor="#333333" GridLines="None" AutoGenerateRows="False" OnItemDeleting="MailDomainDetailsView_ItemDeleting"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + <Fields> + <asp:BoundField DataField="MailDomainId" HeaderText="Mail Domain Id" SortExpression="MailDomainId" /> + <asp:BoundField DataField="PrimaryHost" HeaderText="Primary Host" SortExpression="PrimaryHost" /> + <asp:CommandField ShowEditButton="True" /> + <asp:CommandField ShowDeleteButton="True" /> + </Fields> + </asp:DetailsView> + <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomain" + TypeName="NMail.Administration.Web.MailDomainDataSource" UpdateMethod="UpdateMailDomain" DeleteMethod="DeleteMailDomain" OnDeleted="MailDomainDataSource_Deleted" OnDeleting="MailDomainDataSource_Deleting"> + <SelectParameters> + <asp:QueryStringParameter Name="mailDomainId" QueryStringField="MailDomainId" Type="Int32" /> + </SelectParameters> + <UpdateParameters> + <asp:Parameter Name="mailDomainId" Type="Int32" /> + <asp:Parameter Name="primaryHost" Type="String" /> + </UpdateParameters> + <DeleteParameters> + <asp:Parameter Name="mailDomainId" Type="Int32" /> + </DeleteParameters> + </asp:ObjectDataSource> + </asp:Panel> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -9,6 +9,62 @@ using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; +using NMail; +using NMail.DataTypes; + public partial class MailDomainDetails : System.Web.UI.Page -{ +{ + #region Mail Domain Deletion Events + + protected void yesBtn_Click(object sender, EventArgs e) + { + // Got confirmation, send the delete command and hide the confirmation panel + this.MailDomainDataSource.Delete(); + this.ConfirmPanel.Visible = false; + } + + protected void noBtn_Click(object sender, EventArgs e) + { + // Got a cancel, hide the confirmation panel + this.ConfirmPanel.Visible = false; + } + + protected void MailDomainDetailsView_ItemDeleting(object sender, DetailsViewDeleteEventArgs e) + { + // Display the confirmation panel and canel the event + this.ConfirmPanel.Visible = true; + e.Cancel = true; + } + + protected void MailDomainDataSource_Deleted(object sender, ObjectDataSourceStatusEventArgs e) + { + LocalStoreMailDomainResult result = (LocalStoreMailDomainResult)e.ReturnValue; + + // Display the result of the attempt to delete the mail domain + switch (result) + { + case LocalStoreMailDomainResult.OkSuccessful: + this.StatusMessage.Text = "Mail domain deleted."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; + + // Hide these controls, they shouldn't have any data now + this.MainPanel.Visible = false; + break; + + default: + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to delete the mail domain: {0}", result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + } + + this.StatusImage.Visible = true; + } + + protected void MailDomainDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) + { + e.InputParameters["mailDomainId"] = Request.QueryString["MailDomainId"]; + } + #endregion + + } Modified: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-23 11:10:20 UTC (rev 49) @@ -1,5 +1,4 @@ <%@ Master Language="C#" %> - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> @@ -23,50 +22,61 @@ } </script> -<html xmlns="http://www.w3.org/1999/xhtml" > +<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> - <title>Untitled Page</title> - <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> + <title>Untitled Page</title> + <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> </head> <body> - <form id="MainForm" runat="server"> + <form id="MainForm" runat="server"> <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> - <tr> - <td colspan="2" style="vertical-align: middle; width: 100%; background-color: #507cd1; border-bottom-width: thin; border-bottom-color: darkgray;"> - <h1 style="color: white"> <img src="Images/nmail-logo-white.png" style="vertical-align: middle" /> NMail Web Administration</h1> - </td> - </tr> - <tr> - <td colspan="2" style="border-bottom: darkgray thick solid; background-color: #eff3fb;"> - <table style="width: 100%"> - <tr> - <td style="width: 100%"><asp:SiteMapPath ID="SiteMapPath" runat="server" Font-Names="Verdana" Font-Size="0.8em" PathSeparator=" : " > - <PathSeparatorStyle Font-Bold="True" ForeColor="#1C5E55" /> - <CurrentNodeStyle ForeColor="#333333" /> - <NodeStyle Font-Bold="True" ForeColor="#666666" /> - <RootNodeStyle Font-Bold="True" ForeColor="#1C5E55" /> - </asp:SiteMapPath></td> - <td style="text-align: right;"><asp:LoginStatus ID="LoginStatus" runat="server" /></td> - </tr> - </table> - </td> - </tr> - <tr> - <td style="border-right-style: solid; border-right-color: darkgray; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em; vertical-align: top; background-color: #eff3fb; height: 100%;"> - <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource" OnTreeNodeDataBound="TreeView_TreeNodeDataBound"> - </asp:TreeView> - <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> - </td> - <td style="width: 100%; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em; vertical-align: top;"> - <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> - </asp:ContentPlaceHolder> - </td> - </tr> - <tr> - <td style="border-right-style: solid; background-color: #eff3fb; text-align: center; border-right-color: darkgray; top: 100%;"><a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> - <td style="height: 18px"></td> - </tr> - </table> - </form> + <tr> + <td colspan="2" style="vertical-align: middle; width: 100%;"> + <div class="box"> + <h1> + <img src="Images/nmail-logo.png" style="vertical-align: middle" /> + NMail Web Administration</h1> + <table> + <tr> + <td style="width: 100%"> + <asp:SiteMapPath ID="SiteMapPath" runat="server" Font-Names="Verdana" Font-Size="0.8em" + PathSeparator=" : "> + <PathSeparatorStyle Font-Bold="True" ForeColor="#1C5E55" /> + <CurrentNodeStyle ForeColor="#333333" /> + <NodeStyle Font-Bold="True" ForeColor="#666666" /> + <RootNodeStyle Font-Bold="True" ForeColor="#1C5E55" /> + </asp:SiteMapPath> + </td> + <td> + <asp:LoginStatus ID="LoginStatus" runat="server" /> + </td> + </tr> + </table> + </div> + </td> + </tr> + <tr> + <td style="vertical-align: top; height: 100%;"> + <div class="box"> + <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource" OnTreeNodeDataBound="TreeView_TreeNodeDataBound"> + </asp:TreeView> + <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> + </div> + </td> + <td style="width: 100%; vertical-align: top;"> + <div style="padding: 0.5em"> + <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> + </asp:ContentPlaceHolder> + </div> + </td> + </tr> + <tr> + <td style="text-align: center; top: 100%;"> + <a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> + <td> + </td> + </tr> + </table> + </form> </body> </html> Modified: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-23 11:10:20 UTC (rev 49) @@ -13,4 +13,12 @@ font-size: large; margin-bottom: 0.5em; margin-top: 1em; +} + +.box +{ + background-color: #eff3fb; + margin: 0.5em; + border: #507cd1 thin solid; + padding: 0.5em; } \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-23 11:10:20 UTC (rev 49) @@ -12,63 +12,65 @@ <asp:Button ID="noBtn" runat="server" Text="No" OnClick="noBtn_Click" /></div> </asp:Panel> - <h2>User Details</h2> - <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="UserDetailsView_ItemDeleting"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <Fields> - <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> - <asp:BoundField DataField="UserId" HeaderText="User Id" ReadOnly="True" SortExpression="UserId" /> - <asp:BoundField DataField="UserFolderId" HeaderText="User Initial Folder Id" SortExpression="UserFolderId" /> - <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Quota Warn Limit" SortExpression="QuotaWarnLimit" /> - <asp:BoundField DataField="QuotaHardLimit" HeaderText="Quota Hard Limit" SortExpression="QuotaHardLimit" /> - <asp:CommandField ShowDeleteButton="True" /> - </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - </asp:DetailsView> - <asp:ObjectDataSource ID="UserDataSource" runat="server" - SelectMethod="GetUser" TypeName="NMail.Administration.Web.UserDataSource" DeleteMethod="DeleteUser" OnDeleting="UserDataSource_Deleting" OnDeleted="UserDataSource_Deleted"> - <SelectParameters> - <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> - </SelectParameters> - <DeleteParameters> - <asp:Parameter Name="userId" Type="Int32" /> - </DeleteParameters> - </asp:ObjectDataSource> - - <h2>User's Folders</h2> - <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" - DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <Columns> - <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> - <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> - <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> - <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> - <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" - Text="details" /> - </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - <EmptyDataTemplate> - The user doesn't have any folders. - </EmptyDataTemplate> - </asp:GridView> - <asp:ObjectDataSource ID="UserFolderDataSource" runat="server" SelectMethod="GetUserFolders" - TypeName="NMail.Administration.Web.UserDataSource"> - <SelectParameters> - <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> - </SelectParameters> - </asp:ObjectDataSource> + <asp:Panel ID="MainPanel" runat="server"> + <h2>User Details</h2> + <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" + DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="UserDetailsView_ItemDeleting"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> + <asp:BoundField DataField="UserId" HeaderText="User Id" ReadOnly="True" SortExpression="UserId" /> + <asp:BoundField DataField="UserFolderId" HeaderText="User Initial Folder Id" SortExpression="UserFolderId" /> + <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Quota Warn Limit" SortExpression="QuotaWarnLimit" /> + <asp:BoundField DataField="QuotaHardLimit" HeaderText="Quota Hard Limit" SortExpression="QuotaHardLimit" /> + <asp:CommandField ShowDeleteButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="UserDataSource" runat="server" + SelectMethod="GetUser" TypeName="NMail.Administration.Web.UserDataSource" DeleteMethod="DeleteUser" OnDeleting="UserDataSource_Deleting" OnDeleted="UserDataSource_Deleted"> + <SelectParameters> + <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> + </SelectParameters> + <DeleteParameters> + <asp:Parameter Name="userId" Type="Int32" /> + </DeleteParameters> + </asp:ObjectDataSource> + + <h2>User's Folders</h2> + <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" + DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + Text="details" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + The user doesn't have any folders. + </EmptyDataTemplate> + </asp:GridView> + <asp:ObjectDataSource ID="UserFolderDataSource" runat="server" SelectMethod="GetUserFolders" + TypeName="NMail.Administration.Web.UserDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> + </asp:Panel> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -30,8 +30,7 @@ this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; // Hide these controls, they shouldn't have any data now - this.UserDetailsView.Visible = false; - this.UserFoldersGridView.Visible = false; + this.MainPanel.Visible = false; break; case LocalStoreUserResult.UserStillHasFolders: Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-23 11:10:20 UTC (rev 49) @@ -6,6 +6,8 @@ <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <Columns> <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:HyperLinkField DataNavigateUrlFields="ParentId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + DataTextField="ParentId" HeaderText="Parent Id" /> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -203,10 +203,10 @@ /// <returns>The result of the delivery.</returns> public DeliveryResult DeliverMessage(IAuthenticationToken authToken, Message message, StoreFolder folder) { - LocalStoreDelivery lsd = new LocalStoreDelivery((Message) null, folder); + LocalStoreData.DeliverMessage(message, folder); + return new DeliveryResult(DeliveryResultType.Success, null); - // Need to get a mail domain for the user here... - throw new NotImplementedException(); + // TODO: lookup a maildomain or a system wide delivery chain to process the message //// Pass through the default chain //DeliveryActionList deliveryChain = LocalStoreConfiguration.Current.DeliveryChain; @@ -504,7 +504,8 @@ public StoreFolder[] GetChildren(IAuthenticationToken authToken, StoreFolder parent) { // Ensure the user has rights to list the folders - if (hasFolderPrivilege(authToken.Username, parent.FolderId, StoreFolderPrivilege.Lookup)) { + if (parent != null + && hasFolderPrivilege(authToken.Username, parent.FolderId, StoreFolderPrivilege.Lookup)) { // Return the children return LocalStoreData.GetChildren(parent); Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-06-23 11:10:20 UTC (rev 49) @@ -1,5 +1,4 @@ - -DROP DATABASE IF EXISTS NMailLocalStore; +DROP DATABASE IF EXISTS NMailLocalStore; CREATE DATABASE NMailLocalStore; USE NMailLocalStore; @@ -210,19 +209,23 @@ OUT Result INT ) BEGIN - + DECLARE Username VARCHAR(100); + START TRANSACTION; /* Check if the parameters are valid. */ - IF ParentId IS NULL OR - EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = ParentId) THEN + IF (ParentId IS NULL OR EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = ParentId)) THEN /* Check for duplicate folders. */ IF NOT EXISTS (SELECT f.FolderId FROM Folder f WHERE f.Name LIKE Name) THEN - INSERT INTO Folder (ParentFolderId, NamespaceId, Name, OwnerUserId, NextMessageId) VALUES (ParentId, NamespaceId, Name, UserId, 1); + INSERT INTO Folder (FolderId, ParentFolderId, NamespaceId, Name, OwnerUserId, NextMessageId) VALUES (NULL, ParentId, NamespaceId, Name, UserId, 1); SELECT LAST_INSERT_ID() INTO FolderId; - + + SELECT u.Username INTO Username FROM `User` u WHERE u.UserId = UserId; + + INSERT INTO FolderAcl (FolderAclId, Identifier, FolderId, Allow, Privilege) VALUES (NULL, Username, FolderId, 1, 0xffffffff); + /* Ok successful. */ SELECT 0 INTO Result; @@ -273,6 +276,38 @@ END // +DROP PROCEDURE IF EXISTS RenameFolder // +CREATE PROCEDURE RenameFolder +( + FolderId INT, + NewName VARCHAR(1000), + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the folder already exists. */ + IF EXISTS (SELECT f.FolderId FROM Folder f WHERE f.Name LIKE NewName) THEN + + /* Update the folder name. */ + UPDATE + Folder + SET + Name = NewName + WHERE + FolderId = FolderId; + + /* TODO: update any child names */ + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + COMMIT; +END +// + DROP PROCEDURE IF EXISTS GetFolders // CREATE PROCEDURE GetFolders ( @@ -280,7 +315,7 @@ BEGIN SELECT - f.FolderId, f.Name, n.Name AS NameSpace + f.FolderId, f.Name, f.ParentFolderId, n.Name AS NameSpace FROM Folder f, Namespace n WHERE @@ -288,7 +323,86 @@ END // +DROP PROCEDURE IF EXISTS GetFolderChildIds // +CREATE PROCEDURE GetFolderChildIds +( + FolderId INT +) +BEGIN + SELECT + f.FolderId + FROM + Folder f + WHERE + f.ParentFolderId = FolderId; +END +// + +DROP PROCEDURE IF EXISTS GetFolderId // +CREATE PROCEDURE GetFolderId +( + Name VARCHAR(1000), + NameSpace VARCHAR(100), + OUT FolderId INT +) +BEGIN + + SELECT + f.FolderId + INTO + FolderId + FROM + Folder f, Namespace n + WHERE + f.Name LIKE Name AND + n.Name LIKE NameSpace AND + f.NameSpaceId = n.NameSpaceId; +END +// + +DROP PROCEDURE IF EXISTS GetFolder // +CREATE PROCEDURE GetFolder +( + FolderId INT, + OUT ParentId INT, + OUT Name VARCHAR(1000), + OUT NameSpace VARCHAR(100), + OUT Children INT, + OUT Result INT +) +BEGIN + + START TRANSACTION; + + IF EXISTS (SELECT f.Name FROM Folder f WHERE f.FolderId = FolderId) THEN + + SELECT + f.ParentFolderId, f.Name, n.Name + INTO + ParentId, Name, NameSpace + FROM + Folder f, Namespace n + WHERE + f.NameSpaceId = n.NameSpaceId + AND f.FolderId = FolderId; + + SELECT COUNT(*) INTO Children FROM Folder f WHERE f.ParentFolderId = FolderId; + + /* Successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such folder. */ + SELECT 3 INTO Result; + END IF; + + COMMIT; + +END +// + + -- ----------------------------------------------------------------------- -- -- User related stored procedures @@ -538,7 +652,7 @@ BEGIN SELECT - f.FolderId, f.Name, n.Name AS NameSpace + f.FolderId, f.ParentFolderId, f.Name, n.Name AS NameSpace FROM Folder f, Namespace n WHERE @@ -853,9 +967,92 @@ COMMIT; END +// + +DROP PROCEDURE IF EXISTS AddMailDomain // +CREATE PROCEDURE AddMailDomain +( + PrimaryHost VARCHAR(255), + ObjectData LONGBLOB, + OUT MailDomainId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the name is valid. */ + IF NOT EXISTS (SELECT m.MailDomainId FROM MailDomain m WHERE m.PrimaryHost LIKE PrimaryHost) THEN + + INSERT INTO MailDomain (PrimaryHost, ObjectData) VALUES (PrimaryHost, ObjectData); + + SELECT LAST_INSERT_ID() INTO MailDomainId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS UpdateMailDomain // +CREATE PROCEDURE UpdateMailDomain +( + PrimaryHost VARCHAR(255), + ObjectData LONGBLOB, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the name is valid. */ + IF NOT EXISTS (SELECT m.MailDomainId FROM MailDomain m WHERE m.PrimaryHost LIKE PrimaryHost AND m.MailDomainId != MailDomainId) THEN + + UPDATE MailDomain m SET m.PrimaryHost = PrimaryHost, m.ObjectData = ObjectData WHERE m.MailDomainId = MailDomainId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + COMMIT; +END // +DROP PROCEDURE IF EXISTS DeleteMailDomain // +CREATE PROCEDURE DeleteMailDomain +( + DeleteMailDomainId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the name is valid. */ + IF EXISTS (SELECT m.MailDomainId FROM MailDomain m WHERE m.MailDomainId = DeleteMailDomainId) THEN + + DELETE FROM MailDomain WHERE MailDomainId = DeleteMailDomainId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such mail domain. */ + SELECT 2 INTO Result; + END IF; + COMMIT; +END +// + + -- ----------------------------------------------------------------------- -- -- System ACL related stored procedures @@ -919,19 +1116,3 @@ INSERT INTO `Group` (Name) VALUES ("Administrators"); INSERT INTO UserGroupMap (GroupId, UserId) VALUES (1, 1); INSERT INTO Acl (Identifier, Allow, Privilege, Resource) VALUES ("Administrator", 1, 0xffffff, "System"); -- All privs - --- TODO: remove, for testing only -INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing1", "changeme", 2); -INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing2", "changeme", 2); -INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing3", "changeme", 2); - -INSERT INTO `Group` (Name) VALUES ("Test1"); -INSERT INTO `Group` (Name) VALUES ("Test2"); -INSERT INTO `Group` (Name) VALUES ("Test3"); - -INSERT INTO UserGroupMap (UserId, GroupId) VALUES (2, 1); -INSERT INTO UserGroupMap (UserId, GroupId) VALUES (2, 2); -INSERT INTO UserGroupMap (UserId, GroupId) VALUES (3, 3); - - -INSERT INTO GroupGroupMap (ParentId, GroupId) VALUES (3, 2); \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-18 09:43:19 UTC (rev 48) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-23 11:10:20 UTC (rev 49) @@ -26,6 +26,7 @@ using MySql.Data.MySqlClient; using NMail.Authentication; +using NMail.Configuration; using NMail.DataTypes; using NMail.DataTypes.ACLs; using NMail.DataTypes.LocalStore; @@ -173,82 +174,42 @@ #region Folder Retrieval and Manipulation - private bool hasChildren(int folderId, MySqlConnection cnn, MySqlTransaction transaction) { - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.Transaction = transaction; - cmd.CommandText = "SELECT COUNT(f.FolderId) FROM Folder f WHERE f.ParentFolderId = ?FolderId"; - cmd.Parameters.Add("FolderId", folderId); - long count = (long)cmd.ExecuteScalar(); - - return (count > 0); - } - } - #region GetNominalStoreFolder public StoreFolder GetNominalStoreFolder(string username) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "SELECT n.Name as Namespace, f.Name as FolderName, f.FolderId as FolderId FROM User u, Folder f, Namespace n WHERE u.UserFolderId = f.FolderId AND n.NameSpaceId = f.NameSpaceId AND u.Username = ?Username"; - cmd.Parameters.Add("Username", username); + LocalStoreUser user = GetUser(username); - using(MySqlDataReader reader = cmd.ExecuteReader()) { - StoreFolder result = null; - if (reader.Read()) { - result = new StoreFolder( - (string) reader["Namespace"], - (string) reader["FolderName"], - (int) reader["FolderId"], - false); - } - reader.Close(); - - if (result != null) { - result.HasChildren = hasChildren(result.FolderId, cnn, null); - } + if (user == null) { + return null; + } - return result; - } + return GetStoreFolder(user.UserFolderId); } } } #endregion #region GetStoreFolder - private int? getStoreFolderId(Folder folder, MySqlConnection cnn, MySqlTransaction transaction) { + + private StoreFolder getStoreFolder(Folder folder, MySqlConnection cnn, MySqlTransaction transaction) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.Transaction = transaction; - cmd.CommandText = "SELECT f.FolderId FROM Namespace n, Folder f WHERE n.NamespaceId = f.NamespaceId AND n.Name = ?Namespace AND f.Name LIKE ?FolderName"; - cmd.Parameters.Add("FolderName", folder.FolderName); - cmd.Parameters.Add("Namespace", folder.NameSpace); + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetFolderId"; + cmd.Parameters.Add("FolderId", MySqlDbType.Int32); + cmd.Parameters.Add("Name", folder.FolderName); + cmd.Parameters.Add("NameSpace", folder.NameSpace); + cmd.Parameters["FolderId"].Direction = ParameterDirection.Output; - object o = cmd.ExecuteScalar(); - return (o == null) ? null : (int?)o; - } - } + cmd.ExecuteNonQuery(); - private StoreFolder getStoreFolder(int folderId) { - using (MySqlConnection cnn = GetConnection()) { - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "SELECT n.Name as Namespace, f.Name as FolderName FROM Folder f, Namespace n WHERE f.NamespaceId = n.NamespaceId AND f.FolderId = ?FolderId"; - cmd.Parameters.Add("FolderId", folderId); + int? folderId = (int?) cmd.Parameters["FolderId"].Value; - using (MySqlDataReader reader = cmd.ExecuteReader()) { - if (reader.Read()) { - StoreFolder result = new StoreFolder( - (string)reader["Namespace"], - (string)reader["FolderName"], - folderId, - false); - - reader.Close(); - - result.HasChildren = hasChildren(folderId, cnn, null); - return result; - - } else { - return null; - } - } + if (folderId.HasValue) { + return GetStoreFolder(folderId.Value); + } else { + return null; } } } @@ -258,51 +219,60 @@ return getStoreFolder(folder, cnn, null); } } - - private StoreFolder getStoreFolder(Folder folder, MySqlConnection cnn, MySqlTransaction transaction) { - int? folderId = getStoreFolderId(folder, cnn, transaction); - - if (folderId.HasValue) { - return new StoreFolder(folder.NameSpace, - folder.FolderName, - folderId.Value, - hasChildren(folderId.Value, cnn, transaction)); - } else { - return null; - } - } public StoreFolder GetStoreFolder(int folderId) { using (MySqlConnection cnn = GetConnection()) { - return getStoreFolder(folderId); + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetFolder"; + cmd.Parameters.Add("FolderId", folderId); + cmd.Parameters.Add("ParentId", MySqlDbType.Int32); + cmd.Parameters.Add("Name", MySqlDbType.String); + cmd.Parameters.Add("NameSpace", MySqlDbType.String); + cmd.Parameters.Add("Children", MySqlDbType.Int32); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["ParentId"].Direction = ParameterDirection.Output; + cmd.Parameters["Name"].Direction = ParameterDirection.Output; + cmd.Parameters["NameSpace"].Direction = ParameterDirection.Output; + cmd.Parameters["Children"].Direction = ParameterDirection.Output; + cmd.Parameters["Result"].Direction = ParameterDirection.Output; + + cmd.ExecuteNonQuery(); + + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreFolderResult result = (LocalStoreFolderResult) resultValue; + + // Check if the lookup succeeded + if (result != LocalStoreFolderResult.OkSuccessful) { + return null; + } + + // Parse out all the returned values + string name = (string) cmd.Parameters["Name"].Value; + string nameSpace = (string) cmd.Parameters["NameSpace"].Value; + int children = (int) cmd.Parameters["Children"].Value; + int? parentId = (cmd.Parameters["ParentId"].Value == DBNull.Value) + ? null + : (int?) cmd.Parameters["ParentId"].Value; + + // Return the folder object + return new StoreFolder(nameSpace, + name, + folderId, + parentId, + (children != 0)); + } } } #endregion #region Get Parent Folder public StoreFolder GetParentFolder(StoreFolder folder) { - using (MySqlConnection cnn = GetConnection()) { - return getParentFolder(folder, cnn, null); + if (folder.ParentId.HasValue) { + return GetStoreFolder(folder.ParentId.Value); } - } - private StoreFolder getParentFolder(StoreFolder folder, MySqlConnection cnn, MySqlTransaction transaction) { - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.Transaction = transaction; - cmd.CommandText = "SELECT f.Name, f.FolderId FROM Folder f WHERE f.FolderId IN (SELECT ParentFolderId FROM Folder WHERE FolderId = ?FolderId)"; - cmd.Parameters.Add("FolderId", folder.FolderId); - - MySqlDataReader reader = cmd.ExecuteReader(); - - if (reader.NextResult()) { - string folderStr = (string) reader["Name"]; - int parentId = (int) reader["FolderId"]; - StoreFolder parent = new StoreFolder(folder.NameSpace, folderStr, parentId, true); - return parent; - } - - return null; - } + return null; } #endregion @@ -369,6 +339,35 @@ #region RenameFolder public LocalStoreFolderResult RenameFolder(StoreFolder folder, string newFolderName) { + /* Several cases: + * a1.b1 -> a1.b2 => simply rename "a1.b1" to "a1.b2" + * a1.b1 -> a2.b1 => rename "a1" to "a2" and "a1.b1" to "a2.b1" + * a1.b1.c1 -> a1.b2.c1 => rename "a1.b1" to "a1.b2" and "a1.b1.c1" to "a1.b2.c1" + * So simply rename the folder and any children. + * + * Also renaming "a1.b1" to "a2.b2" causes problems so renaming will be limited + * to only allow changing the end folder in the hierarchy. For example: + * a1.b1 -> a1.b2 is ok + * a1 -> a2 is ok + * a1.b1 to a2.b1 is not ok + */ + + // Check only the top level folder is being renamed + char[] delim = { NMailConfiguration.Current.LocalStore.FolderDelimiter }; + string[] folderParts = folder.FolderName.Split(delim); + string[] newParts = newFolderName.Split(delim); + + if (folderParts.Length != newParts.Length) { + return LocalStoreFolderResult.NotPermitted; + } + + for (int i = 0; i < folderParts.Length - 1; i++) { + if (!folderParts[i].ToLower().Equals(newParts[i].ToLower())) { + return LocalStoreFolderResult.NotPermitted; + } + } + + // Only the last part of the folder name has changed, proceed with the rename using (MySqlConnection cnn = GetConnection()) { MySqlTransaction transaction = cnn.BeginTransaction(); @@ -379,24 +378,9 @@ return LocalStoreFolderResult.AlreadyExists; } - // Get the parent folder - StoreFolder parentFolder = getStoreFolder(folder.Parent, cnn, transaction); - - // Rename the folder - MySqlCommand cmd = cnn.CreateCommand(); - cmd.Transaction = transaction; - cmd.CommandText = "UPDATE Folder SET Name = ?Name, ParentFolderId = ?ParentFolderId WHERE FolderId = ?FolderId"; - cmd.Parameters.Add("Name", newFolder.FolderName); - cmd.Parameters.Add("ParentFolderId", parentFolder.FolderId); - cmd.Parameters.Add("FolderId", folder.FolderId); - - if (cmd.ExecuteNonQuery() == 0) { - transaction.Commit(); - return LocalStoreFolderResult.NonExistent; - } else { - transaction.Commit(); - return LocalStoreFolderResult.OkSuccessful; - } + throw new NotImplementedException(); + // TODO: rename the folder + // TODO: recursively rename all children } } #endregion @@ -405,26 +389,28 @@ public StoreFolder[] GetChildren(StoreFolder parent) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "SELECT n.Name AS Namespace, f.Name as FolderName, f.FolderId as FolderId FROM Folder f, Namespace n WHERE n.NamespaceId = f.NamespaceId AND f.ParentFolderId = ?FolderId"; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetFolderChildIds"; cmd.Parameters.Add("FolderId", parent.FolderId); using (MySqlDataReader reader = cmd.ExecuteReader()) { - List<StoreFolder> children = new List<StoreFolder>(); - + List<int> childIds = new List<int>(); + while (reader.Read()) { int childFolderId = (int)reader["FolderId"]; - string childMailboxName = (string)reader["FolderName"]; - string childNameSpace = (string)reader["Namespace"]; - - children.Add(new StoreFolder(childNameSpace, - childMailboxName, - childFolderId, - false)); + childIds.Add(childFolderId); } + reader.Close(); - for (int i = 0; i < children.Count; i++) { - children[i].HasChildren = hasChildren(children[i].FolderId, cnn, null); + List<StoreFolder> children = new List<StoreFolder>(); + + foreach (int childFolderId in childIds) { + StoreFolder folder = GetStoreFolder(childFolderId); + + if (folder != null) { + children.Add(folder); + } } return children.ToArray(); @@ -451,9 +437,12 @@ int folderId = (int) reader["FolderId"]; string nameSpace = (string) reader["NameSpace"]; string name = (string) reader["Name"]; + int? parentId = (reader["ParentFolderId"] == DBNull.Value) + ? null + : (int?) reader["ParentFolderId"]; // TODO: Get HasChildren from the reader - folders.Add(new StoreFolder(nameSpace, name, folderId, false)); + folders.Add(new StoreFolder(nameSpace, name, folderId, parentId, false)); } return folders.ToArray(); @@ -472,14 +461,19 @@ cmd.Parameters.Add("UserName", userName); using (MySqlDataReader reader = cmd.ExecuteReader()) { - List<StoreF... [truncated message content] |
|
From: <tmy...@us...> - 2006-06-18 09:43:39
|
Revision: 48 Author: tmyroadctfig Date: 2006-06-18 02:43:19 -0700 (Sun, 18 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=48&view=rev Log Message: ----------- Fixed the folder ACL admin page. Other small fixes to the website. Modified Paths: -------------- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-18 09:43:19 UTC (rev 48) @@ -1,219 +1,162 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="FolderDetails.aspx.cs" Inherits="FolderDetails" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <h2>Folder Details</h2> - <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> - <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="FolderDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> - <EditRowStyle BackColor="#2461BF" /> - <RowStyle BackColor="#EFF3FB" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <Fields> - <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> - <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> - <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" InsertVisible="False" /> - <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" ReadOnly="True" /> - <asp:CommandField ShowDeleteButton="True" /> - </Fields> - <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - </asp:DetailsView> - <asp:ObjectDataSource ID="FolderDataSource" runat="server" SelectMethod="GetFolder" - TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder"> - <SelectParameters> - <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> - </SelectParameters> - <DeleteParameters> - <asp:Parameter Name="folderId" Type="Int32" /> - </DeleteParameters> - <InsertParameters> - <asp:Parameter Name="folderName" Type="String" /> - </InsertParameters> - </asp:ObjectDataSource> - <h2>Sub-folders</h2> - <asp:GridView ID="SubFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" - DataSourceID="FolderChildrenDataSource" ForeColor="#333333" GridLines="None"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <Columns> - <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> - <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> - <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> - <asp:CheckBoxField DataField="HasChildren" HeaderText="HasChildren" SortExpression="HasChildren" /> - <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" - HeaderText="Details" Text="details" /> - </Columns> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - </asp:GridView> - <asp:ObjectDataSource ID="FolderChildrenDataSource" runat="server" SelectMethod="GetSubFolders" - TypeName="NMail.Administration.Web.FolderDataSource"> - <SelectParameters> - <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> - </SelectParameters> - </asp:ObjectDataSource> - <h2>Folder ACL</h2> - <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True"> - <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <RowStyle BackColor="#EFF3FB" /> - <EditRowStyle BackColor="#2461BF" /> - <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> - <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> - <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> - <AlternatingRowStyle BackColor="White" /> - <Columns> - <asp:TemplateField> - <EditItemTemplate><!-- Don't show in edit --></EditItemTemplate> - <ItemTemplate> - <asp:LinkButton ID="DeleteLinkBtn" runat="server" OnClientClick="return confirm('Really delete this ACL entry?');" CommandName="Delete">Delete conf</asp:LinkButton> - </ItemTemplate> - <FooterTemplate> - <asp:Button ID="CancelInsertAclEntryBtn" runat="server" Text="Cancel" OnClick="CancelInsertAclEntryBtn_Click"/> - <asp:Button ID="InsertAclEntryBtn" runat="server" Text="Insert" OnClick="InsertAclEntryBtn_Click"/> - </FooterTemplate> - </asp:TemplateField> - <asp:CommandField ShowEditButton="True" /> - <asp:TemplateField HeaderText="Identifier" SortExpression="Identifier"> - <EditItemTemplate> - <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Identifier") %>'></asp:TextBox> - </EditItemTemplate> - <ItemTemplate> - <asp:Label ID="Label1" runat="server" Text='<%# Bind("Identifier") %>'></asp:Label> - </ItemTemplate> - <FooterTemplate> - <asp:TextBox ID="NewIdentifier" runat="server"></asp:TextBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Insert" SortExpression="CanInsert"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("CanInsert") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("CanInsert") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanInsert" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Post" SortExpression="CanPost"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("CanPost") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("CanPost") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanPost" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Lookup" SortExpression="CanLookup"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("CanLookup") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("CanLookup") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanLookup" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Write" SortExpression="CanWrite"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("CanWrite") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("CanWrite") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanWrite" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Read" SortExpression="CanRead"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("CanRead") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("CanRead") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanRead" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Create Sub-folders" SortExpression="CanCreateFolders"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("CanCreateFolders") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("CanCreateFolders") %>' - Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanCreateSubFolders" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Delete" SortExpression="CanDelete"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("CanDelete") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("CanDelete") %>' Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanDelete" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Alter Seen Flag" SortExpression="CanAlterSeenFlag"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("CanAlterSeenFlag") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("CanAlterSeenFlag") %>' - Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanAlterSeenFlag" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - <asp:TemplateField HeaderText="Admin" SortExpression="AdministrativePrivileges"> - <EditItemTemplate> - <asp:CheckBox ID="CheckBox9" runat="server" Checked='<%# Bind("AdministrativePrivileges") %>' /> - </EditItemTemplate> - <ItemTemplate> - <asp:CheckBox ID="CheckBox9" runat="server" Checked='<%# Bind("AdministrativePrivileges") %>' - Enabled="false" /> - </ItemTemplate> - <FooterTemplate> - <asp:CheckBox ID="NewCanAdmin" runat="server"></asp:CheckBox> - </FooterTemplate> - </asp:TemplateField> - </Columns> - </asp:GridView> - <asp:ObjectDataSource ID="FolderAclDataSource" runat="server" SelectMethod="GetFolderAcl" - TypeName="NMail.Administration.Web.FolderDataSource" OnUpdating="FolderAclDataSource_Updating" UpdateMethod="SetStoreFolderAce" DeleteMethod="RemoveStoreFolderAce" InsertMethod="SetStoreFolderAce" OnDeleting="FolderAclDataSource_Deleting" OnInserting="FolderAclDataSource_Inserting"> - <SelectParameters> - <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> - </SelectParameters> - <UpdateParameters> - <asp:Parameter Name="folderId" Type="Int32" /> - <asp:Parameter Name="identifier" Type="String" /> - <asp:Parameter Name="privilege" Type="Object" /> - <asp:Parameter Name="aceType" Type="Object" /> - </UpdateParameters> - <DeleteParameters> - <asp:Parameter Name="folderId" Type="Int32" /> - <asp:Parameter Name="identifier" Type="String" /> - </DeleteParameters> - <InsertParameters> - <asp:Parameter Name="folderId" Type="Int32" /> - <asp:Parameter Name="identifier" Type="String" /> - <asp:Parameter Name="privilege" Type="Object" /> - <asp:Parameter Name="aceType" Type="Object" /> - </InsertParameters> - </asp:ObjectDataSource> - <asp:LinkButton ID="ShowInsertAclEntryBtn" runat="server" OnClick="ShowInsertAclEntryBtn_Click">Insert ACL Entry</asp:LinkButton> + <asp:Image ID="StatusImage" runat="server" Visible="false" /> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> + + <asp:Panel ID="ConfirmPanel" runat="server" Visible="false"> + <br /> + <div style="border-right: black thin solid; padding-right: 0.5em; border-top: black thin solid; padding-left: 0.5em; padding-bottom: 0.5em; border-left: black thin solid; color: red; padding-top: 0.5em; border-bottom: black thin solid;"> + <img src="Images/Tango/Question.png" /> + Really delete this folder? + <asp:Button ID="yesBtn" runat="server" Text="Yes" OnClick="yesBtn_Click" /> + <asp:Button ID="noBtn" runat="server" Text="No" OnClick="noBtn_Click" /></div> + </asp:Panel> + + <asp:Panel ID="MainPanel" runat="server"> + <h2>Folder Details</h2> + <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="FolderDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="FolderDetailsView_ItemDeleting"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" InsertVisible="False" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" ReadOnly="True" /> + <asp:CommandField ShowDeleteButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="FolderDataSource" runat="server" SelectMethod="GetFolder" + TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + <DeleteParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + </DeleteParameters> + <InsertParameters> + <asp:Parameter Name="folderName" Type="String" /> + </InsertParameters> + </asp:ObjectDataSource> + + <h2>Sub-folders</h2> + <asp:GridView ID="SubFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" + DataSourceID="FolderChildrenDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="HasChildren" SortExpression="HasChildren" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + HeaderText="Details" Text="details" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + This folder has no subfolders.<br /> + </EmptyDataTemplate> + </asp:GridView> + <asp:ObjectDataSource ID="FolderChildrenDataSource" runat="server" SelectMethod="GetSubFolders" + TypeName="NMail.Administration.Web.FolderDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> + + <asp:Image ID="AclStatusImage" runat="server" Visible="false" /> + <asp:Label ID="AclStatusLabel" runat="server"></asp:Label> + + <h2>Folder ACL</h2> + <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True" DataKeyNames="Identifier" OnRowDeleting="AclGridView_RowDeleting"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + <Columns> + <asp:BoundField DataField="Identifier" HeaderText="Identifier" /> + <asp:CheckBoxField DataField="CanInsert" HeaderText="Insert" /> + <asp:CheckBoxField DataField="CanPost" HeaderText="Post" /> + <asp:CheckBoxField DataField="CanLookup" HeaderText="Lookup" /> + <asp:CheckBoxField DataField="CanWrite" HeaderText="Write" /> + <asp:CheckBoxField DataField="CanRead" HeaderText="Read" /> + <asp:CheckBoxField DataField="CanCreateFolders" HeaderText="Create Sub-folders" /> + <asp:CheckBoxField DataField="CanDelete" HeaderText="Delete" /> + <asp:CheckBoxField DataField="CanAlterSeenFlag" HeaderText="Alter Seen Flag" /> + <asp:CheckBoxField DataField="AdministrativePrivileges" HeaderText="Admin" /> + + <asp:CommandField ShowEditButton="True" /> + <asp:CommandField ShowDeleteButton="True" /> + </Columns> + <EmptyDataTemplate> + This folder has no ACL entries. + </EmptyDataTemplate> + </asp:GridView> + <asp:ObjectDataSource ID="FolderAclDataSource" runat="server" SelectMethod="GetFolderAcl" + TypeName="NMail.Administration.Web.FolderDataSource" OnUpdating="FolderAclDataSource_InsertingOrUpdating" UpdateMethod="SetStoreFolderAce" DeleteMethod="RemoveStoreFolderAce" InsertMethod="SetStoreFolderAce" OnDeleting="FolderAclDataSource_Deleting" OnInserting="FolderAclDataSource_InsertingOrUpdating"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + <UpdateParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + <asp:Parameter Name="privilege" Type="Object" /> + <asp:Parameter Name="aceType" Type="Object" /> + </UpdateParameters> + <DeleteParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + </DeleteParameters> + <InsertParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + <asp:Parameter Name="privilege" Type="Object" /> + <asp:Parameter Name="aceType" Type="Object" /> + </InsertParameters> + </asp:ObjectDataSource> + <br /> + <asp:LinkButton ID="ShowInsertAclEntryBtn" runat="server" OnClick="ShowInsertAclEntryBtn_Click">Insert ACL Entry</asp:LinkButton> + + <asp:Panel ID="InsertAclPanel" runat="server" Visible="false"> + <h3>Add an ACL Entry</h3> + <asp:DetailsView ID="CreateAclDetailView" runat="server" AutoGenerateRows="False" + CellPadding="4" DataSourceID="FolderAclDataSource" DefaultMode="Insert" ForeColor="#333333" + GridLines="None" OnModeChanging="CreateAclDetailView_ModeChanging"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="Identifier" HeaderText="Identifier" /> + <asp:CheckBoxField DataField="CanInsert" HeaderText="Insert" /> + <asp:CheckBoxField DataField="CanPost" HeaderText="Post" /> + <asp:CheckBoxField DataField="CanLookup" HeaderText="Lookup" /> + <asp:CheckBoxField DataField="CanWrite" HeaderText="Write" /> + <asp:CheckBoxField DataField="CanRead" HeaderText="Read" /> + <asp:CheckBoxField DataField="CanCreateFolders" HeaderText="Create Sub-folders" /> + <asp:CheckBoxField DataField="CanDelete" HeaderText="Delete" /> + <asp:CheckBoxField DataField="CanAlterSeenFlag" HeaderText="Alter Seen Flag" /> + <asp:CheckBoxField DataField="AdministrativePrivileges" HeaderText="Admin" /> + <asp:CommandField ShowInsertButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + </asp:Panel> + </asp:Panel> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-18 09:43:19 UTC (rev 48) @@ -21,6 +21,8 @@ this.AclGridView.ShowFooter = false; } + #region Folder Events + protected void FolderDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) { e.InputParameters["folderId"] = Request.QueryString["FolderId"]; @@ -30,82 +32,60 @@ { LocalStoreFolderResult result = (LocalStoreFolderResult)e.ReturnValue; + // Display the result of the attempt to delete the user switch (result) { case LocalStoreFolderResult.OkSuccessful: this.StatusMessage.Text = "Folder deleted."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; + + // Hide these controls, they shouldn't have any data now + this.MainPanel.Visible = false; break; case LocalStoreFolderResult.HasChildren: this.StatusMessage.Text = "Cannot delete the folder because it still has sub-folders."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; break; + case LocalStoreFolderResult.NotPermitted: + this.StatusMessage.Text = "You are not permitted to delete this folder."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + default: - this.StatusMessage.Text = result.ToString(); + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to delete the folder: {0}", result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; break; } + + this.StatusImage.Visible = true; } - protected void FolderAclDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) + protected void yesBtn_Click(object sender, EventArgs e) { - StoreFolderPrivilege privilege = StoreFolderPrivilege.None; + // Got confirmation, send the delete command and hide the confirmation panel + this.FolderDataSource.Delete(); + this.ConfirmPanel.Visible = false; + } - if ((bool)e.InputParameters["NewCanAdmin"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Admin); - } + protected void noBtn_Click(object sender, EventArgs e) + { + // Got a cancel, hide the confirmation panel + this.ConfirmPanel.Visible = false; + } - if ((bool)e.InputParameters["NewCanAlterSeenFlag"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.AlterSeenFlag); - } - - if ((bool)e.InputParameters["NewCanCreateSubFolders"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.CreateFolders); - } - - if ((bool)e.InputParameters["NewCanDelete"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Delete); - } - - if ((bool)e.InputParameters["NewCanInsert"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Insert); - } - - if ((bool)e.InputParameters["NewCanLookup"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Lookup); - } - - if ((bool)e.InputParameters["NewCanPost"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Post); - } - - if ((bool)e.InputParameters["NewCanRead"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Read); - } - - if ((bool)e.InputParameters["NewCanWrite"]) - { - privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Write); - } - - string identifier = (string)e.InputParameters["NewIdentifier"]; - - e.InputParameters.Clear(); - - e.InputParameters["Identifier"] = identifier; - e.InputParameters["FolderId"] = this.Request.QueryString["FolderId"]; - e.InputParameters["Privilege"] = privilege; - e.InputParameters["AceType"] = AcePrivilegeType.Allow; + protected void FolderDetailsView_ItemDeleting(object sender, DetailsViewDeleteEventArgs e) + { + // Display the confirmation panel and canel the event + this.ConfirmPanel.Visible = true; + e.Cancel = true; } + #endregion - protected void FolderAclDataSource_Updating(object sender, ObjectDataSourceMethodEventArgs e) + #region Folder ACL Events + + protected void FolderAclDataSource_InsertingOrUpdating(object sender, ObjectDataSourceMethodEventArgs e) { StoreFolderPrivilege privilege = StoreFolderPrivilege.None; @@ -167,30 +147,28 @@ protected void FolderAclDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) { string identifier = (string)e.InputParameters["Identifier"]; - + e.InputParameters.Clear(); e.InputParameters["Identifier"] = identifier; e.InputParameters["FolderId"] = this.Request.QueryString["FolderId"]; } - protected void ShowInsertAclEntryBtn_Click(object sender, EventArgs e) + protected void CreateAclDetailView_ModeChanging(object sender, DetailsViewModeEventArgs e) { - this.AclGridView.ShowFooter = true; - this.ShowInsertAclEntryBtn.Visible = false; + // Hide the create ACL control if the user cancels + if (e.CancelingEdit) + { + this.InsertAclPanel.Visible = false; + this.ShowInsertAclEntryBtn.Visible = true; + e.Cancel = true; + } } - protected void CancelInsertAclEntryBtn_Click(object sender, EventArgs e) + protected void ShowInsertAclEntryBtn_Click(object sender, EventArgs e) { - this.AclGridView.ShowFooter = false; - this.ShowInsertAclEntryBtn.Visible = true; - } - - protected void InsertAclEntryBtn_Click(object sender, EventArgs e) - { - this.AclGridView.ShowFooter = false; + this.InsertAclPanel.Visible = true; this.ShowInsertAclEntryBtn.Visible = false; - - this.FolderAclDataSource.Insert(); } + #endregion } Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-18 09:43:19 UTC (rev 48) @@ -1,19 +1,20 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <asp:Image ID="StatusImage" runat="server" Visible="false" /> - <asp:Label ID="StatusMessage" runat="server" Visible="False"></asp:Label> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> - <asp:Panel ID="ConfirmPanel" runat="server"> - <div style="border-right: darkgray thin solid; padding-right: 0.5em; border-top: darkgray thin solid; padding-left: 0.5em; padding-bottom: 0.5em; margin: 1em; border-left: darkgray thin solid; color: red; padding-top: 0.5em; border-bottom: darkgray thin solid;"> + <asp:Panel ID="ConfirmPanel" runat="server" Visible="false"> + <br /> + <div style="border-right: black thin solid; padding-right: 0.5em; border-top: black thin solid; padding-left: 0.5em; padding-bottom: 0.5em; border-left: black thin solid; color: red; padding-top: 0.5em; border-bottom: black thin solid;"> <img src="Images/Tango/Question.png" /> Really delete this user? - <asp:Button ID="yesBtn" runat="server" Text="Yes" /> - <asp:Button ID="noBtn" runat="server" Text="No" /></div> + <asp:Button ID="yesBtn" runat="server" Text="Yes" OnClick="yesBtn_Click" /> + <asp:Button ID="noBtn" runat="server" Text="No" OnClick="noBtn_Click" /></div> </asp:Panel> <h2>User Details</h2> <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None"> + DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None" OnItemDeleting="UserDetailsView_ItemDeleting"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-18 09:43:19 UTC (rev 48) @@ -22,13 +22,49 @@ { LocalStoreUserResult result = (LocalStoreUserResult)e.ReturnValue; - this.StatusMessage.Visible = true; - + // Display the result of the attempt to delete the user switch (result) { + case LocalStoreUserResult.OkSuccessful: + this.StatusMessage.Text = "User deleted."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; + + // Hide these controls, they shouldn't have any data now + this.UserDetailsView.Visible = false; + this.UserFoldersGridView.Visible = false; + break; + case LocalStoreUserResult.UserStillHasFolders: this.StatusMessage.Text = "Could not delete the user because they still own folders."; + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; break; + + default: + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to delete the user: {0}", result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; } + + this.StatusImage.Visible = true; } + + protected void noBtn_Click(object sender, EventArgs e) + { + // Got a cancel, hide the confirmation panel + this.ConfirmPanel.Visible = false; + } + + protected void yesBtn_Click(object sender, EventArgs e) + { + // Got confirmation, send the delete command and hide the confirmation panel + this.UserDataSource.Delete(); + this.ConfirmPanel.Visible = false; + } + + protected void UserDetailsView_ItemDeleting(object sender, DetailsViewDeleteEventArgs e) + { + // Display the confirmation panel and canel the event + this.ConfirmPanel.Visible = true; + e.Cancel = true; + } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-18 09:43:19 UTC (rev 48) @@ -17,6 +17,9 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + There are no folders currently in the system. + </EmptyDataTemplate> </asp:GridView> <asp:ObjectDataSource ID="FoldersDataSource" runat="server" SelectMethod="GetFolders" TypeName="NMail.Administration.Web.FolderDataSource"></asp:ObjectDataSource> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-18 05:42:46 UTC (rev 47) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-18 09:43:19 UTC (rev 48) @@ -18,6 +18,9 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + No users currently in the system. + </EmptyDataTemplate> </asp:GridView> <asp:ObjectDataSource ID="UserDataSource" runat="server" SelectMethod="GetUsers" TypeName="NMail.Administration.Web.UserDataSource"></asp:ObjectDataSource> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-18 05:43:43
|
Revision: 47 Author: tmyroadctfig Date: 2006-06-17 22:42:46 -0700 (Sat, 17 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=47&view=rev Log Message: ----------- Further work on admin website. Modified Paths: -------------- NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/Images/GreenLight.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/ NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Delete.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Error.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Group.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/License.txt NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/MailDomain.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/NewFolder.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/OpenFolder.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Question.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Thumbs.db NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/User.png NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Warning.png NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo-white.png Property Changed: ---------------- NMail/branches/luke-dev/NMail.Administration.Web/Images/ Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -549,12 +549,12 @@ MailDomain[] GetMailDomains(IAuthenticationToken authToken); /// <summary> - /// Adds a new mail domain. + /// Creates a new mail domain for the given host. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="mailDomain">The mail domain to add.</param> + /// <param name="host">The primary host for the mail domain.</param> /// <returns>The result of the attempt to add the mail domain.</returns> - LocalStoreMailDomainResult AddMailDomain(IAuthenticationToken authToken, MailDomain mailDomain); + LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host host); /// <summary> /// Deletes a mail domain from the local store. Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -461,11 +461,11 @@ MailDomain[] GetMailDomains(); /// <summary> - /// Adds a new mail domain. - /// </summary> - /// <param name="mailDomain">The mail domain to add.</param> - /// <returns>The result of the attempt to add the mail domain.</returns> - LocalStoreMailDomainResult AddMailDomain(MailDomain mailDomain); + /// Creates a new mail domain for the given host. + /// </summary> + /// <param name="host">The primary host for the mail domain.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult CreateMailDomain(Host host); /// <summary> /// Deletes a mail domain from the local store. Modified: NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -81,10 +81,8 @@ return; } - MailDomain mailDomain = new MailDomain(-1, host); + LocalStoreMailDomainResult result = this.localStore.CreateMailDomain(this.authToken, host); - LocalStoreMailDomainResult result = this.localStore.AddMailDomain(this.authToken, mailDomain); - if (result == LocalStoreMailDomainResult.OkSuccessful) { System.Console.WriteLine("Added new mail domain."); } else { Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -23,6 +23,7 @@ /// </summary> public static class FolderDataSource { + #region Folder Operations /// <summary> /// Gets a list of all folders in the local store. /// </summary> @@ -106,7 +107,9 @@ return localStore.CreateFolder(authToken, folderName); } + #endregion + #region Folder ACL Operations /// <summary> /// Gets a list of access control entries for the given folder. /// </summary> @@ -131,6 +134,13 @@ return result; } + /// <summary> + /// Sets or adds a store folder ACE. + /// </summary> + /// <param name="folderId">The folder to add the entry to.</param> + /// <param name="identifier">The identifier to set or add the entry for.</param> + /// <param name="privilege">The privilege to set or add.</param> + /// <param name="aceType">The type of ace to set or add.</param> public static void SetStoreFolderAce(int folderId, string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -142,6 +152,11 @@ localStore.SetStoreFolderAce(authToken, folder, ace); } + /// <summary> + /// Removes a folder ACL entry from a store folder. + /// </summary> + /// <param name="folderId">The Id of the folder to remove the ACE from.</param> + /// <param name="identifier">The identifier to remove.</param> public static void RemoveStoreFolderAce(int folderId, string identifier) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -151,14 +166,29 @@ StoreFolder folder = localStore.GetStoreFolder(authToken, folderId); localStore.RemoveStoreFolderAce(authToken, folder, identifier); } + #endregion } + #region Store Folder Ace + /// <summary> + /// A simple wrapper class that converts a store folder ACE into a form + /// that ASP.net can use. + /// </summary> public class StoreFolderAce : GenericAce<StoreFolderPrivilege> { + /// <summary> + /// Creates a new ACE with the given details. + /// </summary> + /// <param name="identifier">The identifier to associated with this ACE.</param> + /// <param name="privilege">The privilege to set.</param> + /// <param name="aceType">The ACE type.</param> public StoreFolderAce(string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) : base(identifier, privilege, aceType) { } + /// <summary> + /// Gets or sets whether this ACE has administrative privileges. + /// </summary> public bool AdministrativePrivileges { get @@ -178,6 +208,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to alter the seen flag. + /// </summary> public bool CanAlterSeenFlag { get @@ -197,6 +230,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to create sub folders. + /// </summary> public bool CanCreateFolders { get @@ -216,6 +252,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to delete messages. + /// </summary> public bool CanDelete { get @@ -235,6 +274,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to insert messages. + /// </summary> public bool CanInsert { get @@ -254,6 +296,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to lookup messages and folders. + /// </summary> public bool CanLookup { get @@ -273,6 +318,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to post messages into the folder. + /// </summary> public bool CanPost { get @@ -292,6 +340,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to read messages. + /// </summary> public bool CanRead { get @@ -311,6 +362,9 @@ } } + /// <summary> + /// Gets or sets whether this ACE has privileges to write to messages. + /// </summary> public bool CanWrite { get @@ -330,4 +384,5 @@ } } } + #endregion } Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -1,5 +1,6 @@ using System; using System.Data; +using System.Collections.Generic; using System.Configuration; using System.Web; using System.Web.Security; @@ -21,33 +22,19 @@ /// </summary> public static class MailDomainDataSource { - public static DataTable GetMailDomains() + public static List<MailDomain> GetMailDomains() { - DataTable result = new DataTable("Mail Domains"); - result.Columns.Add("Id"); - result.Columns.Add("Primary Host"); - IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; MailDomain[] mailDomains = localStore.GetMailDomains(authToken); - foreach (MailDomain mailDomain in mailDomains) - { - object[] p = { mailDomain.MailDomainId, mailDomain.PrimaryHost }; - result.Rows.Add(p); - } - - return result; + return new List<MailDomain>(mailDomains); } - public static DataTable GetMailDomain(int mailDomainId) + public static MailDomain GetMailDomain(int mailDomainId) { - DataTable result = new DataTable("Mail Domain"); - result.Columns.Add("Id"); - result.Columns.Add("Primary Host"); - IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; @@ -58,13 +45,11 @@ { if (mailDomain.MailDomainId == mailDomainId) { - object[] p = { mailDomain.MailDomainId, mailDomain.PrimaryHost }; - result.Rows.Add(p); - break; + return mailDomain; } } - return result; + return null; } public static void UpdateMailDomain(int mailDomainId, string primaryHost) @@ -77,5 +62,14 @@ localStore.UpdateMailDomain(authToken, updatedMailDomain); } + + public static LocalStoreMailDomainResult CreateMailDomain(Host primaryHost) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.CreateMailDomain(authToken, primaryHost); + } } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -1,9 +1,10 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateFolder.aspx.cs" Inherits="CreateFolder" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Image ID="StatusImage" runat="server" Visible="false" /> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> <h2>Create New Folder</h2> - <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" - ForeColor="#333333" GridLines="None" DefaultMode="Insert" DataSourceID="CreateFolderDataSource" AutoGenerateInsertButton="True"> + ForeColor="#333333" GridLines="None" DefaultMode="Insert" DataSourceID="CreateFolderDataSource" AutoGenerateInsertButton="True" OnModeChanging="FolderDetailsView_ModeChanging"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -19,6 +19,7 @@ protected void FolderDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) { + // Save the folder name to display in the insert callback below this.folderName = (string) e.InputParameters["FolderName"]; } @@ -26,16 +27,34 @@ { LocalStoreFolderResult result = (LocalStoreFolderResult)e.ReturnValue; + // Display the result of the attempt to create the folder switch (result) { case LocalStoreFolderResult.OkSuccessful: - StoreFolder folder = FolderDataSource.GetFolder(this.folderName); - Response.Redirect(string.Format("FolderDetails.aspx?FolderId={0}", folder.FolderId)); + this.StatusMessage.Text = string.Format("Folder \"{0}\" created successfully!", this.folderName); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; break; + case LocalStoreFolderResult.AlreadyExists: + this.StatusMessage.Text = string.Format("Folder \"{0}\" already exists.", this.folderName); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + default: - this.StatusMessage.Text = result.ToString(); + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to create the folder \"{0}\": {1}", this.folderName, result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; break; } + + this.StatusImage.Visible = true; } + + protected void FolderDetailsView_ModeChanging(object sender, DetailsViewModeEventArgs e) + { + // Redirect back to the folder list on canel + if (e.CancelingEdit) + { + Response.Redirect("ViewFolders.aspx"); + } + } } Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -0,0 +1,25 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateMailDomain.aspx.cs" Inherits="CreateMailDomain" Title="Untitled Page" %> +<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Image ID="StatusImage" Visible="false" runat="server" /> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> + <h2>Create New Mail Domain</h2> + <asp:DetailsView ID="MailDomainDetailsView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateRows="False" DefaultMode="Insert" DataMember=" " OnItemInserting="MailDomainDetailsView_ItemInserting" OnModeChanging="MailDomainDetailsView_ModeChanging"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + <Fields> + <asp:TemplateField HeaderText="Primary Host" SortExpression="PrimaryHost"> + <InsertItemTemplate> + <asp:TextBox ID="HostTextBox" runat="server"></asp:TextBox> + </InsertItemTemplate> + </asp:TemplateField> + <asp:CommandField ShowInsertButton="True" /> + </Fields> + </asp:DetailsView> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateMailDomain.aspx.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -0,0 +1,56 @@ +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; + +using NMail; +using NMail.DataTypes; +using NMail.Administration.Web; + +public partial class CreateMailDomain : System.Web.UI.Page +{ + protected void MailDomainDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e) + { + TextBox hostTextBox = (TextBox)this.MailDomainDetailsView.FindControl("HostTextBox"); + string hostName = hostTextBox.Text; + + // Attempt to create the mail domain + LocalStoreMailDomainResult result = MailDomainDataSource.CreateMailDomain(new Host(hostName)); + + // Show the result + switch (result) + { + case LocalStoreMailDomainResult.OkSuccessful: + this.StatusMessage.Text = string.Format("Mail domain \"{0}\" created successfully!", hostName); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; + break; + + case LocalStoreMailDomainResult.AlreadyExists: + this.StatusMessage.Text = string.Format("Mail domain \"{0}\" already exists.", hostName); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + + default: + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to create mail domain \"{0}\": {1}", hostName, result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + } + + this.StatusImage.Visible = true; + } + + protected void MailDomainDetailsView_ModeChanging(object sender, DetailsViewModeEventArgs e) + { + // Redirect back to the mail domain list on canel + if (e.CancelingEdit) + { + Response.Redirect("ViewMailDomains.aspx"); + } + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -1,10 +1,11 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateUser.aspx.cs" Inherits="CreateUser" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> + <asp:Image ID="StatusImage" runat="server" Visible="false" /> + <asp:Label ID="StatusMessage" runat="server"></asp:Label> <h2>Create user</h2> <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="CreateUserDataSource" DefaultMode="Insert" ForeColor="#333333" - GridLines="None"> + GridLines="None" OnModeChanging="UserDetailsView_ModeChanging"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -19,6 +19,7 @@ protected void CreateUserDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) { + // Save the username to display in the insert callback below this.username = (string)e.InputParameters["Username"]; } @@ -26,16 +27,34 @@ { LocalStoreUserResult result = (LocalStoreUserResult)e.ReturnValue; + // Display the result of the attempt to create the user switch (result) { case LocalStoreUserResult.OkSuccessful: - LocalStoreUser user = UserDataSource.GetUser(this.username); - Response.Redirect(string.Format("UserDetails.aspx?UserId={0}", user.UserId)); + this.StatusMessage.Text = string.Format("User \"{0}\" created successfully!", this.username); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/GreenLight.png"; break; + case LocalStoreUserResult.AlreadyExists: + this.StatusMessage.Text = string.Format("User \"{0}\" already exists.", this.username); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; + break; + default: - this.StatusMessage.Text = result.ToString(); + this.StatusMessage.Text = string.Format("Unknown error occured while attempting to create the user \"{0}\": {1}", username, result.ToString()); + this.StatusImage.ImageUrl = Request.ApplicationPath + @"/Images/Tango/Error.png"; break; } + + this.StatusImage.Visible = true; } + + protected void UserDetailsView_ModeChanging(object sender, DetailsViewModeEventArgs e) + { + // Redirect back to the user list on canel + if (e.CancelingEdit) + { + Response.Redirect("ViewUsers.aspx"); + } + } } Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images ___________________________________________________________________ Name: svn:ignore + Thumbs.db Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/GreenLight.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/GreenLight.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Delete.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Delete.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Error.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Error.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Group.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Group.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/License.txt =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/License.txt (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/License.txt 2006-06-18 05:42:46 UTC (rev 47) @@ -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/branches/luke-dev/NMail.Administration.Web/Images/Tango/MailDomain.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/MailDomain.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/NewFolder.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/NewFolder.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/OpenFolder.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/OpenFolder.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Question.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Question.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Thumbs.db =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Thumbs.db ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/User.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/User.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Warning.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/Tango/Warning.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo-white.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo-white.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-18 05:42:46 UTC (rev 47) @@ -11,6 +11,16 @@ this.Response.Redirect("Login.aspx"); } } + + protected void TreeView_TreeNodeDataBound(object sender, TreeNodeEventArgs e) + { + SiteMapNode nodeFromSiteMap = (SiteMapNode)e.Node.DataItem; + + if (nodeFromSiteMap["imageUrl"] != null) + { + e.Node.ImageUrl = nodeFromSiteMap["imageUrl"]; + } + } </script> <html xmlns="http://www.w3.org/1999/xhtml" > @@ -22,15 +32,20 @@ <form id="MainForm" runat="server"> <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> <tr> - <td colspan="2" style="vertical-align: middle; width: 100%; border-bottom: darkgray thin solid; background-color: #eff3fb;"> - <h1> <img src="Images/nmail-logo.png" style="vertical-align: middle" /> NMail Web Administration</h1> + <td colspan="2" style="vertical-align: middle; width: 100%; background-color: #507cd1; border-bottom-width: thin; border-bottom-color: darkgray;"> + <h1 style="color: white"> <img src="Images/nmail-logo-white.png" style="vertical-align: middle" /> NMail Web Administration</h1> </td> </tr> <tr> - <td colspan="2" style="border-bottom: darkgray thick solid;"> + <td colspan="2" style="border-bottom: darkgray thick solid; background-color: #eff3fb;"> <table style="width: 100%"> <tr> - <td style="width: 100%"><asp:SiteMapPath ID="SiteMapPath" runat="server" /></td> + <td style="width: 100%"><asp:SiteMapPath ID="SiteMapPath" runat="server" Font-Names="Verdana" Font-Size="0.8em" PathSeparator=" : " > + <PathSeparatorStyle Font-Bold="True" ForeColor="#1C5E55" /> + <CurrentNodeStyle ForeColor="#333333" /> + <NodeStyle Font-Bold="True" ForeColor="#666666" /> + <RootNodeStyle Font-Bold="True" ForeColor="#1C5E55" /> + </asp:SiteMapPath></td> <td style="text-align: right;"><asp:LoginStatus ID="LoginStatus" runat="server" /></td> </tr> </table> @@ -38,7 +53,7 @@ </tr> <tr> <td style="border-right-style: solid; border-right-color: darkgray; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em; vertical-align: top; background-color: #eff3fb; height: 100%;"> - <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource"> + <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource" OnTreeNodeDataBound="TreeView_TreeNodeDataBound"> </asp:TreeView> <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> </td> Modified: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-18 05:42:46 UTC (rev 47) @@ -8,7 +8,9 @@ font-size: larger; } -h2 +h2 { font-size: large; + margin-bottom: 0.5em; + margin-top: 1em; } \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -1,7 +1,17 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Image ID="StatusImage" runat="server" Visible="false" /> + <asp:Label ID="StatusMessage" runat="server" Visible="False"></asp:Label> + + <asp:Panel ID="ConfirmPanel" runat="server"> + <div style="border-right: darkgray thin solid; padding-right: 0.5em; border-top: darkgray thin solid; padding-left: 0.5em; padding-bottom: 0.5em; margin: 1em; border-left: darkgray thin solid; color: red; padding-top: 0.5em; border-bottom: darkgray thin solid;"> + <img src="Images/Tango/Question.png" /> + Really delete this user? + <asp:Button ID="yesBtn" runat="server" Text="Yes" /> + <asp:Button ID="noBtn" runat="server" Text="No" /></div> + </asp:Panel> + <h2>User Details</h2> - <asp:Literal ID="StatusMessage" runat="server" Visible="False"></asp:Literal> <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> @@ -30,6 +40,7 @@ <asp:Parameter Name="userId" Type="Int32" /> </DeleteParameters> </asp:ObjectDataSource> + <h2>User's Folders</h2> <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> @@ -40,7 +51,7 @@ <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" - HeaderText="Details" Text="details" /> + Text="details" /> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> @@ -48,6 +59,9 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + The user doesn't have any folders. + </EmptyDataTemplate> </asp:GridView> <asp:ObjectDataSource ID="UserFolderDataSource" runat="server" SelectMethod="GetUserFolders" TypeName="NMail.Administration.Web.UserDataSource"> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -9,8 +9,7 @@ <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> - <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" - HeaderText="Details" Text="details" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" Text="details" /> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -1,18 +1,16 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Untitled Page" %> <asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> <h2>Mail Domains</h2> - <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource" UpdateMethod="UpdateMailDomain"> - <UpdateParameters> - <asp:Parameter Name="mailDomainId" Type="Int32" /> - <asp:Parameter Name="primaryHost" Type="String" /> - </UpdateParameters> + <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource"> </asp:ObjectDataSource> - <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" - CellPadding="4" DataSourceID="MailDomainDataSource" ForeColor="#333333" GridLines="None"> + <asp:GridView ID="GridView1" runat="server" AllowSorting="True" + CellPadding="4" DataSourceID="MailDomainDataSource" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <Columns> - <asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="MailDomainDetails.aspx?MailDomainId={0}" - HeaderText="Details" Text="details" /> + <asp:BoundField DataField="MailDomainId" HeaderText="MailDomainId" SortExpression="MailDomainId" /> + <asp:BoundField DataField="PrimaryHost" HeaderText="Primary Host" SortExpression="PrimaryHost" /> + <asp:HyperLinkField DataNavigateUrlFields="MailDomainId" DataNavigateUrlFormatString="MailDomainDetails.aspx?MailDomainId={0}" + Text="details" /> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> @@ -20,6 +18,11 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> + <EmptyDataTemplate> + There are no mail domains currently defined in the system. + </EmptyDataTemplate> </asp:GridView> + <br /> + <a href="CreateMailDomain.aspx">Create new mail domain</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-18 05:42:46 UTC (rev 47) @@ -10,8 +10,7 @@ <asp:BoundField DataField="UserFolderId" HeaderText="UserFolderId" SortExpression="UserFolderId" /> <asp:BoundField DataField="QuotaWarnLimit" HeaderText="QuotaWarnLimit" SortExpression="QuotaWarnLimit" /> <asp:BoundField DataField="QuotaHardLimit" HeaderText="QuotaHardLimit" SortExpression="QuotaHardLimit" /> - <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="UserDetails.aspx?UserId={0}" - HeaderText="Edit" Text="edit" /> + <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="UserDetails.aspx?UserId={0}" Text="details" /> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-06-18 05:42:46 UTC (rev 47) @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > - <siteMapNode url="Default.aspx" title="Home" description=""> - <siteMapNode url="Login.aspx" title="Login" description="" /> - <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" /> - <siteMapNode url="ViewUsers.aspx" title="Users" description="" /> - <siteMapNode url="ViewFolders.aspx" title="Folders" description="" /> - </siteMapNode> + <siteMapNode url="Default.aspx" title="Home" description=""> + <siteMapNode url="Login.aspx" title="Login" description="" /> + <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" imageUrl="~/Images/Tango/MailDomain.png" /> + <siteMapNode url="ViewUsers.aspx" title="Users" description="" imageUrl="~/Images/Tango/User.png" /> + <siteMapNode url="ViewFolders.aspx" title="Folders" description="" imageUrl="~/Images/Tango/OpenFolder.png" /> + </siteMapNode> </siteMap> Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -1189,18 +1189,17 @@ // TODO: check acls return this.LocalStoreData.GetMailDomains(); } - - /// <summary> - /// Adds a new mail domain. + /// <summary> + /// Creates a new mail domain for the given host. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="mailDomain">The mail domain to add.</param> + /// <param name="host">The primary host for the mail domain.</param> /// <returns>The result of the attempt to add the mail domain.</returns> - public LocalStoreMailDomainResult AddMailDomain(IAuthenticationToken authToken, MailDomain mailDomain) { - // TODO: check ACLs + public LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host host) { + // TODO: check ACLs - return this.LocalStoreData.AddMailDomain(mailDomain); - } + return this.LocalStoreData.CreateMailDomain(host); + } /// <summary> /// Deletes a mail domain from the local store. Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-14 11:45:11 UTC (rev 46) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-18 05:42:46 UTC (rev 47) @@ -1690,14 +1690,16 @@ #endregion #region Add Mail Domain - /// <summary> - /// Adds a new mail domain. + /// <summary> + /// Creates a new mail domain for the given host. /// </summary> - /// <param name="mailDomain">The mail domain to add.</param> + /// <param name="host">The primary host for the mail domain.</param> /// <returns>The result of the attempt to add the mail domain.</returns> - public LocalStoreMailDomainResult AddMailDomain(MailDomain mailDomain) { + public LocalStoreMailDomainResult CreateMailDomain(Host host) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { + MailDomain mailDomain = new MailDomain(-1, host); + cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "AddMailDomain"; cmd.Parameters.Add("PrimaryHost", mailDomain.PrimaryHost.ToString()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-14 11:45:19
|
Revision: 46 Author: tmyroadctfig Date: 2006-06-14 04:45:11 -0700 (Wed, 14 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=46&view=rev Log Message: ----------- Added file to ignore list. Property Changed: ---------------- NMail/trunk/ Property changes on: NMail/trunk ___________________________________________________________________ Name: svn:ignore - NMail.suo + NMail.suo NMail.Administration.Web.suo This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-14 11:44:06
|
Revision: 45 Author: tmyroadctfig Date: 2006-06-14 04:43:39 -0700 (Wed, 14 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=45&view=rev Log Message: ----------- Work on admin website. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderPrivilege.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderPrivilege.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderPrivilege.cs 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderPrivilege.cs 2006-06-14 11:43:39 UTC (rev 45) @@ -34,48 +34,48 @@ /// The mailbox is visible to the IMAP "LIST" and "LSUB" commands. Mailbox details /// can be obtained (e.g. message counts, etc). /// </summary> - Lookup, + Lookup = 1, /// <summary> /// The mailbox can be selected and searched and mail can be fetched, copied, etc. /// </summary> - Read, + Read = 2, /// <summary> /// The seen flag can be altered. /// </summary> - AlterSeenFlag, + AlterSeenFlag = 4, /// <summary> /// Message flags aside from seen and deleted can be altered. /// </summary> - Write, + Write = 8, /// <summary> /// Messages can be appended or copied into the mailbox. /// </summary> - Insert, + Insert = 16, /// <summary> /// Send mail to submission address for mailbox. /// </summary> - Post, + Post = 32, /// <summary> /// New sub-mailboxes can be created. /// </summary> - CreateFolders, + CreateFolders = 64, /// <summary> /// The message deleted flag can be altered. Expunge command is allowed. Mailboxes /// can be deleted. /// </summary> - Delete, + Delete = 128, /// <summary> /// ACLs can be altered on the mailbox. /// </summary> - Admin + Admin = 256 } /// <summary> Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-14 11:43:39 UTC (rev 45) @@ -18,10 +18,15 @@ namespace NMail.Administration.Web { /// <summary> - /// Summary description for FolderDataSource + /// Some simple glue code to allow an object data source to bind to + /// the NMail data model. /// </summary> public static class FolderDataSource { + /// <summary> + /// Gets a list of all folders in the local store. + /// </summary> + /// <returns>The list of folders.</returns> public static List<StoreFolder> GetFolders() { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -31,6 +36,11 @@ return new List<StoreFolder>(localStore.GetFolders(authToken)); } + /// <summary> + /// Gets the folder with the given folder Id. + /// </summary> + /// <param name="folderId">The Id of the folder to get.</param> + /// <returns>The folder or null.</returns> public static StoreFolder GetFolder(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -40,6 +50,11 @@ return localStore.GetStoreFolder(authToken, folderId); } + /// <summary> + /// Gets a folder based on its folder name. + /// </summary> + /// <param name="folderName">The name of the folder to get.</param> + /// <returns>The folder or null.</returns> public static StoreFolder GetFolder(string folderName) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -49,6 +64,11 @@ return localStore.GetStoreFolder(authToken, folderName); } + /// <summary> + /// Gets a list of sub-folder for the given folder. + /// </summary> + /// <param name="folderId">The Id of the folder to get the sub-folders for.</param> + /// <returns>The list of folders.</returns> public static List<StoreFolder> GetSubFolders(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -59,6 +79,11 @@ return new List<StoreFolder>(localStore.GetChildren(authToken, parent)); } + /// <summary> + /// Deletes the folder with the given folder Id. + /// </summary> + /// <param name="folderId">The Id of the folder to delete.</param> + /// <returns>The result of the attempt to delete the folder.</returns> public static LocalStoreFolderResult DeleteFolder(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -68,6 +93,11 @@ return localStore.DeleteFolder(authToken, folderId); } + /// <summary> + /// Creates a new folder. + /// </summary> + /// <param name="folderName">The name of the folder to create.</param> + /// <returns>The result of the attempt to create the folder.</returns> public static LocalStoreFolderResult CreateFolder(string folderName) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -77,23 +107,227 @@ return localStore.CreateFolder(authToken, folderName); } - public static List<GenericAce<StoreFolderPrivilege>> GetFolderAcl(int folderId) + /// <summary> + /// Gets a list of access control entries for the given folder. + /// </summary> + /// <param name="folderId">The folder to get the ACL for.</param> + /// <returns>The list of ACEs.</returns> + public static List<StoreFolderAce> GetFolderAcl(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; StoreFolderAcl acl = localStore.GetStoreFolderAcl(authToken, folderId); - List<GenericAce<StoreFolderPrivilege>> result = new List<GenericAce<StoreFolderPrivilege>>(); + List<StoreFolderAce> result = new List<StoreFolderAce>(); IEnumerator<string> e = acl.GetIdentifiers(); while (e.MoveNext()) { GenericAce<StoreFolderPrivilege> ace = acl[e.Current]; - result.Add(ace); + result.Add(new StoreFolderAce(ace.Identifier, ace.Privilege, ace.AceType)); } return result; } + + public static void SetStoreFolderAce(int folderId, string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + StoreFolder folder = localStore.GetStoreFolder(authToken, folderId); + GenericAce<StoreFolderPrivilege> ace = new GenericAce<StoreFolderPrivilege>(identifier, privilege, aceType); + localStore.SetStoreFolderAce(authToken, folder, ace); + } + + public static void RemoveStoreFolderAce(int folderId, string identifier) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + StoreFolder folder = localStore.GetStoreFolder(authToken, folderId); + localStore.RemoveStoreFolderAce(authToken, folder, identifier); + } } + + public class StoreFolderAce : GenericAce<StoreFolderPrivilege> + { + public StoreFolderAce(string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) + : base(identifier, privilege, aceType) + { } + + public bool AdministrativePrivileges + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Admin) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Admin); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Admin); + } + } + } + + public bool CanAlterSeenFlag + { + get + { + return ((this.Privilege & StoreFolderPrivilege.AlterSeenFlag) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.AlterSeenFlag); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.AlterSeenFlag); + } + } + } + + public bool CanCreateFolders + { + get + { + return ((this.Privilege & StoreFolderPrivilege.CreateFolders) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.CreateFolders); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.CreateFolders); + } + } + } + + public bool CanDelete + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Delete) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Delete); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Delete); + } + } + } + + public bool CanInsert + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Insert) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Insert); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Insert); + } + } + } + + public bool CanLookup + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Lookup) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Lookup); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Lookup); + } + } + } + + public bool CanPost + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Post) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Post); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Post); + } + } + } + + public bool CanRead + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Read) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Read); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Read); + } + } + } + + public bool CanWrite + { + get + { + return ((this.Privilege & StoreFolderPrivilege.Write) != 0); + } + set + { + if (value) + { + this.Privilege = StoreFolderPrivilegeHelper.AddPrivileges(this.Privilege, StoreFolderPrivilege.Write); + } + else + { + this.Privilege = StoreFolderPrivilegeHelper.RemovePrivileges(this.Privilege, StoreFolderPrivilege.Write); + } + } + } + } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs 2006-06-14 11:43:39 UTC (rev 45) @@ -17,10 +17,15 @@ namespace NMail.Administration.Web { /// <summary> - /// Summary description for UserDataSource + /// Some simple glue code to allow an object data source to bind to + /// the NMail data model. /// </summary> public static class UserDataSource { + /// <summary> + /// Gets all users in the system. + /// </summary> + /// <returns>The list of users.</returns> public static List<LocalStoreUser> GetUsers() { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -32,6 +37,11 @@ return new List<LocalStoreUser>(users); } + /// <summary> + /// Gets the user that matches the given username. + /// </summary> + /// <param name="username">The name of the user to lookup.</param> + /// <returns>The user or null.</returns> public static LocalStoreUser GetUser(string username) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-14 11:43:39 UTC (rev 45) @@ -57,7 +57,7 @@ </SelectParameters> </asp:ObjectDataSource> <h2>Folder ACL</h2> - <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource"> + <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource" ShowFooter="True"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> @@ -66,16 +66,154 @@ <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> <Columns> - <asp:BoundField DataField="Identifier" HeaderText="Identifier" SortExpression="Identifier" /> - <asp:BoundField DataField="Privilege" HeaderText="Privilege" SortExpression="Privilege" /> - <asp:BoundField DataField="AceType" HeaderText="AceType" SortExpression="AceType" /> + <asp:TemplateField> + <EditItemTemplate><!-- Don't show in edit --></EditItemTemplate> + <ItemTemplate> + <asp:LinkButton ID="DeleteLinkBtn" runat="server" OnClientClick="return confirm('Really delete this ACL entry?');" CommandName="Delete">Delete conf</asp:LinkButton> + </ItemTemplate> + <FooterTemplate> + <asp:Button ID="CancelInsertAclEntryBtn" runat="server" Text="Cancel" OnClick="CancelInsertAclEntryBtn_Click"/> + <asp:Button ID="InsertAclEntryBtn" runat="server" Text="Insert" OnClick="InsertAclEntryBtn_Click"/> + </FooterTemplate> + </asp:TemplateField> + <asp:CommandField ShowEditButton="True" /> + <asp:TemplateField HeaderText="Identifier" SortExpression="Identifier"> + <EditItemTemplate> + <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Identifier") %>'></asp:TextBox> + </EditItemTemplate> + <ItemTemplate> + <asp:Label ID="Label1" runat="server" Text='<%# Bind("Identifier") %>'></asp:Label> + </ItemTemplate> + <FooterTemplate> + <asp:TextBox ID="NewIdentifier" runat="server"></asp:TextBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Insert" SortExpression="CanInsert"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("CanInsert") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("CanInsert") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanInsert" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Post" SortExpression="CanPost"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("CanPost") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("CanPost") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanPost" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Lookup" SortExpression="CanLookup"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("CanLookup") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("CanLookup") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanLookup" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Write" SortExpression="CanWrite"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("CanWrite") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("CanWrite") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanWrite" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Read" SortExpression="CanRead"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("CanRead") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("CanRead") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanRead" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Create Sub-folders" SortExpression="CanCreateFolders"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("CanCreateFolders") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("CanCreateFolders") %>' + Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanCreateSubFolders" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Delete" SortExpression="CanDelete"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("CanDelete") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("CanDelete") %>' Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanDelete" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Alter Seen Flag" SortExpression="CanAlterSeenFlag"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("CanAlterSeenFlag") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("CanAlterSeenFlag") %>' + Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanAlterSeenFlag" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> + <asp:TemplateField HeaderText="Admin" SortExpression="AdministrativePrivileges"> + <EditItemTemplate> + <asp:CheckBox ID="CheckBox9" runat="server" Checked='<%# Bind("AdministrativePrivileges") %>' /> + </EditItemTemplate> + <ItemTemplate> + <asp:CheckBox ID="CheckBox9" runat="server" Checked='<%# Bind("AdministrativePrivileges") %>' + Enabled="false" /> + </ItemTemplate> + <FooterTemplate> + <asp:CheckBox ID="NewCanAdmin" runat="server"></asp:CheckBox> + </FooterTemplate> + </asp:TemplateField> </Columns> </asp:GridView> <asp:ObjectDataSource ID="FolderAclDataSource" runat="server" SelectMethod="GetFolderAcl" - TypeName="NMail.Administration.Web.FolderDataSource"> + TypeName="NMail.Administration.Web.FolderDataSource" OnUpdating="FolderAclDataSource_Updating" UpdateMethod="SetStoreFolderAce" DeleteMethod="RemoveStoreFolderAce" InsertMethod="SetStoreFolderAce" OnDeleting="FolderAclDataSource_Deleting" OnInserting="FolderAclDataSource_Inserting"> <SelectParameters> <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> </SelectParameters> + <UpdateParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + <asp:Parameter Name="privilege" Type="Object" /> + <asp:Parameter Name="aceType" Type="Object" /> + </UpdateParameters> + <DeleteParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + </DeleteParameters> + <InsertParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + <asp:Parameter Name="identifier" Type="String" /> + <asp:Parameter Name="privilege" Type="Object" /> + <asp:Parameter Name="aceType" Type="Object" /> + </InsertParameters> </asp:ObjectDataSource> + <asp:LinkButton ID="ShowInsertAclEntryBtn" runat="server" OnClick="ShowInsertAclEntryBtn_Click">Insert ACL Entry</asp:LinkButton> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-14 11:43:39 UTC (rev 45) @@ -10,9 +10,17 @@ using System.Web.UI.HtmlControls; using NMail; +using NMail.DataTypes.ACLs; public partial class FolderDetails : System.Web.UI.Page { + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + this.AclGridView.ShowFooter = false; + } + protected void FolderDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) { e.InputParameters["folderId"] = Request.QueryString["FolderId"]; @@ -37,4 +45,152 @@ break; } } + + protected void FolderAclDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) + { + StoreFolderPrivilege privilege = StoreFolderPrivilege.None; + + if ((bool)e.InputParameters["NewCanAdmin"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Admin); + } + + if ((bool)e.InputParameters["NewCanAlterSeenFlag"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.AlterSeenFlag); + } + + if ((bool)e.InputParameters["NewCanCreateSubFolders"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.CreateFolders); + } + + if ((bool)e.InputParameters["NewCanDelete"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Delete); + } + + if ((bool)e.InputParameters["NewCanInsert"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Insert); + } + + if ((bool)e.InputParameters["NewCanLookup"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Lookup); + } + + if ((bool)e.InputParameters["NewCanPost"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Post); + } + + if ((bool)e.InputParameters["NewCanRead"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Read); + } + + if ((bool)e.InputParameters["NewCanWrite"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Write); + } + + string identifier = (string)e.InputParameters["NewIdentifier"]; + + e.InputParameters.Clear(); + + e.InputParameters["Identifier"] = identifier; + e.InputParameters["FolderId"] = this.Request.QueryString["FolderId"]; + e.InputParameters["Privilege"] = privilege; + e.InputParameters["AceType"] = AcePrivilegeType.Allow; + } + + protected void FolderAclDataSource_Updating(object sender, ObjectDataSourceMethodEventArgs e) + { + StoreFolderPrivilege privilege = StoreFolderPrivilege.None; + + if ((bool)e.InputParameters["AdministrativePrivileges"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Admin); + } + + if ((bool)e.InputParameters["CanAlterSeenFlag"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.AlterSeenFlag); + } + + if ((bool)e.InputParameters["CanCreateFolders"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.CreateFolders); + } + + if ((bool)e.InputParameters["CanDelete"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Delete); + } + + if ((bool)e.InputParameters["CanInsert"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Insert); + } + + if ((bool)e.InputParameters["CanLookup"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Lookup); + } + + if ((bool)e.InputParameters["CanPost"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Post); + } + + if ((bool)e.InputParameters["CanRead"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Read); + } + + if ((bool)e.InputParameters["CanWrite"]) + { + privilege = StoreFolderPrivilegeHelper.AddPrivileges(privilege, StoreFolderPrivilege.Write); + } + + string identifier = (string)e.InputParameters["Identifier"]; + + e.InputParameters.Clear(); + + e.InputParameters["Identifier"] = identifier; + e.InputParameters["FolderId"] = this.Request.QueryString["FolderId"]; + e.InputParameters["Privilege"] = privilege; + e.InputParameters["AceType"] = AcePrivilegeType.Allow; + } + + protected void FolderAclDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) + { + string identifier = (string)e.InputParameters["Identifier"]; + + e.InputParameters.Clear(); + + e.InputParameters["Identifier"] = identifier; + e.InputParameters["FolderId"] = this.Request.QueryString["FolderId"]; + } + + protected void ShowInsertAclEntryBtn_Click(object sender, EventArgs e) + { + this.AclGridView.ShowFooter = true; + this.ShowInsertAclEntryBtn.Visible = false; + } + + protected void CancelInsertAclEntryBtn_Click(object sender, EventArgs e) + { + this.AclGridView.ShowFooter = false; + this.ShowInsertAclEntryBtn.Visible = true; + } + + protected void InsertAclEntryBtn_Click(object sender, EventArgs e) + { + this.AclGridView.ShowFooter = false; + this.ShowInsertAclEntryBtn.Visible = false; + + this.FolderAclDataSource.Insert(); + } } Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-07 09:30:26 UTC (rev 44) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-14 11:43:39 UTC (rev 45) @@ -1807,7 +1807,7 @@ string identifer = (string) reader["Identifier"]; uint privilegeValue = (uint) reader["Privilege"]; SystemPrivilege privilege = (SystemPrivilege) privilegeValue; - bool allowValue = (bool) reader["Allow"]; + bool allowValue = ((sbyte) reader["Allow"] == 1) ? true : false; AcePrivilegeType allow = (allowValue) ? AcePrivilegeType.Allow : AcePrivilegeType.Deny; result.SetAce(new GenericAce<SystemPrivilege>(identifer, privilege, allow)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-07 09:46:27
|
Revision: 44 Author: tmyroadctfig Date: 2006-06-07 02:30:26 -0700 (Wed, 07 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=44&view=rev Log Message: ----------- Added initial ACL support to web interface. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -23,6 +23,7 @@ /// <summary> /// A generic access control entry for an ACL. /// </summary> + [Serializable] public class GenericAce<PrivilegeType> { /// <summary> /// Creates a new access control entry. Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -16,6 +16,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Text; @@ -23,6 +24,7 @@ /// <summary> /// A list of access control entries. /// </summary> + [Serializable] public class GenericAcl<PrivilegeType> { /// <summary> /// A map of identifiers to access control entries. Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -23,6 +23,7 @@ /// <summary> /// A list of access control entries for a folder. /// </summary> + [Serializable] public class StoreFolderAcl : GenericAcl<StoreFolderPrivilege> { /// <summary> /// Creates a new ACL for the given folder. Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -331,9 +331,9 @@ /// Gets the ACL for the given folder. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="folder">The folder to get the ACL for.</param> + /// <param name="folderId">The Id of the folder to get the ACL for.</param> /// <returns>The folder ACL or null if insufficient privileges.</returns> - StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, StoreFolder folder); + StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, int folderId); #endregion #region Load and Save Object Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -292,9 +292,9 @@ /// <summary> /// Gets the ACL for the given folder. /// </summary> - /// <param name="folder">The folder to get the ACL for.</param> + /// <param name="folderId">The Id of the folder to get the ACL for.</param> /// <returns>The folder ACL.</returns> - StoreFolderAcl GetStoreFolderAcl(StoreFolder folder); + StoreFolderAcl GetStoreFolderAcl(int folderId); #endregion #region User Management Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -77,13 +77,23 @@ return localStore.CreateFolder(authToken, folderName); } - public static StoreFolderAcl GetFolderAcl(int folderId) + public static List<GenericAce<StoreFolderPrivilege>> GetFolderAcl(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; - return localStore.GetStoreFolderAcl(authToken, folderId); + StoreFolderAcl acl = localStore.GetStoreFolderAcl(authToken, folderId); + List<GenericAce<StoreFolderPrivilege>> result = new List<GenericAce<StoreFolderPrivilege>>(); + + IEnumerator<string> e = acl.GetIdentifiers(); + while (e.MoveNext()) + { + GenericAce<StoreFolderPrivilege> ace = acl[e.Current]; + result.Add(ace); + } + + return result; } } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-07 09:30:26 UTC (rev 44) @@ -57,7 +57,7 @@ </SelectParameters> </asp:ObjectDataSource> <h2>Folder ACL</h2> - <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"> + <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataSourceID="FolderAclDataSource"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> @@ -65,6 +65,17 @@ <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> + <Columns> + <asp:BoundField DataField="Identifier" HeaderText="Identifier" SortExpression="Identifier" /> + <asp:BoundField DataField="Privilege" HeaderText="Privilege" SortExpression="Privilege" /> + <asp:BoundField DataField="AceType" HeaderText="AceType" SortExpression="AceType" /> + </Columns> </asp:GridView> + <asp:ObjectDataSource ID="FolderAclDataSource" runat="server" SelectMethod="GetFolderAcl" + TypeName="NMail.Administration.Web.FolderDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> </asp:Content> Modified: NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -390,7 +390,7 @@ StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { - StoreFolderAcl folderAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder); + StoreFolderAcl folderAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder.FolderId); if (folderAcl != null) { currentAce = folderAcl[cmd.Identifier]; @@ -458,7 +458,7 @@ StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { - StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder); + StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder.FolderId); if (currentAcl != null) { IEnumerator<string> e = currentAcl.GetIdentifiers(); @@ -493,7 +493,7 @@ StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { - StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder); + StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder.FolderId); if (currentAcl != null) { if (currentAcl[cmd.Identifier] != null) { @@ -523,7 +523,7 @@ StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { - StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder); + StoreFolderAcl currentAcl = LocalStore.GetStoreFolderAcl(Session.AuthenticationToken, folder.FolderId); if (currentAcl != null) { string username = Session.AuthenticationToken.Username; Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -1163,13 +1163,13 @@ } } - public StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, StoreFolder folder) { + public StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, int folderId) { // Ensure the user has rights to lookup the ACL - if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup) + if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Lookup) || hasSystemPrivilege(authToken.Username, SystemPrivilege.EditAllAcls)) { // Return the ACL - StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); + StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folderId); return currentAcl; } else { @@ -1344,7 +1344,7 @@ // First check if the user has the required privilege on the folder StoreFolder folder = LocalStoreData.GetStoreFolder(folderId); - StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); + StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folderId); GenericAce<StoreFolderPrivilege> userAce = currentAcl[username]; if (privilege != StoreFolderPrivilege.None) { Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-06 12:55:52 UTC (rev 43) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-07 09:30:26 UTC (rev 44) @@ -1602,7 +1602,8 @@ #endregion #region Get StoreFolder ACL - public StoreFolderAcl GetStoreFolderAcl(StoreFolder folder) { + public StoreFolderAcl GetStoreFolderAcl(int folderId) { + StoreFolder folder = getStoreFolder(folderId); StoreFolderAcl result = new StoreFolderAcl(folder); using (MySqlConnection cnn = GetConnection()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-06 17:07:45
|
Revision: 41 Author: tmyroadctfig Date: 2006-06-06 04:32:51 -0700 (Tue, 06 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=41&view=rev Log Message: ----------- Work on web administration interface and local store. Modified Paths: -------------- NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail/NMail.csproj NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo.png NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx NMail/branches/luke-dev/NMail.ImapService/Response/AclResponse.cs NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Added Paths: ----------- NMail/branches/luke-dev/NMail/DataTypes/ACLs/SystemPrivilege.cs NMail/branches/luke-dev/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs Removed Paths: ------------- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAce.cs Modified: NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs =================================================================== --- NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/Authentication/IAuthenticationProvider.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -17,6 +17,8 @@ using System; +using NMail.DataTypes.ACLs; + namespace NMail.Authentication { /// <summary> /// The interface for an authentication provider that operates on username and Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -23,14 +23,16 @@ /// <summary> /// A generic access control entry for an ACL. /// </summary> - public class GenericAce { + public class GenericAce<PrivilegeType> { /// <summary> /// Creates a new access control entry. /// </summary> /// <param name="identifier">The identifier to associated the ACE with.</param> + /// <param name="privilege">The privileges.</param> /// <param name="acePrivilegeType">Whether to allow or deny the privileges.</param> - public GenericAce(string identifier, AcePrivilegeType acePrivilegeType) { + public GenericAce(string identifier, PrivilegeType privilege, AcePrivilegeType acePrivilegeType) { this.identifier = identifier; + this.privilege = privilege; this.acePrivilegeType = acePrivilegeType; } @@ -48,6 +50,20 @@ } } + private PrivilegeType privilege; + + /// <summary> + /// The privilege associated with this ACE. + /// </summary> + public PrivilegeType Privilege { + get { + return this.privilege; + } + set { + this.privilege = value; + } + } + private AcePrivilegeType acePrivilegeType; /// <summary> Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -23,40 +23,23 @@ /// <summary> /// A list of access control entries. /// </summary> - public class GenericAcl<AceType> where AceType : GenericAce { + public class GenericAcl<PrivilegeType> { /// <summary> /// A map of identifiers to access control entries. /// </summary> - protected Dictionary<string, AceType> entries = new Dictionary<string, AceType>(StringComparer.InvariantCultureIgnoreCase); + protected Dictionary<string, GenericAce<PrivilegeType>> entries = new Dictionary<string, GenericAce<PrivilegeType>>(StringComparer.InvariantCultureIgnoreCase); /// <summary> - /// Creates a new ACL for the given resource name. + /// Creates a new ACL. /// </summary> - /// <param name="resourceName">The name of the resource this ACL is for.</param> - public GenericAcl(string resourceName) { - this.resourceName = resourceName; - } + public GenericAcl() {} - private string resourceName; - /// <summary> - /// The name of the resource this ACL is associated wtih. - /// </summary> - public string ResourceName { - get { - return this.resourceName; - } - set { - this.resourceName = value; - } - } - - /// <summary> /// Replaces the existing ACE for the associated identifier. If no ACE exists /// for the given identifer the new ACE is simply added. /// </summary> /// <param name="ace">The ACE to set.</param> - public void SetAce(AceType ace) { + public void SetAce(GenericAce<PrivilegeType> ace) { lock (this) { if (this.entries.ContainsKey(ace.Identifier)) { this.entries.Remove(ace.Identifier); @@ -90,7 +73,7 @@ /// </summary> /// <param name="identifier">The identifier to look up.</param> /// <returns>The identifier or null if non is found.</returns> - public AceType this[string identifier] { + public GenericAce<PrivilegeType> this[string identifier] { get { lock (this) { if (this.entries.ContainsKey(identifier)) { Deleted: NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAce.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAce.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAce.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -1,53 +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; -using System.Collections.Generic; -using System.Text; - -namespace NMail.DataTypes.ACLs { - /// <summary> - /// An access control entry for a store folder ACL. - /// </summary> - public class StoreFolderAce : GenericAce { - /// <summary> - /// Creates a new access control entry. - /// </summary> - /// <param name="identifier">The identifier to associated the ACE with.</param> - /// <param name="privilege">The privileges.</param> - /// <param name="aceType">Whether to allow or deny the privileges.</param> - public StoreFolderAce(string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) - : base(identifier, aceType) { - - this.privilege = privilege; - } - - private StoreFolderPrivilege privilege; - - /// <summary> - /// The privilege associated with this ACE. - /// </summary> - public StoreFolderPrivilege Privilege { - get { - return this.privilege; - } - set { - this.privilege = value; - } - } - } -} Modified: NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -21,14 +21,14 @@ namespace NMail.DataTypes.ACLs { /// <summary> - /// A list of access control entries. + /// A list of access control entries for a folder. /// </summary> - public class StoreFolderAcl : GenericAcl<StoreFolderAce> { + public class StoreFolderAcl : GenericAcl<StoreFolderPrivilege> { /// <summary> /// Creates a new ACL for the given folder. /// </summary> /// <param name="folder">The folder associated with the ACL.</param> - public StoreFolderAcl(StoreFolder folder) : base(folder.FolderId.ToString()) { + public StoreFolderAcl(StoreFolder folder) : base() { this.folder = folder; } Added: NMail/branches/luke-dev/NMail/DataTypes/ACLs/SystemPrivilege.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/SystemPrivilege.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/SystemPrivilege.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.DataTypes.ACLs { + /// <summary> + /// The possible privileges a user or group can have on the NMail system. + /// </summary> + [FlagsAttribute] + public enum SystemPrivilege : uint { + /// <summary> + /// No rights are granted. + /// </summary> + None = 0, + + /// <summary> + /// The right to view the system privilege ACL. + /// </summary> + ViewSystemPrivileges = 1, + + /// <summary> + /// The right to modify the system privilege ACL. + /// </summary> + ModifySystemPrivileges = 2, + + /// <summary> + /// The right to edit any ACLs. + /// </summary> + EditAllAcls = 4, + + /// <summary> + /// The right to create a new mail domain. + /// </summary> + CreateMailDomain = 8 + } +} Added: NMail/branches/luke-dev/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs (rev 0) +++ NMail/branches/luke-dev/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.DataTypes.ACLs { + /// <summary> + /// The possible privileges a user or group can have for editing other users and + /// groups. + /// </summary> + [FlagsAttribute] + public enum UserGroupAdminPrivilege : uint { + /// <summary> + /// No rights are granted. + /// </summary> + None = 0, + + /// <summary> + /// The right to view all users in the system. + /// </summary> + ViewAllUsers = 1, + + /// <summary> + /// The right to create new users. + /// </summary> + CreateUsers = 2, + + /// <summary> + /// The right to edit existing users. + /// </summary> + EditUsers = 4, + + /// <summary> + /// The right to delete existing users. + /// </summary> + DeleteUsers = 8, + + /// <summary> + /// The right to view all groups in the system. + /// </summary> + ViewAllGroups = 16, + + /// <summary> + /// The right to create new groups. + /// </summary> + CreateGroups = 32, + + /// <summary> + /// The right to edit existing groups. + /// </summary> + EditGroups = 64, + + /// <summary> + /// The right to delete existing groups. + /// </summary> + DeleteGroups = 128 + } +} Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -140,6 +140,13 @@ /// <param name="parent">The parent to get the children from.</param> /// <returns>The list of folders.</returns> StoreFolder[] GetChildren(IAuthenticationToken authToken, StoreFolder parent); + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of folders.</returns> + StoreFolder[] GetFolders(IAuthenticationToken authToken); #endregion #region Folder Subscription @@ -310,7 +317,7 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="folder">The folder to set the ACE on.</param> /// <param name="ace">The privileges and the identifier to put.</param> - void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, StoreFolderAce ace); + void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, GenericAce<StoreFolderPrivilege> ace); /// <summary> /// Removes any ACE associated with the given user. @@ -583,6 +590,54 @@ /// <returns>The list of user Ids.</returns> int[] GetMailDomainUsers(IAuthenticationToken authToken, int mailDomainId); #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetSystemPrivilegeAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveSystemPrivilegeAce(IAuthenticationToken authToken, string identifier); + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The system ACL or null if insufficient privileges.</returns> + GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(IAuthenticationToken authToken); + #endregion + + #region User and Group Administration + /// <summary> + /// Get the ACL that lists user's privileges for user and group administration. + /// </summary> + /// <param name="user">The user trying to get the admin ACL.</param> + /// <returns>The ACL or null if insufficient privileges.</returns> + GenericAcl<UserGroupAdminPrivilege> GetAdministrationAcl(IAuthenticationToken user); + + /// <summary> + /// Sets the administration privileges for the associated identifier. + /// If no ACE exists for the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetAdministrationAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveAdministrationAce(IAuthenticationToken authToken, string identifier); + #endregion } /// <summary> Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -109,6 +109,12 @@ /// <param name="parent">The parent to get the children from.</param> /// <returns>The list of folders.</returns> StoreFolder[] GetChildren(StoreFolder parent); + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <returns>The list of folders.</returns> + StoreFolder[] GetFolders(); #endregion #region Folder Subscription @@ -274,7 +280,7 @@ /// </summary> /// <param name="folder">The folder to set the ACE on.</param> /// <param name="ace">The privileges and the identifier to put.</param> - void SetStoreFolderAce(StoreFolder folder, StoreFolderAce ace); + void SetStoreFolderAce(StoreFolder folder, GenericAce<StoreFolderPrivilege> ace); /// <summary> /// Removes any ACE associated with the given user. @@ -491,5 +497,26 @@ /// <returns>The list of user Ids.</returns> int[] GetMailDomainUsers(int mailDomainId); #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetSystemPrivilegeAce(GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveSystemPrivilegeAce(string identifier); + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <returns>The system ACL.</returns> + GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(); + #endregion } } Modified: NMail/branches/luke-dev/NMail/NMail.csproj =================================================================== --- NMail/branches/luke-dev/NMail/NMail.csproj 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail/NMail.csproj 2006-06-06 11:32:51 UTC (rev 41) @@ -122,12 +122,13 @@ <Compile Include="Configuration\ObjectConfigurationElement.cs" /> <Compile Include="Configuration\ObjectConfigurationElementCollection.cs" /> <Compile Include="Configuration\WildcardHostElementCollection.cs" /> + <Compile Include="DataTypes\ACLs\SystemPrivilege.cs" /> <Compile Include="DataTypes\ACLs\GenericAce.cs" /> <Compile Include="DataTypes\ACLs\GenericAcl.cs" /> <Compile Include="DataTypes\ACLs\MailDomainPrivilege.cs" /> - <Compile Include="DataTypes\ACLs\StoreFolderAce.cs" /> <Compile Include="DataTypes\ACLs\StoreFolderAcl.cs" /> <Compile Include="DataTypes\ACLs\StoreFolderPrivilege.cs" /> + <Compile Include="DataTypes\ACLs\UserGroupAdminPrivilege.cs" /> <Compile Include="DataTypes\LocalStoreGroup.cs" /> <Compile Include="DataTypes\ByteString.cs"> <SubType>Code</SubType> Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -13,6 +13,7 @@ using NMail; using NMail.Authentication; using NMail.DataTypes; +using NMail.DataTypes.ACLs; namespace NMail.Administration.Web { @@ -27,8 +28,7 @@ IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; ILocalStore localStore = (ILocalStore)session["LocalStore"]; - //return new List<StoreFolder>(localStore.GetStoreFolder(authToken)); - return null; + return new List<StoreFolder>(localStore.GetFolders(authToken)); } public static StoreFolder GetFolder(int folderId) @@ -40,6 +40,15 @@ return localStore.GetStoreFolder(authToken, folderId); } + public static StoreFolder GetFolder(string folderName) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.GetStoreFolder(authToken, folderName); + } + public static List<StoreFolder> GetSubFolders(int folderId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -67,5 +76,14 @@ return localStore.CreateFolder(authToken, folderName); } + + public static StoreFolderAcl GetFolderAcl(int folderId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.GetStoreFolderAcl(authToken, folderId); + } } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -32,6 +32,15 @@ return new List<LocalStoreUser>(users); } + public static LocalStoreUser GetUser(string username) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.GetUser(authToken, username); + } + public static LocalStoreUser GetUser(int userId) { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); @@ -58,5 +67,14 @@ return new List<StoreFolder>(localStore.GetUserFolders(authToken, userId)); } + + public static LocalStoreUserResult CreateUesr(string Username, int? QuotaWarnLimit, int? QuotaHardLimit) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.CreateUser(authToken, Username, QuotaWarnLimit, QuotaHardLimit); + } } } Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,27 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateFolder.aspx.cs" Inherits="CreateFolder" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>Create New Folder</h2> + <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> + <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" + ForeColor="#333333" GridLines="None" DefaultMode="Insert" DataSourceID="CreateFolderDataSource" AutoGenerateInsertButton="True"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" SortExpression="FolderName" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="CreateFolderDataSource" runat="server" InsertMethod="CreateFolder" + OnInserted="FolderDataSource_Inserted" OnInserting="FolderDataSource_Inserting" + SelectMethod="GetFolders" TypeName="NMail.Administration.Web.FolderDataSource"> + <InsertParameters> + <asp:Parameter Name="folderName" Type="String" /> + </InsertParameters> + </asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateFolder.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,41 @@ +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; + +using NMail; +using NMail.DataTypes; +using NMail.Administration.Web; + +public partial class CreateFolder : System.Web.UI.Page +{ + private string folderName; + + protected void FolderDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) + { + this.folderName = (string) e.InputParameters["FolderName"]; + } + + protected void FolderDataSource_Inserted(object sender, ObjectDataSourceStatusEventArgs e) + { + LocalStoreFolderResult result = (LocalStoreFolderResult)e.ReturnValue; + + switch (result) + { + case LocalStoreFolderResult.OkSuccessful: + StoreFolder folder = FolderDataSource.GetFolder(this.folderName); + Response.Redirect(string.Format("FolderDetails.aspx?FolderId={0}", folder.FolderId)); + break; + + default: + this.StatusMessage.Text = result.ToString(); + break; + } + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,33 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="CreateUser.aspx.cs" Inherits="CreateUser" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> + <h2>Create user</h2> + <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" + DataSourceID="CreateUserDataSource" DefaultMode="Insert" ForeColor="#333333" + GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> + <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Warn Quota" SortExpression="QuotaWarnLimit" /> + <asp:BoundField DataField="QuotaHardLimit" HeaderText="Hard Quota" SortExpression="QuotaHardLimit" /> + <asp:CommandField ShowInsertButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="CreateUserDataSource" runat="server" InsertMethod="CreateUesr" + OnInserted="CreateUserDataSource_Inserted" OnInserting="CreateUserDataSource_Inserting" + SelectMethod="GetUsers" TypeName="NMail.Administration.Web.UserDataSource"> + <InsertParameters> + <asp:Parameter Name="username" Type="String" /> + <asp:Parameter Name="QuotaWarnLimit" Type="Int32" /> + <asp:Parameter Name="QuotaHardLimit" Type="Int32" /> + </InsertParameters> + </asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/CreateUser.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -0,0 +1,41 @@ +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; + +using NMail; +using NMail.DataTypes; +using NMail.Administration.Web; + +public partial class CreateUser : System.Web.UI.Page +{ + private string username; + + protected void CreateUserDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) + { + this.username = (string)e.InputParameters["Username"]; + } + + protected void CreateUserDataSource_Inserted(object sender, ObjectDataSourceStatusEventArgs e) + { + LocalStoreUserResult result = (LocalStoreUserResult)e.ReturnValue; + + switch (result) + { + case LocalStoreUserResult.OkSuccessful: + LocalStoreUser user = UserDataSource.GetUser(this.username); + Response.Redirect(string.Format("UserDetails.aspx?UserId={0}", user.UserId)); + break; + + default: + this.StatusMessage.Text = result.ToString(); + break; + } + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -1,17 +1,6 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %> -<script runat="server"> - - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } -</script> - <asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> - Where here! + Welcome to the NMail administration website. </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -12,15 +12,15 @@ <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" InsertVisible="False" /> - <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" /> - <asp:CommandField ShowDeleteButton="True" ShowInsertButton="True" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" ReadOnly="True" /> + <asp:CommandField ShowDeleteButton="True" /> </Fields> <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> <asp:ObjectDataSource ID="FolderDataSource" runat="server" SelectMethod="GetFolder" - TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder" OnInserting="FolderDataSource_Inserting"> + TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder"> <SelectParameters> <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> </SelectParameters> @@ -56,5 +56,15 @@ <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> + <h2>Folder ACL</h2> + <asp:GridView ID="AclGridView" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -13,14 +13,6 @@ public partial class FolderDetails : System.Web.UI.Page { - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } - protected void FolderDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) { e.InputParameters["folderId"] = Request.QueryString["FolderId"]; @@ -32,13 +24,17 @@ switch (result) { + case LocalStoreFolderResult.OkSuccessful: + this.StatusMessage.Text = "Folder deleted."; + break; + case LocalStoreFolderResult.HasChildren: this.StatusMessage.Text = "Cannot delete the folder because it still has sub-folders."; break; + + default: + this.StatusMessage.Text = result.ToString(); + break; } } - protected void FolderDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) - { - - } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo.png =================================================================== (Binary files differ) Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -10,12 +10,5 @@ using System.Web.UI.HtmlControls; public partial class MailDomainDetails : System.Web.UI.Page -{ - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } +{ } Modified: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-06-06 11:32:51 UTC (rev 41) @@ -2,18 +2,28 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<script runat="server"> + + protected void Page_Load(object sender, EventArgs e) + { + if (!this.Request.IsAuthenticated && !this.Request.Url.AbsoluteUri.EndsWith("Login.aspx")) + { + this.Response.Redirect("Login.aspx"); + } + } +</script> + <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> </head> <body> - <form id="form1" runat="server"> - <div> - <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> + <form id="MainForm" runat="server"> + <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> <tr> - <td colspan="2" style="vertical-align: middle; width: 100%; border-bottom: darkgray thin solid;"> - <h1><img src="Images/nmail-logo.png" style="vertical-align: middle" /> NMail Web Administration</h1> + <td colspan="2" style="vertical-align: middle; width: 100%; border-bottom: darkgray thin solid; background-color: #eff3fb;"> + <h1> <img src="Images/nmail-logo.png" style="vertical-align: middle" /> NMail Web Administration</h1> </td> </tr> <tr> @@ -27,22 +37,21 @@ </td> </tr> <tr> - <td style="border-right-style: solid; border-right-color: darkgray; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em;"> + <td style="border-right-style: solid; border-right-color: darkgray; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em; vertical-align: top; background-color: #eff3fb; height: 100%;"> <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource"> </asp:TreeView> <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> - </td> - <td style="width: 100%; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em;"> + </td> + <td style="width: 100%; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em; vertical-align: top;"> <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> </asp:ContentPlaceHolder> </td> </tr> <tr> - <td colspan="2" style="border-top-style: solid; border-top-color: darkgray;"> - <a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> + <td style="border-right-style: solid; background-color: #eff3fb; text-align: center; border-right-color: darkgray; top: 100%;"><a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> + <td style="height: 18px"></td> </tr> </table> - </div> </form> </body> </html> Modified: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-06-06 11:32:51 UTC (rev 41) @@ -2,3 +2,13 @@ { font-family: Sans-Serif; } + +h1 +{ + font-size: larger; +} + +h2 +{ + font-size: large; +} \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -31,12 +31,4 @@ break; } } - - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -1,5 +1,6 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>Folders</h2> <asp:GridView ID="FoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="FoldersDataSource" ForeColor="#333333" GridLines="None"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> @@ -20,5 +21,7 @@ </asp:GridView> <asp:ObjectDataSource ID="FoldersDataSource" runat="server" SelectMethod="GetFolders" TypeName="NMail.Administration.Web.FolderDataSource"></asp:ObjectDataSource> + <br /> + <a href="CreateFolder.aspx">Create new folder</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -10,12 +10,5 @@ using System.Web.UI.HtmlControls; public partial class ViewFolders : System.Web.UI.Page -{ - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } +{ } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -1,5 +1,6 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Untitled Page" %> <asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>Mail Domains</h2> <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource" UpdateMethod="UpdateMailDomain"> <UpdateParameters> <asp:Parameter Name="mailDomainId" Type="Int32" /> Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -16,11 +16,4 @@ public partial class ViewMailDomains : System.Web.UI.Page { - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } } Modified: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-06 11:32:51 UTC (rev 41) @@ -1,25 +1,15 @@ <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %> -<script runat="server"> - - protected void Page_Load(object sender, EventArgs e) - { - if (!Request.IsAuthenticated) - { - Response.Redirect("Login.aspx"); - } - } -</script> - <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>Users</h2> <asp:GridView ID="GridView1" runat="server" DataSourceID="UserDataSource" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <Columns> <asp:BoundField DataField="UserId" HeaderText="UserId" SortExpression="UserId" /> + <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> <asp:BoundField DataField="UserFolderId" HeaderText="UserFolderId" SortExpression="UserFolderId" /> <asp:BoundField DataField="QuotaWarnLimit" HeaderText="QuotaWarnLimit" SortExpression="QuotaWarnLimit" /> <asp:BoundField DataField="QuotaHardLimit" HeaderText="QuotaHardLimit" SortExpression="QuotaHardLimit" /> - <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="UserDetails.aspx?UserId={0}" HeaderText="Edit" Text="edit" /> </Columns> @@ -32,5 +22,7 @@ </asp:GridView> <asp:ObjectDataSource ID="UserDataSource" runat="server" SelectMethod="GetUsers" TypeName="NMail.Administration.Web.UserDataSource"></asp:ObjectDataSource> + <br /> + <a href="CreateUser.aspx">Create new user</a> </asp:Content> Modified: NMail/branches/luke-dev/NMail.ImapService/Response/AclResponse.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/Response/AclResponse.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.ImapService/Response/AclResponse.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -24,7 +24,7 @@ namespace NMail.ImapService.Response { public class AclResponse : AbstractResponse { - public AclResponse(string cmdString, Folder folder, StoreFolderAce ace) { + public AclResponse(string cmdString, Folder folder, GenericAce<StoreFolderPrivilege> ace) { this.cmdString = cmdString; this.ace = ace; this.folder = folder; @@ -32,7 +32,7 @@ private string cmdString; - private StoreFolderAce ace; + private GenericAce<StoreFolderPrivilege> ace; private Folder folder; Modified: NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -386,7 +386,7 @@ public override void ProcessCommand(SetAclCommand cmd) { try { // Attempt to lookup the current privileges - StoreFolderAce currentAce = null; + GenericAce<StoreFolderPrivilege> currentAce = null; StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { @@ -466,7 +466,7 @@ while (e.MoveNext()) { // Send each entry in the ACL to the client string currentIdentifier = e.Current; - StoreFolderAce currentAce = currentAcl[currentIdentifier]; + GenericAce<StoreFolderPrivilege> currentAce = currentAcl[currentIdentifier]; QueueResponse(new AclResponse("ACL", folder, currentAce)); } @@ -530,7 +530,7 @@ if (currentAcl[username] != null) { // Show the rights for the current user - StoreFolderAce currentAce = currentAcl[username]; + GenericAce<StoreFolderPrivilege> currentAce = currentAcl[username]; currentAce.Identifier = string.Empty; QueueResponse(new AclResponse("MYRIGHTS", folder, currentAce)); } Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -35,6 +35,9 @@ /// clients. /// </summary> public class LocalStore : MarshalByRefObject, ILocalStore { + + // TODO: check with AuthProvider that AuthTokens are valid + #region ILocalStore Members #region Delivery & Validation @@ -358,7 +361,7 @@ StoreFolder createdFolder = LocalStoreData.GetStoreFolder(resolvedFolder); // Create an ACL for the folder - StoreFolderAce ace = new StoreFolderAce(authToken.Username, StoreFolderPrivilegeHelper.AllPrivileges, AcePrivilegeType.Allow); + GenericAce<StoreFolderPrivilege> ace = new GenericAce<StoreFolderPrivilege>(authToken.Username, StoreFolderPrivilegeHelper.AllPrivileges, AcePrivilegeType.Allow); LocalStoreData.SetStoreFolderAce(createdFolder, ace); return LocalStoreFolderResult.OkSuccessful; @@ -399,6 +402,17 @@ return LocalStoreFolderResult.NotPermitted; } } + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of folders.</returns> + public StoreFolder[] GetFolders(IAuthenticationToken authToken) { + // TODO: check for admin ACLs + + return LocalStoreData.GetFolders(); + } #endregion #region Rename Folder @@ -1129,10 +1143,11 @@ #endregion #region Folder ACLs - public void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, StoreFolderAce ace) { + public void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, GenericAce<StoreFolderPrivilege> ace) { // Ensure the user has rights to alter the ACL - if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin) + || hasSystemPrivilege(authToken.Username, SystemPrivilege.EditAllAcls)) { // Set the ACE LocalStoreData.SetStoreFolderAce(folder, ace); } @@ -1141,7 +1156,8 @@ public void RemoveStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, string identifier) { // Ensure the user has rights to alter the ACL - if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin) + || hasSystemPrivilege(authToken.Username, SystemPrivilege.EditAllAcls)) { // Remove the ACE LocalStoreData.RemoveStoreFolderAce(folder, identifier); } @@ -1150,7 +1166,8 @@ public StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to lookup the ACL - if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup) + || hasSystemPrivilege(authToken.Username, SystemPrivilege.EditAllAcls)) { // Return the ACL StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); return currentAcl; @@ -1235,14 +1252,100 @@ return this.LocalStoreData.GetMailDomainUsers(mailDomainId); } #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + public void SetSystemPrivilegeAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace) { + // Ensure the user has rights to modifiy the system ACL + if (hasSystemPrivilege(authToken.Username, SystemPrivilege.ModifySystemPrivileges)) { + LocalStoreData.SetSystemPrivilegeAce(ace); + } + } + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + public void RemoveSystemPrivilegeAce(IAuthenticationToken authToken, string identifier) { + // Ensure the user has rights to modifiy the system ACL + if (hasSystemPrivilege(authToken.Username, SystemPrivilege.ModifySystemPrivileges)) { + LocalStoreData.RemoveSystemPrivilegeAce(identifier); + } + } + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The system ACL or null if insufficient privileges.</returns> + public GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(IAuthenticationToken authToken) { + // Ensure the user has rights to view the ACL + if (hasSystemPrivilege(authToken.Username, SystemPrivilege.ViewSystemPrivileges)) { + return LocalStoreData.GetSystemPrivilegeAcl(); + + } else { + return null; + } + } #endregion + #region User and Group Administration + /// <summary> + /// Get the ACL that lists user's privileges for user and group administration. + /// </summary> + /// <param name="user">The user trying to get the admin ACL.</param> + /// <returns>The ACL or null if insufficient privileges.</returns> + public GenericAcl<UserGroupAdminPrivilege> GetAdministrationAcl(IAuthenticationToken user) { + throw new NotImplementedException(); + } + + /// <summary> + /// Sets the administration privileges for the associated identifier. + /// If no ACE exists for the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + public void SetAdministrationAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace) { + throw new NotImplementedException(); + } + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + public void RemoveAdministrationAce(IAuthenticationToken authToken, string identifier) { + throw new NotImplementedException(); + } + #endregion + #endregion + + #region Privilege Checks + + // TODO: check group permissions + // TODO: apply deny ACEs over allow ACEs + // TODO: recursive ACEs? + + #region Has Folder Privilege + /// <summary> + /// Checks if a user has a privilege on a folder. + /// </summary> + /// <param name="username">The user to check.</param> + /// <param name="folderId">The Id of the folder to check.</param> + /// <param name="privilege">The privilege to check for.</param> + /// <returns>True if the user has the privilege.</returns> private bool hasFolderPrivilege(string username, int folderId, StoreFolderPrivilege privilege) { // First check if the user has the required privilege on the folder StoreFolder folder = LocalStoreData.GetStoreFolder(folderId); StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); - StoreFolderAce userAce = currentAcl[username]; + GenericAce<StoreFolderPrivilege> userAce = currentAcl[username]; if (privilege != StoreFolderPrivilege.None) { if (userAce == null) { @@ -1270,7 +1373,40 @@ // No parent (don't need Lookup priv) and user has the required privilege return true; } + #endregion + + #region Has System Privilege + /// <summary> + /// Checks if a identifier has a system privilege. + /// </summary> + /// <param name="identifier">The identifier to check.</param> + /// <param name="privilege">The privilege to check for.</param> + /// <returns>True if the user has the privilege.</returns> + private bool hasSystemPrivilege(string identifier, SystemPrivilege privilege) { + if (privilege == SystemPrivilege.None) { + // Anyone is allowed no privileges, even if they're not on the ACL! ;-) + return true; + } + GenericAcl<SystemPrivilege> systemAcl = LocalStoreData.GetSystemPrivilegeAcl(); + GenericAce<SystemPrivilege> identifierAce = systemAcl[identifier]; + + if (identifierAce == null) { + // Identifier isn't listed on the ACL + return false; + } + + if ((identifierAce.AceType != AcePrivilegeType.Allow) + || ((identifierAce.Privilege & privilege) != privilege)) { + // Identifier doesn't have the required privilege + return false; + } + + return true; + } + #endregion + #endregion + /// <summary> /// The folder delimiter used by this local store. /// </summary> Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-06-06 11:32:51 UTC (rev 41) @@ -273,7 +273,22 @@ END // +DROP PROCEDURE IF EXISTS GetFolders // +CREATE PROCEDURE GetFolders +( +) +BEGIN + SELECT + f.FolderId, f.Name, n.Name AS NameSpace + FROM + Folder f, Namespace n + WHERE + f.NameSpaceId = n.NameSpaceId; +END +// + + -- ----------------------------------------------------------------------- -- -- User related stored procedures @@ -841,6 +856,50 @@ // +-- ----------------------------------------------------------------------- +-- +-- System ACL related stored procedures +-- +-- ----------------------------------------------------------------------- + + +DROP PROCEDURE IF EXISTS GetSystemAcl // +CREATE PROCEDURE GetSystemAcl +() +BEGIN + + SELECT Identifier, Allow, Privilege FROM Acl WHERE Resource = 'System'; + +END +// + +DROP PROCEDURE IF EXISTS SetSystemAce // +CREATE PROCEDURE SetSystemAce +( + Identifier VARCHAR(100), + Allow BOOL, + Privilege INT UNSIGNED +) +BEGIN + + REPLACE Acl (Identifier, Allow, Privilege, Resource) VALUES (Identifier, Allow, Privilege, 'System'); + +END +// + +DROP PROCEDURE IF EXISTS RemoveSystemAce // +CREATE PROCEDURE RemoveSystemAce +( + DeleteIdentifier VARCHAR(100) +) +BEGIN + + DELETE FROM Acl WHERE Identifier = DeleteIdentifier AND Resource = 'System'; + +END +// + + delimiter ; @@ -859,8 +918,8 @@ INSERT INTO Subscription (UserId, FolderId) VALUES (1, 2); INSERT INTO `Group` (Name) VALUES ("Administrators"); INSERT INTO UserGroupMap (GroupId, UserId) VALUES (1, 1); +INSERT INTO Acl (Identifier, Allow, Privilege, Resource) VALUES ("Administrator", 1, 0xffffff, "System"); -- All privs - -- TODO: remove, for testing only INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing1", "changeme", 2); INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing2", "changeme", 2); Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-02 13:26:56 UTC (rev 40) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-06 11:32:51 UTC (rev 41) @@ -434,6 +434,32 @@ } #endregion + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <returns>The list of folders.</returns> + public StoreFolder[] GetFolders() { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetFolders"; + + List<StoreFolder> folders = new List<StoreFolder>(); + MySqlDataReader reader = cmd.ExecuteReader(); + + while (reader.Read()) { + int folderId = (int) reader["FolderId"]; + string nameSpace = (string) reader["NameSpace"]; + string name = (string) reader["Name"]; + + // TODO: Get HasChildren from the reader + folders.Add(new StoreFolder(nameSpace, name, folderId, false)); + } + + return folders.ToArray(); + } + } + } #endregion #region Folder Subscription @@... [truncated message content] |
|
From: <tmy...@us...> - 2006-06-06 17:07:02
|
Revision: 43 Author: tmyroadctfig Date: 2006-06-06 05:55:52 -0700 (Tue, 06 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=43&view=rev Log Message: ----------- Merged in changes from development branch. Modified Paths: -------------- NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs NMail/trunk/NMail/DataTypes/ACLs/GenericAcl.cs NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAcl.cs NMail/trunk/NMail/DataTypes/Folder.cs NMail/trunk/NMail/DataTypes/LocalStore/MailDomain.cs NMail/trunk/NMail/DataTypes/LocalStoreGroup.cs NMail/trunk/NMail/DataTypes/StoreFolder.cs NMail/trunk/NMail/ILocalStore.cs NMail/trunk/NMail/ILocalStoreData.cs NMail/trunk/NMail/ILocalStoreDeliveryAction.cs NMail/trunk/NMail/ILocalStoreRecipientValidator.cs NMail/trunk/NMail/IO/TcpChannel.cs NMail/trunk/NMail/IO/TcpClientChannel.cs NMail/trunk/NMail/IO/TcpClientTransportSink.cs NMail/trunk/NMail/IO/TcpClientTransportSinkProvider.cs NMail/trunk/NMail/IO/TcpServerChannel.cs NMail/trunk/NMail/IO/TcpServerTransportSink.cs NMail/trunk/NMail/NMail.csproj NMail/trunk/NMail.Administration.Console/Context/LocalStoreContext.cs NMail/trunk/NMail.Administration.Console/Context/TopLevelContext.cs NMail/trunk/NMail.Administration.Console/NMail.Administration.Console.csproj NMail/trunk/NMail.ImapService/Response/AclResponse.cs NMail/trunk/NMail.ImapService/State/AuthenticatedState.cs NMail/trunk/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs NMail/trunk/NMail.LocalStore/DeliveryActions/Copy.cs NMail/trunk/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs NMail/trunk/NMail.LocalStore/DeliveryActions/Move.cs NMail/trunk/NMail.LocalStore/LocalStore.cs NMail/trunk/NMail.LocalStore/NMail.LocalStore.csproj NMail/trunk/NMail.LocalStore/Validators/AddressDate.cs NMail/trunk/NMail.LocalStore/Validators/AddressKeyword.cs NMail/trunk/NMail.LocalStore/Validators/AddressSender.cs NMail/trunk/NMail.LocalStore/Validators/OnWhiteList.cs NMail/trunk/NMail.LocalStore/Validators/OrdbBlackList.cs NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/trunk/NMail.Server/NMail.Server.csproj NMail/trunk/NMail.Server/NMailServer.cs NMail/trunk/NMail.Server/RemoteAdministration.cs NMail/trunk/NMail.Server.Console/NMail.Server.Console.csproj NMail/trunk/NMail.Server.Console/NMailConsoleServer.cs Added Paths: ----------- NMail/trunk/NDns/NDns.xml NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs NMail/trunk/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs NMail/trunk/NMail.Administration.Console/Command/AddMailDomainCommand.cs NMail/trunk/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs NMail/trunk/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs NMail/trunk/NMail.Administration.Web/ NMail/trunk/NMail.Administration.Web/App_Code/ NMail/trunk/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/trunk/NMail.Administration.Web/App_Code/MailDomainDataSource.cs NMail/trunk/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/trunk/NMail.Administration.Web/App_Data/ NMail/trunk/NMail.Administration.Web/Bin/ NMail/trunk/NMail.Administration.Web/CreateFolder.aspx NMail/trunk/NMail.Administration.Web/CreateFolder.aspx.cs NMail/trunk/NMail.Administration.Web/CreateUser.aspx NMail/trunk/NMail.Administration.Web/CreateUser.aspx.cs NMail/trunk/NMail.Administration.Web/Default.aspx NMail/trunk/NMail.Administration.Web/FolderDetails.aspx NMail/trunk/NMail.Administration.Web/FolderDetails.aspx.cs NMail/trunk/NMail.Administration.Web/Global.asax NMail/trunk/NMail.Administration.Web/Images/ NMail/trunk/NMail.Administration.Web/Images/nmail-logo.png NMail/trunk/NMail.Administration.Web/Login.aspx NMail/trunk/NMail.Administration.Web/Login.aspx.cs NMail/trunk/NMail.Administration.Web/MailDomainDetails.aspx NMail/trunk/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/trunk/NMail.Administration.Web/MasterPage.master NMail/trunk/NMail.Administration.Web/StyleSheet.css NMail/trunk/NMail.Administration.Web/UserDetails.aspx NMail/trunk/NMail.Administration.Web/UserDetails.aspx.cs NMail/trunk/NMail.Administration.Web/ViewFolders.aspx NMail/trunk/NMail.Administration.Web/ViewFolders.aspx.cs NMail/trunk/NMail.Administration.Web/ViewMailDomains.aspx NMail/trunk/NMail.Administration.Web/ViewMailDomains.aspx.cs NMail/trunk/NMail.Administration.Web/ViewUsers.aspx NMail/trunk/NMail.Administration.Web/Web.sitemap NMail/trunk/NMail.Administration.Web/web.config NMail/trunk/NMail.Administration.Web.sln Removed Paths: ------------- NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAce.cs Added: NMail/trunk/NDns/NDns.xml =================================================================== --- NMail/trunk/NDns/NDns.xml (rev 0) +++ NMail/trunk/NDns/NDns.xml 2006-06-06 12:55:52 UTC (rev 43) @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>NDns</name> + </assembly> + <members> + </members> +</doc> Modified: NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs =================================================================== --- NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -17,6 +17,8 @@ using System; +using NMail.DataTypes.ACLs; + namespace NMail.Authentication { /// <summary> /// The interface for an authentication provider that operates on username and Modified: NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -23,14 +23,16 @@ /// <summary> /// A generic access control entry for an ACL. /// </summary> - public class GenericAce { + public class GenericAce<PrivilegeType> { /// <summary> /// Creates a new access control entry. /// </summary> /// <param name="identifier">The identifier to associated the ACE with.</param> + /// <param name="privilege">The privileges.</param> /// <param name="acePrivilegeType">Whether to allow or deny the privileges.</param> - public GenericAce(string identifier, AcePrivilegeType acePrivilegeType) { + public GenericAce(string identifier, PrivilegeType privilege, AcePrivilegeType acePrivilegeType) { this.identifier = identifier; + this.privilege = privilege; this.acePrivilegeType = acePrivilegeType; } @@ -48,6 +50,20 @@ } } + private PrivilegeType privilege; + + /// <summary> + /// The privilege associated with this ACE. + /// </summary> + public PrivilegeType Privilege { + get { + return this.privilege; + } + set { + this.privilege = value; + } + } + private AcePrivilegeType acePrivilegeType; /// <summary> Modified: NMail/trunk/NMail/DataTypes/ACLs/GenericAcl.cs =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/ACLs/GenericAcl.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -23,40 +23,23 @@ /// <summary> /// A list of access control entries. /// </summary> - public class GenericAcl<AceType> where AceType : GenericAce { + public class GenericAcl<PrivilegeType> { /// <summary> /// A map of identifiers to access control entries. /// </summary> - protected Dictionary<string, AceType> entries = new Dictionary<string, AceType>(StringComparer.InvariantCultureIgnoreCase); + protected Dictionary<string, GenericAce<PrivilegeType>> entries = new Dictionary<string, GenericAce<PrivilegeType>>(StringComparer.InvariantCultureIgnoreCase); /// <summary> - /// Creates a new ACL for the given resource name. + /// Creates a new ACL. /// </summary> - /// <param name="resourceName">The name of the resource this ACL is for.</param> - public GenericAcl(string resourceName) { - this.resourceName = resourceName; - } + public GenericAcl() {} - private string resourceName; - /// <summary> - /// The name of the resource this ACL is associated wtih. - /// </summary> - public string ResourceName { - get { - return this.resourceName; - } - set { - this.resourceName = value; - } - } - - /// <summary> /// Replaces the existing ACE for the associated identifier. If no ACE exists /// for the given identifer the new ACE is simply added. /// </summary> /// <param name="ace">The ACE to set.</param> - public void SetAce(AceType ace) { + public void SetAce(GenericAce<PrivilegeType> ace) { lock (this) { if (this.entries.ContainsKey(ace.Identifier)) { this.entries.Remove(ace.Identifier); @@ -90,7 +73,7 @@ /// </summary> /// <param name="identifier">The identifier to look up.</param> /// <returns>The identifier or null if non is found.</returns> - public AceType this[string identifier] { + public GenericAce<PrivilegeType> this[string identifier] { get { lock (this) { if (this.entries.ContainsKey(identifier)) { Deleted: NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAce.cs =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAce.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAce.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -1,53 +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; -using System.Collections.Generic; -using System.Text; - -namespace NMail.DataTypes.ACLs { - /// <summary> - /// An access control entry for a store folder ACL. - /// </summary> - public class StoreFolderAce : GenericAce { - /// <summary> - /// Creates a new access control entry. - /// </summary> - /// <param name="identifier">The identifier to associated the ACE with.</param> - /// <param name="privilege">The privileges.</param> - /// <param name="aceType">Whether to allow or deny the privileges.</param> - public StoreFolderAce(string identifier, StoreFolderPrivilege privilege, AcePrivilegeType aceType) - : base(identifier, aceType) { - - this.privilege = privilege; - } - - private StoreFolderPrivilege privilege; - - /// <summary> - /// The privilege associated with this ACE. - /// </summary> - public StoreFolderPrivilege Privilege { - get { - return this.privilege; - } - set { - this.privilege = value; - } - } - } -} Modified: NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAcl.cs =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/ACLs/StoreFolderAcl.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -21,14 +21,14 @@ namespace NMail.DataTypes.ACLs { /// <summary> - /// A list of access control entries. + /// A list of access control entries for a folder. /// </summary> - public class StoreFolderAcl : GenericAcl<StoreFolderAce> { + public class StoreFolderAcl : GenericAcl<StoreFolderPrivilege> { /// <summary> /// Creates a new ACL for the given folder. /// </summary> /// <param name="folder">The folder associated with the ACL.</param> - public StoreFolderAcl(StoreFolder folder) : base(folder.FolderId.ToString()) { + public StoreFolderAcl(StoreFolder folder) : base() { this.folder = folder; } Copied: NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs (from rev 42, NMail/branches/luke-dev/NMail/DataTypes/ACLs/SystemPrivilege.cs) =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs (rev 0) +++ NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.DataTypes.ACLs { + /// <summary> + /// The possible privileges a user or group can have on the NMail system. + /// </summary> + [FlagsAttribute] + public enum SystemPrivilege : uint { + /// <summary> + /// No rights are granted. + /// </summary> + None = 0, + + /// <summary> + /// The right to view the system privilege ACL. + /// </summary> + ViewSystemPrivileges = 1, + + /// <summary> + /// The right to modify the system privilege ACL. + /// </summary> + ModifySystemPrivileges = 2, + + /// <summary> + /// The right to edit any ACLs. + /// </summary> + EditAllAcls = 4, + + /// <summary> + /// The right to create a new mail domain. + /// </summary> + CreateMailDomain = 8 + } +} Copied: NMail/trunk/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs (from rev 42, NMail/branches/luke-dev/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs) =================================================================== --- NMail/trunk/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs (rev 0) +++ NMail/trunk/NMail/DataTypes/ACLs/UserGroupAdminPrivilege.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NMail.DataTypes.ACLs { + /// <summary> + /// The possible privileges a user or group can have for editing other users and + /// groups. + /// </summary> + [FlagsAttribute] + public enum UserGroupAdminPrivilege : uint { + /// <summary> + /// No rights are granted. + /// </summary> + None = 0, + + /// <summary> + /// The right to view all users in the system. + /// </summary> + ViewAllUsers = 1, + + /// <summary> + /// The right to create new users. + /// </summary> + CreateUsers = 2, + + /// <summary> + /// The right to edit existing users. + /// </summary> + EditUsers = 4, + + /// <summary> + /// The right to delete existing users. + /// </summary> + DeleteUsers = 8, + + /// <summary> + /// The right to view all groups in the system. + /// </summary> + ViewAllGroups = 16, + + /// <summary> + /// The right to create new groups. + /// </summary> + CreateGroups = 32, + + /// <summary> + /// The right to edit existing groups. + /// </summary> + EditGroups = 64, + + /// <summary> + /// The right to delete existing groups. + /// </summary> + DeleteGroups = 128 + } +} Modified: NMail/trunk/NMail/DataTypes/Folder.cs =================================================================== --- NMail/trunk/NMail/DataTypes/Folder.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/Folder.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -23,6 +23,7 @@ /// <summary> /// Represents a folder in the local store. /// </summary> + [Serializable] public class Folder { #region Constructors /// <summary> Modified: NMail/trunk/NMail/DataTypes/LocalStore/MailDomain.cs =================================================================== --- NMail/trunk/NMail/DataTypes/LocalStore/MailDomain.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/LocalStore/MailDomain.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -20,6 +20,7 @@ using System.Text; using NMail; +using NMail.Authentication; using NMail.DataTypes; namespace NMail.DataTypes.LocalStore { @@ -27,6 +28,7 @@ /// A mail domain maps users and administrators to a set of hosts that the store /// accepts mail for. /// </summary> + [Serializable] public class MailDomain { public MailDomain(int mailDomainId, Host primaryHost) { this.mailDomainId = mailDomainId; @@ -61,76 +63,147 @@ } } - WildcardHost[] additionalHosts; + private List<WildcardHost> additionalHosts = new List<WildcardHost>(); /// <summary> /// Other hosts that this domain accepts mail for. /// </summary> public WildcardHost[] AdditionalHosts { get { - return this.additionalHosts; + return this.additionalHosts.ToArray(); } set { - this.additionalHosts = value; + this.additionalHosts.Clear(); + this.additionalHosts.AddRange(value); } } - private ILocalStoreUserMap[] mailboxMappings; + private List<ILocalStoreUserMap> mailboxMappings = new List<ILocalStoreUserMap>(); /// <summary> /// Gets the mailbox mappings for this domain. /// </summary> public ILocalStoreUserMap[] MailboxMappings { get { - return this.mailboxMappings; + return this.mailboxMappings.ToArray(); } set { - this.mailboxMappings = value; + this.mailboxMappings.Clear(); + this.mailboxMappings.AddRange(value); } } - private ILocalStoreDeliveryAction[] allowedActions; + private List<ILocalStoreDeliveryAction> allowedActions = new List<ILocalStoreDeliveryAction>(); /// <summary> /// The actions that user's of this domain are allowed to use. /// </summary> public ILocalStoreDeliveryAction[] AllowedActions { get { - return this.allowedActions; + return this.allowedActions.ToArray(); } - set { - this.allowedActions = value; - } + set { + this.allowedActions.Clear(); + this.allowedActions.AddRange(value); + } } - private ILocalStoreRecipientValidator[] allowedValidators; + private List<ILocalStoreRecipientValidator> allowedValidators = new List<ILocalStoreRecipientValidator>(); /// <summary> /// The validators that user's of this domain are allowed to use. /// </summary> public ILocalStoreRecipientValidator[] AllowedValidators { get { - return this.allowedValidators; + return this.allowedValidators.ToArray(); } set { - this.allowedValidators = value; + this.allowedValidators.Clear(); + this.allowedValidators.AddRange(value); } } - private ILocalStoreDeliveryAction[] defaultActions; + private List<ILocalStoreDeliveryAction> defaultActions = new List<ILocalStoreDeliveryAction>(); /// <summary> /// The default set of actions to apply to incoming messages. /// </summary> public ILocalStoreDeliveryAction[] DefaultActions { get { - return this.defaultActions; + return this.defaultActions.ToArray(); } set { - this.defaultActions = value; + this.defaultActions.Clear(); + this.defaultActions.AddRange(value); } } // TODO: add in a recipient validator tree here + + + /// <summary> + /// Maps a given mailbox to a user. + /// </summary> + /// <param name="mailbox">The mailbox to lookup.</param> + /// <returns>The username or null.</returns> + public string MapMailboxToUser(string mailbox) { + string result = null; + + // Search for a valid mapping for the mailbox + for (int i = 0; result == null && i < this.mailboxMappings.Count; i++) { + result = this.mailboxMappings[i].MapMailboxToUser(mailbox); + } + + return result; + } + + public ILocalStoreRecipientValidator GetRecipientValidator(string name) { + name = name.Trim().ToLower(); + + foreach (ILocalStoreRecipientValidator validator in this.allowedValidators) { + if (validator.Name.Trim().ToLower() == name) { + return validator; + } + } + + return null; + } + + + public ILocalStoreDeliveryAction GetDeliveryAction(string name) { + name = name.Trim().ToLower(); + + foreach (ILocalStoreDeliveryAction action in this.allowedActions) { + if (action.Name.Trim().ToLower() == name) { + return action; + } + } + + return null; + } + + /// <summary> + /// Processes the incomming message against the list of delivery actions. + /// </summary> + /// <param name="delivery">The delivery in progress.</param> + /// <param name="username">The associated username.</param> + /// <returns>The result of the delivery attempt.</returns> + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username) { + for (int i = 0; i < this.defaultActions.Count; i++) { + string name = this.defaultActions[i].Name; + string data = null; + if (delivery.Recipient != null) { + data = delivery.Recipient.Mailbox.GetDataPairValue(name); + } + + DeliveryResult result = this.defaultActions[i].ProcessDelivery(delivery, username, data); + + if (result.Type != DeliveryResultType.Success) { + return result; + } + } + + return new DeliveryResult(DeliveryResultType.Success, null); + } } } Modified: NMail/trunk/NMail/DataTypes/LocalStoreGroup.cs =================================================================== --- NMail/trunk/NMail/DataTypes/LocalStoreGroup.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/LocalStoreGroup.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -35,6 +35,8 @@ public LocalStoreGroup(string name, int groupId, int[] userIds, int[] groupIds) { this.name = name; this.groupId = groupId; + this.userIds = userIds; + this.groupIds = groupIds; } private string name; Modified: NMail/trunk/NMail/DataTypes/StoreFolder.cs =================================================================== --- NMail/trunk/NMail/DataTypes/StoreFolder.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/DataTypes/StoreFolder.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -23,6 +23,7 @@ /// <summary> /// A folder that has been obtained from the local store. /// </summary> + [Serializable] public class StoreFolder : Folder { /// <summary> /// Creates a new store folder. Modified: NMail/trunk/NMail/ILocalStore.cs =================================================================== --- NMail/trunk/NMail/ILocalStore.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/ILocalStore.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -83,6 +83,14 @@ StoreFolder GetStoreFolder(IAuthenticationToken authToken, string folder); /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invalid.</returns> + StoreFolder GetStoreFolder(IAuthenticationToken authToken, int folderId); + + /// <summary> /// Creates a new folder. /// </summary> /// <remarks> @@ -97,9 +105,9 @@ /// Deletes an existing folder. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, StoreFolder folder); + LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, int folderId); /// <summary> /// Renames an existing folder in the local store. @@ -132,6 +140,13 @@ /// <param name="parent">The parent to get the children from.</param> /// <returns>The list of folders.</returns> StoreFolder[] GetChildren(IAuthenticationToken authToken, StoreFolder parent); + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The list of folders.</returns> + StoreFolder[] GetFolders(IAuthenticationToken authToken); #endregion #region Folder Subscription @@ -302,7 +317,7 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="folder">The folder to set the ACE on.</param> /// <param name="ace">The privileges and the identifier to put.</param> - void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, StoreFolderAce ace); + void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, GenericAce<StoreFolderPrivilege> ace); /// <summary> /// Removes any ACE associated with the given user. @@ -420,7 +435,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - void AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + /// <returns>The result of the attempt to add the user to the mail domain.</returns> + LocalStoreUserResult AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); /// <summary> /// Removes user from the given mail domain. @@ -428,7 +444,16 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - void RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + /// <returns>The result of the attempt to remove the user from the mail domain.</returns> + LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid or unauthorized.</returns> + StoreFolder[] GetUserFolders(IAuthenticationToken authToken, int userId); #endregion #region Group Management @@ -471,21 +496,40 @@ /// <returns>The result of the attempt to delete a group.</returns> LocalStoreGroupResult DeleteGroup(IAuthenticationToken authToken, int groupId); - /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - LocalStoreGroupResult UpdateGroup(IAuthenticationToken authToken, LocalStoreGroup group); + /// <summary> + /// Renames the group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + LocalStoreGroupResult RenameGroup(IAuthenticationToken authToken, LocalStoreGroup group); + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToGroup(IAuthenticationToken authToken, int parentId, int groupId); + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromGroup(IAuthenticationToken authToken, int parentId, int groupId); + /// <summary> /// Adds a group to the given mail domain. /// </summary> /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - void AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + LocalStoreGroupResult AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); /// <summary> /// Removes group from the given mail domain. @@ -493,7 +537,7 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - void RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + LocalStoreGroupResult RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); #endregion #region Mail Domain Management @@ -504,13 +548,13 @@ /// <returns>The mail domains.</returns> MailDomain[] GetMailDomains(IAuthenticationToken authToken); - /// <summary> - /// Creates a new mail domain. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="primaryHost">The primary host for the mail domain.</param> - /// <returns>The result of the attempt to create the mail domain.</returns> - LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host primaryHost); + /// <summary> + /// Adds a new mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomain">The mail domain to add.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult AddMailDomain(IAuthenticationToken authToken, MailDomain mailDomain); /// <summary> /// Deletes a mail domain from the local store. @@ -546,6 +590,54 @@ /// <returns>The list of user Ids.</returns> int[] GetMailDomainUsers(IAuthenticationToken authToken, int mailDomainId); #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetSystemPrivilegeAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveSystemPrivilegeAce(IAuthenticationToken authToken, string identifier); + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <returns>The system ACL or null if insufficient privileges.</returns> + GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(IAuthenticationToken authToken); + #endregion + + #region User and Group Administration + /// <summary> + /// Get the ACL that lists user's privileges for user and group administration. + /// </summary> + /// <param name="user">The user trying to get the admin ACL.</param> + /// <returns>The ACL or null if insufficient privileges.</returns> + GenericAcl<UserGroupAdminPrivilege> GetAdministrationAcl(IAuthenticationToken user); + + /// <summary> + /// Sets the administration privileges for the associated identifier. + /// If no ACE exists for the associated identifier one is added. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetAdministrationAce(IAuthenticationToken authToken, GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveAdministrationAce(IAuthenticationToken authToken, string identifier); + #endregion } /// <summary> @@ -555,29 +647,29 @@ /// <summary> /// The operation was completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// The create or rename failed because a folder with the same name already existed. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// The folder was not deleted because it contained child folders. /// </summary> - HasChildren, + HasChildren = 2, /// <summary> /// The operation failed because the source folder was not found on the server. /// If the operation is on a subfolder that the user can't see due to permissions /// this will be returned. /// </summary> - NonExistent, + NonExistent = 3, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 4 } /// <summary> @@ -587,27 +679,42 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A user with the same name already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching user exists in the local store. /// </summary> - NoSuchUser, + NoSuchUser = 2, /// <summary> + /// Cannot add or remove the user from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> /// The user cannot be deleted because they still own folders. /// </summary> - UserStillHasFolders, + UserStillHasFolders = 4, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 5, + + /// <summary> + /// The user cannot be created because there is existing folders with the same details. + /// </summary> + FoldersAlreadyExist = 6, + + /// <summary> + /// An unknown error occurred trying to perform the operation. + /// </summary> + UnkownError = 7 } /// <summary> @@ -617,22 +724,27 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A group with the same name already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching group exists in the local store. /// </summary> - NoSuchUser, + NoSuchGroup = 2, /// <summary> + /// Cannot add or remove the group from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 4 } /// <summary> @@ -642,21 +754,21 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A mail domain with the same primary host already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching mail domain exists in the local store. /// </summary> - NoSuchMailDomain, + NoSuchMailDomain = 2, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 3 } } Modified: NMail/trunk/NMail/ILocalStoreData.cs =================================================================== --- NMail/trunk/NMail/ILocalStoreData.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/ILocalStoreData.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -58,6 +58,13 @@ StoreFolder GetStoreFolder(Folder folder); /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invalid.</returns> + StoreFolder GetStoreFolder(int folderId); + + /// <summary> /// Gets the parent folder for the given folder. /// </summary> /// <param name="folder">The folder to lookup the parent of.</param> @@ -71,15 +78,15 @@ /// It is a requirement of the local store that each new folder get an incremented Id number. /// </remarks> /// <param name="newFolder">The folder to create.</param> - /// <returns>The newly created folder details.</returns> - StoreFolder CreateFolder(string userName, StoreFolder parent, Folder newFolder); + /// <returns>The result of the attempt to create the folder.</returns> + LocalStoreFolderResult CreateFolder(int userId, StoreFolder parent, Folder newFolder); /// <summary> /// Deletes an existing folder. /// </summary> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - LocalStoreFolderResult DeleteFolder(StoreFolder folder); + LocalStoreFolderResult DeleteFolder(int folderId); /// <summary> /// Renames an existing folder in the local store. @@ -102,6 +109,12 @@ /// <param name="parent">The parent to get the children from.</param> /// <returns>The list of folders.</returns> StoreFolder[] GetChildren(StoreFolder parent); + + /// <summary> + /// Gets a list of all folders + /// </summary> + /// <returns>The list of folders.</returns> + StoreFolder[] GetFolders(); #endregion #region Folder Subscription @@ -267,7 +280,7 @@ /// </summary> /// <param name="folder">The folder to set the ACE on.</param> /// <param name="ace">The privileges and the identifier to put.</param> - void SetStoreFolderAce(StoreFolder folder, StoreFolderAce ace); + void SetStoreFolderAce(StoreFolder folder, GenericAce<StoreFolderPrivilege> ace); /// <summary> /// Removes any ACE associated with the given user. @@ -317,7 +330,7 @@ /// </summary> /// <param name="username">The username to lookup.</param> /// <returns>The user Id or null if non is found.</returns> - int GetUserId(string username); + int? GetUserId(string username); /// <summary> /// Creates a new user in the local store and creates an initial folder. @@ -347,14 +360,21 @@ /// </summary> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - void AddUserToMailDomain(int userId, int mailDomainId); + LocalStoreUserResult AddUserToMailDomain(int userId, int mailDomainId); /// <summary> /// Removes user from the given mail domain. /// </summary> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - void RemoveUserFromMailDomain(int userId, int mailDomainId); + LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId); + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid.</returns> + StoreFolder[] GetUserFolders(int userId); #endregion #region Group Management @@ -393,25 +413,44 @@ LocalStoreGroupResult DeleteGroup(int groupId); /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - LocalStoreGroupResult UpdateGroup(LocalStoreGroup group); + /// Renames the group. + /// </summary> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + LocalStoreGroupResult RenameGroup(int groupId, string newName); + + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToGroup(int parentId, int groupId); + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromGroup(int parentId, int groupId); /// <summary> /// Adds a group to the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - void AddGroupToMailDomain(int groupId, int mailDomainId); + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId); /// <summary> /// Removes group from the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to remove.</param> - /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - void RemoveGroupFromMailDomain(int groupId, int mailDomainId); + /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId); #endregion #region Mail Domain Management @@ -422,11 +461,11 @@ MailDomain[] GetMailDomains(); /// <summary> - /// Creates a new mail domain. + /// Adds a new mail domain. /// </summary> - /// <param name="primaryHost">The primary host for the mail domain.</param> - /// <returns>The result of the attempt to create the mail domain.</returns> - LocalStoreMailDomainResult CreateMailDomain(Host primaryHost); + /// <param name="mailDomain">The mail domain to add.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult AddMailDomain(MailDomain mailDomain); /// <summary> /// Deletes a mail domain from the local store. @@ -458,5 +497,26 @@ /// <returns>The list of user Ids.</returns> int[] GetMailDomainUsers(int mailDomainId); #endregion + + #region System ACL + /// <summary> + /// Sets the system privileges for the associated identifier. If no ACE exists for + /// the associated identifier one is added. + /// </summary> + /// <param name="ace">The privileges and the identifier to put.</param> + void SetSystemPrivilegeAce(GenericAce<SystemPrivilege> ace); + + /// <summary> + /// Removes any ACE associated with the given identifier. + /// </summary> + /// <param name="identifier">The identifier to remove from the ACL.</param> + void RemoveSystemPrivilegeAce(string identifier); + + /// <summary> + /// Gets the system ACL. + /// </summary> + /// <returns>The system ACL.</returns> + GenericAcl<SystemPrivilege> GetSystemPrivilegeAcl(); + #endregion } } Modified: NMail/trunk/NMail/ILocalStoreDeliveryAction.cs =================================================================== --- NMail/trunk/NMail/ILocalStoreDeliveryAction.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/ILocalStoreDeliveryAction.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -26,12 +26,11 @@ /// An action that can occur during delivery into the local store. /// </summary> public interface ILocalStoreDeliveryAction { - /// <summary> - /// Sets up the instance of the action using the configuration in the XML node. - /// </summary> - /// <remarks>This will only be called if the validator is part of the default validator.</remarks> - /// <param name="node">The configuration node.</param> - void Create(XmlNode node); + /// <summary> + /// The name of the delivery action. E.g. "move" or "copy". + /// </summary> + /// <remarks>This is the key used to lookup data in the mailbox part of an address.</remarks> + string Name { get; } /// <summary> /// Passes the local store delivery data through this action. Modified: NMail/trunk/NMail/ILocalStoreRecipientValidator.cs =================================================================== --- NMail/trunk/NMail/ILocalStoreRecipientValidator.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/ILocalStoreRecipientValidator.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -26,12 +26,11 @@ /// A validation that can be performed on a recipient before accepting delivery. /// </summary> public interface ILocalStoreRecipientValidator { - /// <summary> - /// Sets up the instance of the validator using the configuration in the XML node. - /// </summary> - /// <remarks>This will only be called if the validator is part of the default validator.</remarks> - /// <param name="node">The configuration node.</param> - void Create(XmlNode node); + /// <summary> + /// The name of the validator. E.g. "date" or "sender". + /// </summary> + /// <remarks>This is the key used to lookup data in the mailbox part of an address.</remarks> + string Name { get; } /// <summary> /// Checks if the given recipient will be accepted for delivery. Modified: NMail/trunk/NMail/IO/TcpChannel.cs =================================================================== --- NMail/trunk/NMail/IO/TcpChannel.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpChannel.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -39,6 +39,12 @@ private TcpServerChannel serverChannel; public TcpChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider) { + // Parse common properties + bool useTls = true; + if (properties.Contains("useTls")) { + useTls = (bool) properties["useTls"]; + } + // Create the client sink provider if needed if (clientSinkProvider == null) { clientSinkProvider = new BinaryClientFormatterSinkProvider(); @@ -52,7 +58,8 @@ this.clientChannel = new TcpClientChannel(clientSinkProvider, getAuthDetailsCallback, certValidationCallback, - authCompleteCallback); + authCompleteCallback, + useTls); if (properties["isServer"] != null && ((string) properties["isServer"]) == "yes") { // Create the server sink provider if needed @@ -68,7 +75,8 @@ this.serverChannel = new TcpServerChannel(port, certificate, authProvider, - serverSinkProvider); + serverSinkProvider, + useTls); } } Modified: NMail/trunk/NMail/IO/TcpClientChannel.cs =================================================================== --- NMail/trunk/NMail/IO/TcpClientChannel.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpClientChannel.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -48,21 +48,11 @@ /// Creates a new client channel with the given provider. /// </summary> /// <param name="clientSinkProvider">The provider to use.</param> - public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, ChannelAuthComplete authCompleteCallback) { - this.clientSinkProvider = clientSinkProvider; - - this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, null, authCompleteCallback); - } - - /// <summary> - /// Creates a new client channel with the given provider. - /// </summary> - /// <param name="clientSinkProvider">The provider to use.</param> /// <param name="certValidationCallback">The certificate to use to validate the remote server's certificate.</param> - public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.clientSinkProvider = clientSinkProvider; - this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, certValidationCallback, authCompleteCallback); + this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, certValidationCallback, authCompleteCallback, useTls); if (this.clientSinkProvider == null) { this.clientSinkProvider = new BinaryClientFormatterSinkProvider(); Modified: NMail/trunk/NMail/IO/TcpClientTransportSink.cs =================================================================== --- NMail/trunk/NMail/IO/TcpClientTransportSink.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpClientTransportSink.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -62,16 +62,19 @@ ChannelAuthComplete authCompleteCallback; + private bool useTls; + /// <summary> /// Creates a new sink with the given url. /// </summary> /// <param name="url">The URL to connect to.</param> /// <param name="remoteChannelData">Channel data optionally containing the URL.</param> /// <param name="certValidationCallback">The callback to use to validate the remote certificate.</param> - public TcpClientTransportSink(string url, object remoteChannelData, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientTransportSink(string url, object remoteChannelData, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.getAuthDetailsCallback = getAuthDetailsCallback; this.certValidationCallback = certValidationCallback; this.authCompleteCallback = authCompleteCallback; + this.useTls = useTls; if (TcpChannel.ValidUrl(url)) { string objectURI; @@ -225,33 +228,39 @@ if (response.Trim().ToLower() == "nmail remoting channel") { this.connection.WriteLine("OK"); - // Go encrypted... - if (this.certValidationCallback == null) { - this.connection.StartTlsAsClient(this.host.ToString()); - } else { - this.connection.StartTlsAsClient(this.host.ToString(), this.certValidationCallback); - } + if (this.useTls) + { + // Go encrypted... + if (this.certValidationCallback == null) + { + this.connection.StartTlsAsClient(this.host.ToString()); + } + else + { + this.connection.StartTlsAsClient(this.host.ToString(), this.certValidationCallback); + } - if (this.connection.Encrypted) { - while (this.connection.Connected && this.authToken == null) { - // Get the auth details - TcpUserPasswordPair authDetails = this.getAuthDetailsCallback(this); - - // Send them to the server - this.connection.Write(authDetails); - this.authToken = (IAuthenticationToken) this.connection.Read(); - } + if (!this.connection.Encrypted) + { + throw new InvalidOperationException("Failed to establish a secure connection to the server."); + } + } - if (this.authToken == null) { - throw new InvalidOperationException("Failed to authenticated to the server."); - } + while (this.connection.Connected && this.authToken == null) { + // Get the auth details + TcpUserPasswordPair authDetails = this.getAuthDetailsCallback(this); + + // Send them to the server + this.connection.Write(authDetails); + this.authToken = (IAuthenticationToken) this.connection.Read(); + } - // Notify the caller that the auth token has arrived - this.authCompleteCallback(authToken); + if (this.authToken == null) { + throw new InvalidOperationException("Failed to authenticated to the server."); + } - } else { - throw new InvalidOperationException("Failed to establish a secure connection to the server."); - } + // Notify the caller that the auth token has arrived + this.authCompleteCallback(authToken); } } } Modified: NMail/trunk/NMail/IO/TcpClientTransportSinkProvider.cs =================================================================== --- NMail/trunk/NMail/IO/TcpClientTransportSinkProvider.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpClientTransportSinkProvider.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -44,14 +44,17 @@ private ChannelAuthComplete authCompleteCallback; + private bool useTls; + /// <summary> /// Creates a new provider with the given certificate validation callback. /// </summary> /// <param name="certValidationCallback">The callback to use to validation teh remote server's certificate null for the default.</param> - public TcpClientTransportSinkProvider(GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientTransportSinkProvider(GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.getAuthDetailsCallback = getAuthDetailsCallback; this.certValidationCallback = certValidationCallback; this.authCompleteCallback = authCompleteCallback; + this.useTls = useTls; } #region IClientChannelSinkProvider Members @@ -91,7 +94,7 @@ // Create a transport if needed if (!sinkMap.ContainsKey(key)) { - this.sinkMap.Add(key, new TcpClientTransportSink(url, remoteChannelData, this.getAuthDetailsCallback, this.certValidationCallback, this.authCompleteCallback)); + this.sinkMap.Add(key, new TcpClientTransportSink(url, remoteChannelData, this.getAuthDetailsCallback, this.certValidationCallback, this.authCompleteCallback, this.useTls)); } return this.sinkMap[key]; Modified: NMail/trunk/NMail/IO/TcpServerChannel.cs =================================================================== --- NMail/trunk/NMail/IO/TcpServerChannel.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpServerChannel.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -68,16 +68,19 @@ /// </summary> private IServerChannelSink nextSink; + private bool useTls; + /// <summary> /// Creates a new server channel with the given details. /// </summary> /// <param name="port">The port to listen on.</param> /// <param name="certificate">The certificate to use for SSL.</param> /// <param name="serverSinkProvider">The provider.</param> - public TcpServerChannel(int port, X509Certificate2 certificate, IAuthenticationProvider authProvider, IServerChannelSinkProvider serverSinkProvider) { + public TcpServerChannel(int port, X509Certificate2 certificate, IAuthenticationProvider authProvider, IServerChannelSinkProvider serverSinkProvider, bool useTls) { this.port = port; this.certificate = certificate; this.authProvider = authProvider; + this.useTls = useTls; // This is needed to report a valid IP to clients asking for channel data IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); @@ -238,7 +241,7 @@ while (true) { Socket client = socket.AcceptSocket(); - new TcpServerTransportSink(this.nextSink, this.certificate, this.authProvider, client); + new TcpServerTransportSink(this.nextSink, this.certificate, this.authProvider, client, this.useTls); } } catch (SocketException e) { // Ignore interrupted exception during shutdown Modified: NMail/trunk/NMail/IO/TcpServerTransportSink.cs =================================================================== --- NMail/trunk/NMail/IO/TcpServerTransportSink.cs 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/IO/TcpServerTransportSink.cs 2006-06-06 12:55:52 UTC (rev 43) @@ -54,17 +54,20 @@ protected IAuthenticationProvider authProvider; + private bool useTls; + /// <summary> /// Creates a new transport sink with the given details. /// </summary> /// <param name="nextSink">The next sink in the chain.</param> /// <param name="certificate">The certificate to use in SSL.</param> /// <param name="client">The socket to the remote client.</param> - public TcpServerTransportSink(IServerChannelSink nextSink, X509Certificate2 certificate, IAuthenticationProvider authProvider, Socket client) { + public TcpServerTransportSink(IServerChannelSink nextSink, X509Certificate2 certificate, IAuthenticationProvider authProvider, Socket client, bool useTls) { this.nextSink = nextSink; this.connection.Create(client); this.connection.Certificate = certificate; this.authProvider = authProvider; + this.useTls = useTls; // Create a new thread to read requests with ThreadHelper th = new ThreadHelper(new WaitCallback(processConnection), null); @@ -90,8 +93,11 @@ this.connection.Close(); } - // Go encrypted... - this.connection.StartTlsAsServer(); + if (this.useTls) + { + // Go encrypted... + this.connection.StartTlsAsServer(); + } int authAttempts = 0; bool authenticated = false; Modified: NMail/trunk/NMail/NMail.csproj =================================================================== --- NMail/trunk/NMail/NMail.csproj 2006-06-06 11:44:08 UTC (rev 42) +++ NMail/trunk/NMail/NMail.csproj 2006-06-06 12:55:52 UTC (rev 43) @@ -122,12 +122,13 @@ <Compile Include="Configuration\ObjectConfigurationElement.cs" /> <Compile Include="Configuration\ObjectConfigurationElementCollection.cs" /> <Compile Include="Configuration\WildcardHostElementCollection.cs" /> + <Compile Include="DataTypes\ACLs\SystemPrivilege.cs" /> <Compile Include="DataTypes\ACLs\GenericAce.cs" /> <Compile Include="DataTypes\ACLs\GenericAcl.cs" /> <Compile Include="DataTypes\ACLs\MailDomainPrivilege.cs" /> - <Compile Include="DataTypes\ACLs\StoreFolderAce.cs" /> <Compile Include="DataTypes\ACLs\StoreFolderAcl.cs" /> <Compile Include="DataTypes\ACLs\StoreFolderPrivilege.cs" /> + <Compile Include="DataTypes\ACLs\UserGroupAdminPrivilege.cs" /> <Compile Include="DataTypes\LocalStoreGro... [truncated message content] |
|
From: <tmy...@us...> - 2006-06-06 15:21:00
|
Revision: 42 Author: tmyroadctfig Date: 2006-06-06 04:44:08 -0700 (Tue, 06 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=42&view=rev Log Message: ----------- Merged in changes from the trunk. Modified Paths: -------------- NMail/branches/luke-dev/NMail.SmtpService/Command/HeloCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/RecipientCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/SenderCommand.cs NMail/branches/luke-dev/NMail.SmtpService/NMail.SmtpService.csproj NMail/branches/luke-dev/NMail.SmtpService/SmtpSession.cs NMail/branches/luke-dev/NMail.SmtpService/State/AbstractSmtpState.cs NMail/branches/luke-dev/NMail.SmtpService/State/ConnectedState.cs NMail/branches/luke-dev/NMail.SmtpService/State/NegotiatedState.cs NMail/branches/luke-dev/NMail.SmtpService/State/RecipientRecievedState.cs NMail/branches/luke-dev/NMail.SmtpService/State/SenderRecievedState.cs NMail/branches/luke-dev/NMail.UnitTests/SmtpServiceTests.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.SmtpService/Command/DataCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/EhloCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/ISmtpCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/NoopCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/QuitCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/ResetCommand.cs NMail/branches/luke-dev/NMail.SmtpService/Command/StartTlsCommand.cs Removed Paths: ------------- NMail/branches/luke-dev/NMail.SmtpService/Command/AbstractCommand.cs NMail/branches/luke-dev/NMail.SmtpService/State/DataState.cs NMail/branches/luke-dev/NMail.SmtpService/State/SmtpState.cs Deleted: NMail/branches/luke-dev/NMail.SmtpService/Command/AbstractCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/AbstractCommand.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/AbstractCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,48 +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.SmtpService.Command { - /// <summary> - /// Provides an abstract SMTP command. - /// </summary> - public abstract class AbstractCommand { - /// <summary> - /// Creates the command from the given command string. Any parameters are - /// extracted at this point. - /// </summary> - /// <param name="command">The command string.</param> - protected AbstractCommand(string command) { - this.command = command; - } - - /// <summary> - /// The full command string. - /// </summary> - private string command; - - /// <summary> - /// The full command string. - /// </summary> - public string Command { - get { - return this.command; - } - } - } -} Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/DataCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/DataCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/DataCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/DataCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,138 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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.Specialized; +using System.Collections.Generic; +using System.Text; +using System.Globalization; +using System.Text.RegularExpressions; + +using NMail.DataTypes; +using NMail.Helper; +using NMail.Configuration; +using NMail.SmtpService.State; +using NMail.SmtpService.Configuration; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command DATA. + /// This command does not expect any arguments. + /// If no arguments are provided to the DATA command server will: + /// <list> + /// <item>Send a continuation response.</item> + /// <item>Read lines of message data until a single period is received (".")</item> + /// <item>Append any required headers.</item> + /// <item>Attempt to spool the message.</item> + /// <item>Send a 250 Ok response if successful.</item> + /// <item>The SMTP session will be transitioned to the NegotiatedState.</item> + /// </list> + /// </summary> + class DataCommand : ISmtpCommand { + #region ISmtpCommand Members + + public void Execute(SmtpSession session, string[] tokens) { + if (tokens.Length != 1) { + throw new ApplicationException("Invalid command syntax"); + } + + session.Connection.OkWaitingData(); + + int maximumMessageSize = SmtpServiceConfiguration.Current.MaximumMessageSize; + IDnsClient dns = NMailConfiguration.Current.DnsClient; + int currentMaxReadLength = session.Connection.MaximumReadLength; + ByteStringBuilder messageData = new ByteStringBuilder( + session.MessageEncoding, + session.SizeEstimate, + maximumMessageSize); + + try { + // Temporarily allow lines of any length + session.Connection.MaximumReadLength = maximumMessageSize; + + // Data is a special case where we don't want to split each incoming line + while (true) { + string dataLine = session.Connection.ReadLine( + session.MessageEncoding, + SmtpServiceConfiguration.Current.Timeout); + + if (dataLine == ".") { + break; + } else { + try { + // TODO: take action if a line is too long? + + messageData.Append(dataLine + session.Connection.Terminator); + } catch (ArgumentOutOfRangeException) { + // Message is too large + session.Connection.ErrorMessageTooLarge(); + + // All bets are off? + session.Message = null; + session.CurrentState = new NegotiatedState(session); + return; + } + } + } + } finally { + // Reset the maximum read line length + session.Connection.MaximumReadLength = currentMaxReadLength; + } + + // Parse the message headers + session.Message.Data = new Message(messageData.ToByteString()); + MessageHeaders headers = session.Message.Data.Headers; + + // Prepare details for the headers + string currentTime = DateTime.Now.ToString("r", DateTimeFormatInfo.InvariantInfo); + Host clientHost = dns.ResolveHost(session.ClientAddress); + string transport = (session.Esmtp) ? "ESMTP" : "SMTP"; + + // Add the received header + string recievedHeader = string.Format(RecievedHeader, session.ReportedHost, + clientHost, session.ClientAddress, SmtpServiceConfiguration.Current.VisibleHost, transport, currentTime); + headers.AppendStart("Recieved", recievedHeader); + + // All message must have a from address and a date. + if (headers["From"] == null) { + headers["From"] = session.Message.Sender.ToString(true); + } + if (headers["Date"] == null) { + headers["Date"] = currentTime; + } + + try { + // Attempt to spool the message + NMailConfiguration.Current.Router.SpoolMessage(session.Message); + session.Connection.Ok(); + } catch (Exception ex) { + session.Log.Warn("Error spooling message.", ex); + session.Connection.TemporaryBadResponse(ex.Message); + } + + session.Message = null; + session.CurrentState = new NegotiatedState(session); + } + + /// <summary> + /// The format of the "Received:" header line that must be added to the message. + /// </summary> + public const string RecievedHeader = "from {0} ({1} [{2}])\r\n\tby NMail ({3}) with {4} {5}"; + + #endregion + } +} Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/EhloCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/EhloCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/EhloCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/EhloCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,50 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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.SmtpService.Configuration; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command EHLO. + /// This command expects the connecting host's name as its sole argument. + /// The execution of a valid EHLO command will result in the following: + /// <list> + /// <item>The session will be marked as Extended SMTP (ESMTP)</item> + /// <item>The hostname of the client will be attached to the session</item> + /// <item>A 250 response will be sent to the client, with a list of the + /// SMTP server's capabilities. + /// </item> + /// <item>The SMTP session will be transitioned to the NegotiatedState.</item> + /// </list> + /// </summary> + class EhloCommand : HeloCommand { + #region ISmtpCommand Members + + public override void Execute(SmtpSession session, string[] tokens) { + ExecuteNoResponse(session, tokens); + session.Esmtp = true; + session.Connection.OkCapabilities(SmtpServiceConfiguration.Current.VisibleHost, + SmtpServiceConfiguration.Current.MaximumMessageSize); + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.SmtpService/Command/HeloCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/HeloCommand.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/HeloCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,40 +19,51 @@ using NMail.DataTypes; using NMail.Helper; +using NMail.SmtpService.Configuration; +using NMail.SmtpService.State; namespace NMail.SmtpService.Command { /// <summary> - /// Provides parsing for the HELO command. + /// Represents the logic for handling the SMTP command HELO. + /// This command expects the connecting host's name as its sole argument. + /// The execution of a valid HELO command will result in the following: + /// <list> + /// <item>The session will be marked as NOT Extended SMTP (ESMTP)</item> + /// <item>The hostname of the client will be attached to the session</item> + /// <item>A 250 response will be sent to the client</item> + /// <item>The SMTP session will be transitioned to the NegotiatedState</item> + /// </list> /// </summary> - public class HeloCommand : AbstractCommand { - /// <summary> - /// The extracted hostname. - /// </summary> - private Host hostname; + public class HeloCommand : ISmtpCommand { + #region ISmtpCommand Members + + public virtual void Execute(SmtpSession session, string[] tokens) { + ExecuteNoResponse(session, tokens); + session.Connection.OkHelo(SmtpServiceConfiguration.Current.VisibleHost); + } + + #endregion + /// <summary> - /// Attempts to extract a hostname from a HELO command. + /// A helper that executes all command logic except for response to the client /// </summary> - /// <param name="command">The full command string.</param> - public HeloCommand(string command) : base(command) { - string[] tokens = command.Split(' '); + /// <param name="session"></param> + /// <param name="tokens"></param> + protected void ExecuteNoResponse(SmtpSession session, string[] tokens) { + Host hostname = null; if (tokens.Length == 2) { string hostStr = tokens[1]; hostStr = StringTokenizer.UnBracketString(hostStr); - this.hostname = new Host(hostStr); + hostname = new Host(hostStr); } else { throw new ApplicationException("Invalid command syntax"); } - } - /// <summary> - /// The extracted hostname. - /// </summary> - public Host Hostname { - get { - return this.hostname; - } + session.ReportedHost = hostname; + session.Esmtp = false; + session.CurrentState = new NegotiatedState(session); } } } Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/ISmtpCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/ISmtpCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/ISmtpCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/ISmtpCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,34 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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.SmtpService.Command { + /// <summary> + /// Interface for SMTP commands. + /// </summary> + public interface ISmtpCommand { + /// <summary> + /// Executes the command and sends a response to the client. + /// </summary> + /// <param name="session">The current command's session, including the connection + /// for delivering a response</param> + /// <param name="tokens">The arguments supplied to the command. tokens[0] is the command + /// name itself</param> + void Execute(SmtpSession session, string [] tokens); + } +} Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/NoopCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/NoopCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/NoopCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/NoopCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,35 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command NOOP. + /// </summary> + class NoopCommand : ISmtpCommand { + #region ISmtpCommand Members + + public void Execute(SmtpSession session, string[] tokens) { + session.Connection.Ok(); + } + + #endregion + } +} Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/QuitCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/QuitCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/QuitCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/QuitCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,37 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command QUIT. + /// Executing this command causes the connection to the client to be closed. + /// </summary> + class QuitCommand : ISmtpCommand { + + #region ISmtpCommand Members + + public void Execute(SmtpSession session, string[] tokens) { + session.Connection.Close(); + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.SmtpService/Command/RecipientCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/RecipientCommand.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/RecipientCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,23 +18,19 @@ using System; using NMail.DataTypes; +using NMail.Configuration; +using NMail.SmtpService.Configuration; +using NMail.SmtpService.State; namespace NMail.SmtpService.Command { /// <summary> /// Provides parsing for the "RCPT TO:" command. /// </summary> - public class RecipientCommand : AbstractCommand { - /// <summary> - /// The extracted recipient. - /// </summary> - private EmailAddress recipient; + public class RecipientCommand : ISmtpCommand { + #region ISmtpCommand Members - /// <summary> - /// Attempts to extract a recipient from a "RCPT TO:" command. - /// </summary> - /// <param name="command">The full command string.</param> - public RecipientCommand(string command) : base(command) { - string[] tokens = command.Split(' '); + public void Execute(SmtpSession session, string[] tokens) { + EmailAddress recipientEmail = null; if (tokens[1].ToLower().StartsWith("to:")) { // Extract the recipient address @@ -43,28 +39,48 @@ if (tokens.Length != 2) { throw new ApplicationException("Bad command syntax."); } else { - this.recipient = new EmailAddress(tokens[1].Remove(0, 3), true); + recipientEmail = new EmailAddress(tokens[1].Remove(0, 3), true); } } else { if (tokens.Length != 3) { throw new ApplicationException("Bad command syntax."); } else { - this.recipient = new EmailAddress(tokens[2], true); + recipientEmail = new EmailAddress(tokens[2], true); } } } else { // Missing the correct "TO:" part of the command throw new ApplicationException("Bad command syntax."); } - } - /// <summary> - /// The extracted recipient. - /// </summary> - public EmailAddress Recipient { - get { - return this.recipient; + SmtpMessageRecipient recipient = + new SmtpMessageRecipient(session.Message, recipientEmail); + + // Check the recipient + DeliveryResult result = NMailConfiguration.Current.Router.ValidateRecipient(recipient); + switch (result.Type) { + case DeliveryResultType.PermanentError: + session.Connection.ErrorBadRecipient(recipient); + session.IncrementBadRecipientCount(); + break; + + case DeliveryResultType.TemporaryError: + session.Connection.TemporaryBadRecipient(recipient); + break; + + case DeliveryResultType.Success: + if (session.Message.RecipientCount <= SmtpServiceConfiguration.Current.RecipientLimit) { + session.Message.AddRecipient(recipient); + session.Connection.OkRecipient(recipient); + session.CurrentState = new RecipientRecievedState(session); + } else { + session.Connection.TemporaryBadRecipient(recipient); + } + break; } + } + + #endregion } } Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/ResetCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/ResetCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/ResetCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/ResetCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,63 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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.SmtpService.State; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command RSET. + /// This command expects no arguments. + /// The execution of a valid RSET command will result in the following: + /// <list> + /// <item>A 250 response will be sent to the client</item> + /// <item>The SMTP session will be transitioned to the either the + /// ConnectedState or the NegotiatedState depending on how + /// the command was created.</item> + /// </list> + /// </summary> + class ResetCommand : ISmtpCommand { + private bool isNegotiated; + + public ResetCommand(bool isNegotiated) { + this.isNegotiated = isNegotiated; + } + + #region ISmtpCommand Members + + public void Execute(SmtpSession session, string[] tokens) { + + if (tokens.Length == 1) { + // Reset state to negotiated unless we have not yet negotiated + if (isNegotiated) { + session.CurrentState = new NegotiatedState(session); + } else { + session.CurrentState = new ConnectedState(session); + } + + session.Message = null; + session.Connection.Ok(); + } else { + throw new ApplicationException("Invalid command syntax"); + } + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.SmtpService/Command/SenderCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/SenderCommand.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/SenderCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,41 +19,30 @@ using System.Text; using NMail.DataTypes; +using NMail.SmtpService.Configuration; +using NMail.SmtpService.State; namespace NMail.SmtpService.Command { /// <summary> /// Provides parsing for the "MAIL FROM:" command. /// </summary> - public class SenderCommand : AbstractCommand { - /// <summary> - /// The extracted sender. - /// </summary> - private EmailAddress sender; + public class SenderCommand : ISmtpCommand { + #region ISmtpCommand Members - /// <summary> - /// The encoding for the message as reported by the client. - /// </summary> - private Encoding encoding; + public void Execute(SmtpSession session, string[] tokens) { + int sizeEstimate = 0; + Encoding encoding = Encoding.ASCII; + EmailAddress sender = null; - /// <summary> - /// The estimated size of the message in bytes as given by the client. - /// </summary> - private int sizeEstimate; - - public SenderCommand(string command) : base(command) { - this.sizeEstimate = 0; - this.encoding = Encoding.ASCII; - string[] tokens = command.Split(' '); - - if (tokens[1].ToLower().StartsWith("from:")) { + if (tokens.Length > 1 && tokens[1].ToLower().StartsWith("from:")) { // Handle the case where the "FROM:" and email address aren't seperated by whitespace int i; if (tokens[1].Length > 5) { i = 2; - this.sender = new EmailAddress(tokens[1].Remove(0, 5), true); + sender = new EmailAddress(tokens[1].Remove(0, 5), true); } else { i = 3; - this.sender = new EmailAddress(tokens[2], true); + sender = new EmailAddress(tokens[2], true); } #region Parameter Parsing @@ -66,17 +55,17 @@ } else if (parameter.StartsWith("size=")) { // Get the size estimate parameter = parameter.Remove(0, 5); - this.sizeEstimate = Int32.Parse(parameter); + sizeEstimate = Int32.Parse(parameter); } else if (parameter.StartsWith("body=")) { // Get the body type parameter = parameter.Remove(0, 5); switch (parameter) { case "7bit": - this.encoding = Encoding.ASCII; + encoding = Encoding.ASCII; break; case "8bitmime": - this.encoding = Encoding.UTF8; + encoding = Encoding.UTF8; break; default: @@ -94,33 +83,18 @@ // Missing the correct "FROM:" part of the command throw new ApplicationException("Bad command syntax."); } - } - /// <summary> - /// The extracted sender. - /// </summary> - public EmailAddress Sender { - get { - return this.sender; + if (sizeEstimate > SmtpServiceConfiguration.Current.MaximumMessageSize) { + session.Connection.ErrorMessageTooLarge(); + } else { + session.Message.Sender = sender; + session.SizeEstimate = sizeEstimate; + session.MessageEncoding = encoding; + session.Connection.Ok(); + session.CurrentState = new SenderRecievedState(session); } } - /// <summary> - /// The extracted size estimate for the message. - /// </summary> - public int SizeEstimate { - get { - return this.sizeEstimate; - } - } - - /// <summary> - /// The extracted encoding for the message data. - /// </summary> - public Encoding MessageEncoding { - get { - return this.encoding; - } - } + #endregion } } Copied: NMail/branches/luke-dev/NMail.SmtpService/Command/StartTlsCommand.cs (from rev 41, NMail/trunk/NMail.SmtpService/Command/StartTlsCommand.cs) =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/Command/StartTlsCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.SmtpService/Command/StartTlsCommand.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -0,0 +1,42 @@ +/* + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. + * + * 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; + +namespace NMail.SmtpService.Command { + /// <summary> + /// Represents the logic for handling the SMTP command STARTTLS. + /// This command expects no arguments. + /// The execution of a valid STARTTLS command will result in the following: + /// <list> + /// <item>A 250 response will be sent to the client</item> + /// <item>TLS negotiation will begin.</item> + /// </list> + /// </summary> + class StartTlsCommand : ISmtpCommand { + #region ISmtpCommand Members + + public void Execute(SmtpSession session, string[] tokens) { + session.Connection.Ok(); + session.Connection.StartTlsAsServer(); + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.SmtpService/NMail.SmtpService.csproj =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/NMail.SmtpService.csproj 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/NMail.SmtpService.csproj 2006-06-06 11:44:08 UTC (rev 42) @@ -35,8 +35,7 @@ <ConfigurationOverrideFile> </ConfigurationOverrideFile> <DefineConstants>DEBUG;TRACE</DefineConstants> - <DocumentationFile> - </DocumentationFile> + <DocumentationFile>bin\Debug\NMail.SmtpService.XML</DocumentationFile> <DebugSymbols>true</DebugSymbols> <FileAlignment>4096</FileAlignment> <NoStdLib>false</NoStdLib> @@ -98,18 +97,22 @@ <Compile Include="AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> - <Compile Include="Command\AbstractCommand.cs"> - <SubType>Code</SubType> - </Compile> + <Compile Include="Command\DataCommand.cs" /> + <Compile Include="Command\EhloCommand.cs" /> <Compile Include="Command\HeloCommand.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Command\ISmtpCommand.cs" /> + <Compile Include="Command\NoopCommand.cs" /> + <Compile Include="Command\QuitCommand.cs" /> <Compile Include="Command\RecipientCommand.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Command\ResetCommand.cs" /> <Compile Include="Command\SenderCommand.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Command\StartTlsCommand.cs" /> <Compile Include="Configuration\SmtpServiceConfiguration.cs"> <SubType>Code</SubType> </Compile> @@ -128,9 +131,6 @@ <Compile Include="State\ConnectedState.cs"> <SubType>Code</SubType> </Compile> - <Compile Include="State\DataState.cs"> - <SubType>Code</SubType> - </Compile> <Compile Include="State\NegotiatedState.cs"> <SubType>Code</SubType> </Compile> @@ -140,9 +140,6 @@ <Compile Include="State\SenderRecievedState.cs"> <SubType>Code</SubType> </Compile> - <Compile Include="State\SmtpState.cs"> - <SubType>Code</SubType> - </Compile> <Content Include="NMail.SmtpService.build" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> @@ -152,4 +149,4 @@ <PostBuildEvent> </PostBuildEvent> </PropertyGroup> -</Project> \ No newline at end of file +</Project> Modified: NMail/branches/luke-dev/NMail.SmtpService/SmtpSession.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/SmtpSession.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/SmtpSession.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -131,7 +131,7 @@ this.connection.StartIdleTimeout(); // Change to initial state and start processing commands - this.ChangeState(SmtpState.Connected); + this.currentState = new ConnectedState(this); this.CommandLoop(); } catch (Exception e) { // Probably an IO exception, ignore... @@ -161,47 +161,8 @@ command = this.connection.ReadLine(this.config.Timeout).Trim(); cmdTokens = command.Split(' '); - // attempt to process the command - switch (cmdTokens[0].ToLower()) { - case "quit": - this.connection.Close(); - break; - - case "noop": - this.currentState.Noop(command); - break; - - case "ehlo": - this.currentState.Ehlo(command); - break; - - case "helo": - this.currentState.Helo(command); - break; - - case "mail": - this.currentState.MailFrom(command); - break; - - case "rcpt": - this.currentState.RcptTo(command); - break; - - case "data": - this.currentState.Data(command); - break; - - case "rset": - this.currentState.Rset(command); - break; - - case "starttls": - this.currentState.StartTls(command); - break; - - default: - throw new ApplicationException("Invalid command."); - } + // process the command + this.currentState.Execute(command); } catch (TimeoutException) { // Timedout reading data from client this.connection.ErrorReadTimedout(); @@ -232,32 +193,11 @@ } /// <summary> - /// Changes the current state for the session. + /// Gets or set the current state of the session /// </summary> - /// <param name="newState">The new state to change to.</param> - internal void ChangeState(SmtpState newState) { - switch (newState) { - case SmtpState.Connected: - this.currentState = new ConnectedState(this); - break; - - case SmtpState.Negotiated: - this.currentState = new NegotiatedState(this); - break; - - case SmtpState.SenderRecieved: - this.currentState = new SenderRecievedState(this); - break; - - case SmtpState.RecipientRecieved: - this.currentState = new RecipientRecievedState(this); - break; - - case SmtpState.Data: - // The data state is a special case. - new DataState(this); - break; - } + internal AbstractSmtpState CurrentState { + get { return this.currentState; } + set { this.currentState = value; } } /// <summary> Modified: NMail/branches/luke-dev/NMail.SmtpService/State/AbstractSmtpState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/AbstractSmtpState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/AbstractSmtpState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,31 @@ */ using System; +using System.Collections.Generic; using NMail; using NMail.Configuration; using NMail.DataTypes; using NMail.SmtpService; using NMail.SmtpService.Configuration; +using NMail.SmtpService.Command; namespace NMail.SmtpService.State { /// <summary> - /// Provides common SMTP session state functions. + /// <para> + /// Base class for SMTP session states, which provides common SMTP session + /// state functions. To implement a state, extend this class and add supported + /// commands to the <see cref="Commands">Commands</see> collection. Common + /// commands supported in all states have already been added. + /// </para> + /// <para> + /// Example (add this to your subclass constructor): + /// <code> + /// this.Commands["helo"] = new HeloCommand(); + /// this.Commands["ehlo"] = new EhloCommand(); + /// this.Commands["rset"] = new ResetCommand(false); + /// </code> + /// </para> /// </summary> public abstract class AbstractSmtpState { /// <summary> @@ -49,7 +64,14 @@ protected SmtpMessage message; /// <summary> + /// The collection of valid commands for this state, indexed by command name + /// </summary> + private IDictionary<string, ISmtpCommand> commands; + + /// <summary> /// Creates a new instance of the state using the given session. + /// Adds common QUIT, NOOP, and STARTTLS commands to collection of + /// supported commands. /// </summary> /// <param name="session">The session that owns this state.</param> protected AbstractSmtpState(SmtpSession session) { @@ -57,79 +79,48 @@ this.message = this.session.Message; this.messageRouter = NMailConfiguration.Current.Router; this.config = SmtpServiceConfiguration.Current; + + this.commands = new Dictionary<string, ISmtpCommand>(); + this.Commands["quit"] = new QuitCommand(); + this.Commands["noop"] = new NoopCommand(); + this.Commands["starttls"] = new StartTlsCommand(); } - #region Default Smtp Commands /// <summary> - /// The default action to perform for a NOOP command. + /// The collection of valid commands for this state. + /// Keys are command names (as provided by the client), in lowercase. + /// Values are the command to be supported by the name given as key. /// </summary> - /// <param name="command">The full command string.</param> - public virtual void Noop(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - session.Connection.Ok(); - } else { - throw new ApplicationException("Invalid command syntax."); + public IDictionary<string, ISmtpCommand> Commands { + get { + return this.commands; } } /// <summary> - /// The default action to perform for a RSET command. + /// Attempts to parse and execute <code>commandString</code>. + /// First word (delimited by space or end of line) is interpreted as + /// command name. If the command name corresponds to a supported command + /// in the <see cref="Commands">Commands</see> collection, the appropriate + /// command is executed. Otherwise, an <code>ApplicationException</code> + /// is thrown. /// </summary> - /// <param name="command">The full command string.</param> - public virtual void Rset(string command) { - throw new ApplicationException("Invalid state."); - } + /// <param name="commandString"></param> + /// <exception cref="ApplicationException">Application Exception thrown for + /// invalid command syntax or an unsupported command</exception> + public virtual void Execute(string commandString) { + string [] tokens = commandString.Split(' '); - /// <summary> - /// The default action to perform for a HELO command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void Helo(string command) { - throw new ApplicationException("Invalid state."); - } + if (tokens.Length == 0) { + throw new ApplicationException("Invalid command syntax."); + } - /// <summary> - /// The default action to perform for a EHLO command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void Ehlo(string command) { - throw new ApplicationException("Invalid state."); - } + string commandName = tokens[0].ToLower(); + if (!this.Commands.ContainsKey(commandName)) { + throw new ApplicationException("Invalid Command."); + } - /// <summary> - /// The default action to perform for a "MAIL FROM:" command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void MailFrom(string command) { - throw new ApplicationException("Invalid state."); + this.Commands[commandName].Execute(session, tokens); } - - /// <summary> - /// The default action to perform for a "RCPT TO:" command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void RcptTo(string command) { - throw new ApplicationException("Invalid state."); - } - - /// <summary> - /// The default action to perform for a DATA command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void Data(string command) { - throw new ApplicationException("Invalid state."); - } - - /// <summary> - /// The default action to perform for a STARTTLS command. - /// </summary> - /// <param name="command">The full command string.</param> - public virtual void StartTls(string command) { - this.session.Connection.Ok(); - this.session.Connection.StartTlsAsServer(); - } - #endregion } } Modified: NMail/branches/luke-dev/NMail.SmtpService/State/ConnectedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/ConnectedState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/ConnectedState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,46 +30,11 @@ /// </summary> /// <param name="session">The session the owns this state.</param> public ConnectedState(SmtpSession session) : base(session) { + this.Commands["helo"] = new HeloCommand(); + this.Commands["ehlo"] = new EhloCommand(); + this.Commands["rset"] = new ResetCommand(false); + this.session.Connection.Welcome(this.config.VisibleHost); } - - /// <summary> - /// The HELO command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Helo(string command) { - HeloCommand heloCommand = new HeloCommand(command); - this.session.ReportedHost = heloCommand.Hostname; - this.session.Esmtp = false; - this.session.Connection.OkHelo(this.config.VisibleHost); - this.session.ChangeState(SmtpState.Negotiated); - } - - /// <summary> - /// The EHLO command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Ehlo(string command) { - HeloCommand heloCommand = new HeloCommand(command); - this.session.ReportedHost = heloCommand.Hostname; - this.session.Esmtp = true; - this.session.Connection.OkCapabilities(this.config.VisibleHost, - this.config.MaximumMessageSize); - this.session.ChangeState(SmtpState.Negotiated); - } - - /// <summary> - /// The RSET command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Rset(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - this.session.Connection.Ok(); - } else { - throw new ApplicationException("Invalid command syntax"); - } - } } } Deleted: NMail/branches/luke-dev/NMail.SmtpService/State/DataState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/DataState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/DataState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,124 +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; -using System.Collections.Specialized; -using System.Text; -using System.Globalization; -using System.Text.RegularExpressions; - -using NMail.Configuration; -using NMail.DataTypes; -using NMail.Helper; - -namespace NMail.SmtpService.State { - /// <summary> - /// Defines command behaviour in the data state. - /// </summary> - public class DataState : AbstractSmtpState { - /// <summary> - /// The name server for this state. - /// </summary> - private IDnsClient dns; - - /// <summary> - /// Creates a new instance of the state. - /// </summary> - /// <param name="session">The session the owns this state.</param> - public DataState(SmtpSession session) : base(session) { - int maximumMessageSize = this.config.MaximumMessageSize; - this.dns = NMailConfiguration.Current.DnsClient; - int currentMaxReadLength = this.session.Connection.MaximumReadLength; - ByteStringBuilder messageData = new ByteStringBuilder( - this.session.MessageEncoding, - this.session.SizeEstimate, - maximumMessageSize); - - try { - // Temporarily allow lines of any length - this.session.Connection.MaximumReadLength = maximumMessageSize; - - // Data is a special case where we don't want to split each incoming line - while (true) { - string dataLine = this.session.Connection.ReadLine( - this.session.MessageEncoding, - this.config.Timeout); - - if (dataLine == ".") { - break; - } else { - try { - // TODO: take action if a line is too long? - - messageData.Append(dataLine + this.session.Connection.Terminator); - } catch (ArgumentOutOfRangeException) { - // Message is too large - this.session.Connection.ErrorMessageTooLarge(); - - // All bets are off? - this.session.Message = null; - this.session.ChangeState(SmtpState.Negotiated); - return; - } - } - } - } finally { - // Reset the maximum read line length - this.session.Connection.MaximumReadLength = currentMaxReadLength; - } - - // Parse the message headers - this.message.Data = new Message(messageData.ToByteString()); - MessageHeaders headers = this.message.Data.Headers; - - // Prepare details for the headers - string currentTime = DateTime.Now.ToString("r", DateTimeFormatInfo.InvariantInfo); - Host clientHost = dns.ResolveHost(this.session.ClientAddress); - string transport = (this.session.Esmtp) ? "ESMTP" : "SMTP"; - - // Add the received header - string recievedHeader = string.Format(DataState.RecievedHeader, this.session.ReportedHost, - clientHost, this.session.ClientAddress, this.config.VisibleHost, transport, currentTime); - headers.AppendStart("Recieved", recievedHeader); - - // All message must have a from address and a date. - if (headers["From"] == null) { - headers["From"] = this.message.Sender.ToString(true); - } - if (headers["Date"] == null) { - headers["Date"] = currentTime; - } - - try { - // Attempt to spool the message - this.messageRouter.SpoolMessage(this.message); - this.session.Connection.Ok(); - } catch (Exception ex) { - this.session.Log.Warn("Error spooling message.", ex); - this.session.Connection.TemporaryBadResponse(ex.Message); - } - - this.session.Message = null; - this.session.ChangeState(SmtpState.Negotiated); - } - - /// <summary> - /// The format of the "Received:" header line that must be added to the message. - /// </summary> - public const string RecievedHeader = "from {0} ({1} [{2}])\r\n\tby NMail ({3}) with {4} {5}"; - } -} Modified: NMail/branches/luke-dev/NMail.SmtpService/State/NegotiatedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/NegotiatedState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/NegotiatedState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,41 +30,14 @@ /// </summary> /// <param name="session">The session the owns this state.</param> public NegotiatedState(SmtpSession session) : base(session) { + this.Commands["mail"] = new SenderCommand(); + this.Commands["rset"] = new ResetCommand(true); + // Create a new message this.session.Message = new SmtpMessage(); this.message = this.session.Message; this.message.ReportedHost = this.session.ReportedHost; this.message.SourceAddress = session.ClientAddress; } - - public override void MailFrom(string command) { - // Parse mail from, extracting sender and parameters - SenderCommand senderCommand = new SenderCommand(command); - - // Check the message size is ok - if (senderCommand.SizeEstimate > this.config.MaximumMessageSize) { - this.session.Connection.ErrorMessageTooLarge(); - } else { - this.message.Sender = senderCommand.Sender; - this.session.SizeEstimate = senderCommand.SizeEstimate; - this.session.MessageEncoding = senderCommand.MessageEncoding; - this.session.Connection.Ok(); - this.session.ChangeState(SmtpState.SenderRecieved); - } - } - - /// <summary> - /// The RSET command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Rset(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - this.session.Connection.Ok(); - } else { - throw new ApplicationException("Invalid command syntax"); - } - } } } Modified: NMail/branches/luke-dev/NMail.SmtpService/State/RecipientRecievedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/RecipientRecievedState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/RecipientRecievedState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,70 +29,10 @@ /// Creates a new instance of the state. /// </summary> /// <param name="session">The session the owns this state.</param> - public RecipientRecievedState(SmtpSession session) : base(session) { } - - /// <summary> - /// The "RCPT TO:" command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void RcptTo(string command) { - // Get the recipient address - RecipientCommand recipientCommand = new RecipientCommand(command); - SmtpMessageRecipient recipient = - new SmtpMessageRecipient(this.message, recipientCommand.Recipient); - - // Check the recipient - DeliveryResult result = this.messageRouter.ValidateRecipient(recipient); - switch (result.Type) { - case DeliveryResultType.PermanentError: - this.session.Connection.ErrorBadRecipient(recipient); - this.session.IncrementBadRecipientCount(); - break; - - case DeliveryResultType.TemporaryError: - this.session.Connection.TemporaryBadRecipient(recipient); - break; - - case DeliveryResultType.Success: - if (this.message.RecipientCount <= this.config.RecipientLimit) { - this.message.AddRecipient(recipient); - this.session.Connection.OkRecipient(recipient); - } else { - this.session.Connection.TemporaryBadRecipient(recipient); - } - break; - } + public RecipientRecievedState(SmtpSession session) : base(session) { + this.Commands["rcpt"] = new RecipientCommand(); + this.Commands["data"] = new DataCommand(); + this.Commands["rset"] = new ResetCommand(true); } - - /// <summary> - /// The DATA command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Data(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - this.session.Connection.OkWaitingData(); - this.session.ChangeState(SmtpState.Data); - } else { - throw new ApplicationException("Invalid command syntax"); - } - } - - /// <summary> - /// The RSET command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Rset(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - this.session.Message = null; - this.session.Connection.Ok(); - this.session.ChangeState(SmtpState.Negotiated); - } else { - throw new ApplicationException("Invalid command syntax"); - } - } } } Modified: NMail/branches/luke-dev/NMail.SmtpService/State/SenderRecievedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/SenderRecievedState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/SenderRecievedState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Luke Quinane and Daniel Frampton + * Copyright 2004-2006 Luke Quinane, Daniel Frampton and Jared Hodges. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,52 +31,9 @@ /// Creates a new instance of the state. /// </summary> /// <param name="session">The session the owns this state.</param> - public SenderRecievedState(SmtpSession session) : base(session) { } - - /// <summary> - /// The "RCPT TO:" command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void RcptTo(string command) { - // Get the recipient address - RecipientCommand recipientCommand = new RecipientCommand(command); - SmtpMessageRecipient recipient = - new SmtpMessageRecipient(this.message, recipientCommand.Recipient); - - // Check the recipient - DeliveryResult result = this.messageRouter.ValidateRecipient(recipient); - switch (result.Type) { - case DeliveryResultType.PermanentError: - this.session.Connection.ErrorBadRecipient(recipient); - this.session.IncrementBadRecipientCount(); - break; - - case DeliveryResultType.TemporaryError: - this.session.Connection.TemporaryBadRecipient(recipient); - break; - - case DeliveryResultType.Success: - this.message.AddRecipient(recipient); - this.session.Connection.OkRecipient(recipient); - this.session.ChangeState(SmtpState.RecipientRecieved); - break; - } + public SenderRecievedState(SmtpSession session) : base(session) { + this.Commands["rcpt"] = new RecipientCommand(); + this.Commands["rset"] = new ResetCommand(true); } - - /// <summary> - /// The RSET command for this state. - /// </summary> - /// <param name="command">The full command string.</param> - public override void Rset(string command) { - string[] tokens = command.Split(' '); - - if (tokens.Length == 1) { - this.session.Message = null; - this.session.Connection.Ok(); - this.session.ChangeState(SmtpState.Negotiated); - } else { - throw new ApplicationException("Invalid command syntax"); - } - } } } Deleted: NMail/branches/luke-dev/NMail.SmtpService/State/SmtpState.cs =================================================================== --- NMail/branches/luke-dev/NMail.SmtpService/State/SmtpState.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.SmtpService/State/SmtpState.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -1,50 +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.SmtpService.State { - /// <summary> - /// Describes the current state of an SMTP connection. - /// </summary> - public enum SmtpState { - /// <summary> - /// The client has connected but not said "HELO". - /// </summary> - Connected, - - /// <summary> - /// The client has said "HELO" and supplied a valid hostname - /// </summary> - Negotiated, - - /// <summary> - /// The client has given a valid sender - /// </summary> - SenderRecieved, - - /// <summary> - /// The client has given one or more valid recipients - /// </summary> - RecipientRecieved, - - /// <summary> - /// The client has sent a data command - /// </summary> - Data - }; -} Modified: NMail/branches/luke-dev/NMail.UnitTests/SmtpServiceTests.cs =================================================================== --- NMail/branches/luke-dev/NMail.UnitTests/SmtpServiceTests.cs 2006-06-06 11:32:51 UTC (rev 41) +++ NMail/branches/luke-dev/NMail.UnitTests/SmtpServiceTests.cs 2006-06-06 11:44:08 UTC (rev 42) @@ -39,7 +39,12 @@ /// </summary> private void Open() { this.connection = new TcpTextConnection(log); - this.connection.Open(new Host(IPAddress.Loopback), 25); + try { + this.connection.Open(new Host(IPAddress.Loopback), 25); + } catch (System.Net.Sockets.SocketException e) { + Assert.Fail(e.Message + + "\n(These tests are not standalone - you may need to manually start the SMTP Service.)"); + } // Should get a 220 response string welcome = this.connection.ReadLine(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-02 13:27:24
|
Revision: 40 Author: tmyroadctfig Date: 2006-06-02 06:26:56 -0700 (Fri, 02 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=40&view=rev Log Message: ----------- Further work on admin website. Modified Paths: -------------- NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -83,6 +83,14 @@ StoreFolder GetStoreFolder(IAuthenticationToken authToken, string folder); /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invalid.</returns> + StoreFolder GetStoreFolder(IAuthenticationToken authToken, int folderId); + + /// <summary> /// Creates a new folder. /// </summary> /// <remarks> @@ -97,9 +105,9 @@ /// Deletes an existing folder. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, StoreFolder folder); + LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, int folderId); /// <summary> /// Renames an existing folder in the local store. Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -58,6 +58,13 @@ StoreFolder GetStoreFolder(Folder folder); /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder Id is invalid.</returns> + StoreFolder GetStoreFolder(int folderId); + + /// <summary> /// Gets the parent folder for the given folder. /// </summary> /// <param name="folder">The folder to lookup the parent of.</param> @@ -77,9 +84,9 @@ /// <summary> /// Deletes an existing folder. /// </summary> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - LocalStoreFolderResult DeleteFolder(StoreFolder folder); + LocalStoreFolderResult DeleteFolder(int folderId); /// <summary> /// Renames an existing folder in the local store. Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/FolderDataSource.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Data; +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; +using NMail.Authentication; +using NMail.DataTypes; + +namespace NMail.Administration.Web +{ + /// <summary> + /// Summary description for FolderDataSource + /// </summary> + public static class FolderDataSource + { + public static List<StoreFolder> GetFolders() + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + //return new List<StoreFolder>(localStore.GetStoreFolder(authToken)); + return null; + } + + public static StoreFolder GetFolder(int folderId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.GetStoreFolder(authToken, folderId); + } + + public static List<StoreFolder> GetSubFolders(int folderId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + StoreFolder parent = localStore.GetStoreFolder(authToken, folderId); + return new List<StoreFolder>(localStore.GetChildren(authToken, parent)); + } + + public static LocalStoreFolderResult DeleteFolder(int folderId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.DeleteFolder(authToken, folderId); + } + + public static LocalStoreFolderResult CreateFolder(string folderName) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.CreateFolder(authToken, folderName); + } + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx 2006-06-02 13:26:56 UTC (rev 40) @@ -0,0 +1,60 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="FolderDetails.aspx.cs" Inherits="FolderDetails" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>Folder Details</h2> + <asp:Literal ID="StatusMessage" runat="server"></asp:Literal> + <asp:DetailsView ID="FolderDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" DataSourceID="FolderDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" InsertVisible="False" ReadOnly="True" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" InsertVisible="False" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" InsertVisible="False" /> + <asp:CommandField ShowDeleteButton="True" ShowInsertButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="FolderDataSource" runat="server" SelectMethod="GetFolder" + TypeName="NMail.Administration.Web.FolderDataSource" DeleteMethod="DeleteFolder" OnDeleted="FolderDataSource_Deleted" OnDeleting="FolderDataSource_Deleting" InsertMethod="CreateFolder" OnInserting="FolderDataSource_Inserting"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + <DeleteParameters> + <asp:Parameter Name="folderId" Type="Int32" /> + </DeleteParameters> + <InsertParameters> + <asp:Parameter Name="folderName" Type="String" /> + </InsertParameters> + </asp:ObjectDataSource> + <h2>Sub-folders</h2> + <asp:GridView ID="SubFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" + DataSourceID="FolderChildrenDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="HasChildren" SortExpression="HasChildren" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + HeaderText="Details" Text="details" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> + <asp:ObjectDataSource ID="FolderChildrenDataSource" runat="server" SelectMethod="GetSubFolders" + TypeName="NMail.Administration.Web.FolderDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="folderId" QueryStringField="FolderId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/FolderDetails.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -0,0 +1,44 @@ +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; + +using NMail; + +public partial class FolderDetails : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } + + protected void FolderDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) + { + e.InputParameters["folderId"] = Request.QueryString["FolderId"]; + } + + protected void FolderDataSource_Deleted(object sender, ObjectDataSourceStatusEventArgs e) + { + LocalStoreFolderResult result = (LocalStoreFolderResult)e.ReturnValue; + + switch (result) + { + case LocalStoreFolderResult.HasChildren: + this.StatusMessage.Text = "Cannot delete the folder because it still has sub-folders."; + break; + } + } + protected void FolderDataSource_Inserting(object sender, ObjectDataSourceMethodEventArgs e) + { + + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-02 13:26:56 UTC (rev 40) @@ -39,6 +39,8 @@ <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + HeaderText="Details" Text="details" /> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> Added: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx 2006-06-02 13:26:56 UTC (rev 40) @@ -0,0 +1,24 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewFolders.aspx.cs" Inherits="ViewFolders" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:GridView ID="FoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" + DataSourceID="FoldersDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> + <asp:HyperLinkField DataNavigateUrlFields="FolderId" DataNavigateUrlFormatString="FolderDetails.aspx?FolderId={0}" + HeaderText="Details" Text="details" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> + <asp:ObjectDataSource ID="FoldersDataSource" runat="server" SelectMethod="GetFolders" + TypeName="NMail.Administration.Web.FolderDataSource"></asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewFolders.aspx.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -0,0 +1,21 @@ +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 ViewFolders : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-06-02 13:26:56 UTC (rev 40) @@ -4,5 +4,6 @@ <siteMapNode url="Login.aspx" title="Login" description="" /> <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" /> <siteMapNode url="ViewUsers.aspx" title="Users" description="" /> + <siteMapNode url="ViewFolders.aspx" title="Folders" description="" /> </siteMapNode> </siteMap> Modified: NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs =================================================================== --- NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail.ImapService/State/AuthenticatedState.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -270,7 +270,7 @@ StoreFolder folder = LocalStore.GetStoreFolder(Session.AuthenticationToken, cmd.Folder); if (folder != null) { - LocalStoreFolderResult result = LocalStore.DeleteFolder(Session.AuthenticationToken, folder); + LocalStoreFolderResult result = LocalStore.DeleteFolder(Session.AuthenticationToken, folder.FolderId); if (result == LocalStoreFolderResult.OkSuccessful) { // Re-create the inbox folder if it is deleted. Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -295,13 +295,31 @@ StoreFolder storeFolder = LocalStoreData.GetStoreFolder(resolvedFolder); // Ensure the user has rights to list on the parent folder - if (storeFolder == null || !hasFolderPrivilege(authToken.Username, storeFolder, StoreFolderPrivilege.None)) { + if (storeFolder == null || !hasFolderPrivilege(authToken.Username, storeFolder.FolderId, StoreFolderPrivilege.None)) { return null; } // Either have permission or no parent, either way return the folder return storeFolder; } + + /// <summary> + /// Gets the store folder from the given folder Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="folderId">The Id of the folder to lookup.</param> + /// <returns>The store folder or null if the folder name is invalid.</returns> + public StoreFolder GetStoreFolder(IAuthenticationToken authToken, int folderId) { + StoreFolder storeFolder = LocalStoreData.GetStoreFolder(folderId); + + // Ensure the user has rights to list on the parent folder + if (storeFolder == null || !hasFolderPrivilege(authToken.Username, storeFolder.FolderId, StoreFolderPrivilege.None)) { + return null; + } + + // Either have permission or no parent, either way return the folder + return storeFolder; + } #endregion #region Create Folder @@ -322,7 +340,7 @@ if (parent != null) { // Ensure the user has rights to get the message flags - if (hasFolderPrivilege(authToken.Username, parent, StoreFolderPrivilege.CreateFolders)) { + if (hasFolderPrivilege(authToken.Username, parent.FolderId, StoreFolderPrivilege.CreateFolders)) { // Get the user Id int? userId = LocalStoreData.GetUserId(authToken.Username); @@ -367,15 +385,15 @@ /// Deletes an existing folder. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - public LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, StoreFolder folder) { + public LocalStoreFolderResult DeleteFolder(IAuthenticationToken authToken, int folderId) { // Ensure the user has rights to delete the folder - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Delete)) { + if (hasFolderPrivilege(authToken.Username, folderId, StoreFolderPrivilege.Delete)) { // Delete the folder - return LocalStoreData.DeleteFolder(folder); + return LocalStoreData.DeleteFolder(folderId); } else { return LocalStoreFolderResult.NotPermitted; @@ -400,13 +418,13 @@ /// <returns>The result of the rename attempt.</returns> public LocalStoreFolderResult RenameFolder(IAuthenticationToken authToken, StoreFolder folder, string newFolderName) { // Ensure the user has delete privileges on the original folder - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Delete)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Delete)) { Folder newFolder = new Folder(folder.NameSpace, newFolderName); StoreFolder parent = LocalStoreData.GetStoreFolder(newFolder.Parent); // Ensure the user has create privileges on the new parent folder - if (parent != null && hasFolderPrivilege(authToken.Username, parent, StoreFolderPrivilege.CreateFolders)) { + if (parent != null && hasFolderPrivilege(authToken.Username, parent.FolderId, StoreFolderPrivilege.CreateFolders)) { return LocalStoreData.RenameFolder(folder, newFolderName); } else { @@ -472,7 +490,7 @@ public StoreFolder[] GetChildren(IAuthenticationToken authToken, StoreFolder parent) { // Ensure the user has rights to list the folders - if (hasFolderPrivilege(authToken.Username, parent, StoreFolderPrivilege.Lookup)) { + if (hasFolderPrivilege(authToken.Username, parent.FolderId, StoreFolderPrivilege.Lookup)) { // Return the children return LocalStoreData.GetChildren(parent); @@ -536,7 +554,7 @@ public LocalStoreFolderResult Subscribe(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to subscribe to the folder - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Lookup)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup)) { // Subscribe to the folder LocalStoreData.Subscribe(authToken.Username, folder); @@ -573,7 +591,7 @@ public int GetNextMessageId(IAuthenticationToken authToken, int currentId, StoreFolder folder) { // Ensure the user has rights to get the message Id - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message Id return LocalStoreData.GetNextMessageId(currentId, folder); @@ -592,7 +610,7 @@ public int GetNextMessageId(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to get the message Id - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message Id return LocalStoreData.GetNextMessageId(folder); @@ -614,7 +632,7 @@ public int GetMessageId(IAuthenticationToken authToken, int messageOffset, StoreFolder folder) { // Ensure the user has rights to get the message Id - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message Id return LocalStoreData.GetMessageId(messageOffset, folder); @@ -636,7 +654,7 @@ public int GetMessageOffset(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message Id - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message Id return LocalStoreData.GetMessageOffset(messageId, folder); @@ -660,7 +678,7 @@ public StoreMessageFlags? GetMessageFlags(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message flags - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message flags return LocalStoreData.GetMessageFlags(messageId, folder); @@ -686,7 +704,7 @@ if ((changedFlags & StoreMessageFlags.Deleted) == StoreMessageFlags.Deleted) { // Ensure the user has rights to delete a message - if (!hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Delete)) { + if (!hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Delete)) { // No rights, replace with the current deleted flag flags |= StoreMessageFlags.Deleted; flags ^= StoreMessageFlags.Deleted; @@ -697,7 +715,7 @@ if ((changedFlags & StoreMessageFlags.Seen) == StoreMessageFlags.Seen) { // Ensure the user has rights to alter the seen flag - if (!hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.AlterSeenFlag)) { + if (!hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.AlterSeenFlag)) { // No rights, replace with the current seen flag flags |= StoreMessageFlags.Seen; flags ^= StoreMessageFlags.Seen; @@ -708,7 +726,7 @@ if ((changedFlags ^ (StoreMessageFlags.Deleted | StoreMessageFlags.Seen)) != StoreMessageFlags.None) { // Ensure the user has rights to alter the other flags - if (!hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Write)) { + if (!hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Write)) { // No rights, replace with the current flags (excluding \Seen and \Deleted) flags &= (StoreMessageFlags.Deleted | StoreMessageFlags.Seen); currentFlags |= (StoreMessageFlags.Deleted | StoreMessageFlags.Seen); @@ -735,7 +753,7 @@ public DateTime? GetInternalDate(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message date time - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the internal date return LocalStoreData.GetInternalDate(messageId, folder); @@ -757,7 +775,7 @@ public int? GetMessageSize(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message size - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message size return LocalStoreData.GetMessageSize(messageId, folder); @@ -779,7 +797,7 @@ public MessageHeaders GetMessageHeaders(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message headers - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message headers return LocalStoreData.GetMessageHeaders(messageId, folder); @@ -802,7 +820,7 @@ public IMessageBodyPart GetMessageMimePart(IAuthenticationToken authToken, int messageId, StoreFolder folder, int messagePart) { // Ensure the user has rights to get the message - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message part return LocalStoreData.GetMessageMimePart(messageId, folder, messagePart); @@ -824,7 +842,7 @@ public Message GetMessage(IAuthenticationToken authToken, int messageId, StoreFolder folder) { // Ensure the user has rights to get the message - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message return LocalStoreData.GetMessage(messageId, folder); @@ -847,7 +865,7 @@ public int? GetMessageCount(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to get the message count - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Read)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Read)) { // Return the message count return LocalStoreData.GetMessageCount(folder); @@ -868,7 +886,7 @@ public int? GetRecentMessageCount(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to get the message count - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Lookup)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup)) { // Return the count return LocalStoreData.GetRecentMessageCount(folder); @@ -893,7 +911,7 @@ public int[] PurgeDeletedMessages(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to purge the folder - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Delete)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Delete)) { // Purge the folder's deleted messages return LocalStoreData.PurgeDeletedMessages(folder); @@ -1114,7 +1132,7 @@ public void SetStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, StoreFolderAce ace) { // Ensure the user has rights to alter the ACL - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Admin)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin)) { // Set the ACE LocalStoreData.SetStoreFolderAce(folder, ace); } @@ -1123,7 +1141,7 @@ public void RemoveStoreFolderAce(IAuthenticationToken authToken, StoreFolder folder, string identifier) { // Ensure the user has rights to alter the ACL - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Admin)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Admin)) { // Remove the ACE LocalStoreData.RemoveStoreFolderAce(folder, identifier); } @@ -1132,7 +1150,7 @@ public StoreFolderAcl GetStoreFolderAcl(IAuthenticationToken authToken, StoreFolder folder) { // Ensure the user has rights to lookup the ACL - if (hasFolderPrivilege(authToken.Username, folder, StoreFolderPrivilege.Lookup)) { + if (hasFolderPrivilege(authToken.Username, folder.FolderId, StoreFolderPrivilege.Lookup)) { // Return the ACL StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); return currentAcl; @@ -1219,9 +1237,10 @@ #endregion #endregion - private bool hasFolderPrivilege(string username, StoreFolder folder, StoreFolderPrivilege privilege) { + private bool hasFolderPrivilege(string username, int folderId, StoreFolderPrivilege privilege) { // First check if the user has the required privilege on the folder + StoreFolder folder = LocalStoreData.GetStoreFolder(folderId); StoreFolderAcl currentAcl = LocalStoreData.GetStoreFolderAcl(folder); StoreFolderAce userAce = currentAcl[username]; @@ -1245,7 +1264,7 @@ StoreFolder parent = LocalStoreData.GetParentFolder(folder); if (parent != null) { // Recursively check the parent folders for the lookup privilege - return hasFolderPrivilege(username, parent, StoreFolderPrivilege.Lookup); + return hasFolderPrivilege(username, parent.FolderId, StoreFolderPrivilege.Lookup); } // No parent (don't need Lookup priv) and user has the required privilege Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-01 12:15:36 UTC (rev 39) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-02 13:26:56 UTC (rev 40) @@ -271,6 +271,12 @@ return null; } } + + public StoreFolder GetStoreFolder(int folderId) { + using (MySqlConnection cnn = GetConnection()) { + return getStoreFolder(folderId); + } + } #endregion #region Get Parent Folder @@ -340,14 +346,14 @@ /// Deletes an existing folder. /// </summary> /// <param name="authToken">The authentication credentials.</param> - /// <param name="folder">The folder to delete.</param> + /// <param name="folderId">The Id of the folder to delete.</param> /// <returns>The result of the delete attempt.</returns> - public LocalStoreFolderResult DeleteFolder(StoreFolder folder) { + public LocalStoreFolderResult DeleteFolder(int folderId) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "DeleteFolder"; - cmd.Parameters.Add("DeleteFolderId", folder.FolderId); + cmd.Parameters.Add("DeleteFolderId", folderId); cmd.Parameters.Add("Result", MySqlDbType.Int32); cmd.Parameters["Result"].Direction = ParameterDirection.Output; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-06-01 12:16:30
|
Revision: 39 Author: tmyroadctfig Date: 2006-06-01 05:15:36 -0700 (Thu, 01 Jun 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=39&view=rev Log Message: ----------- Work on user administration in administration website. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/Folder.cs NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs NMail/branches/luke-dev/NMail.sln Added Paths: ----------- NMail/branches/luke-dev/NDns/NDns.xml NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx Property Changed: ---------------- NMail/branches/luke-dev/ Property changes on: NMail/branches/luke-dev ___________________________________________________________________ Name: svn:ignore - NMail.suo + NMail.suo NMail.Administration.Web.suo Added: NMail/branches/luke-dev/NDns/NDns.xml =================================================================== --- NMail/branches/luke-dev/NDns/NDns.xml (rev 0) +++ NMail/branches/luke-dev/NDns/NDns.xml 2006-06-01 12:15:36 UTC (rev 39) @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>NDns</name> + </assembly> + <members> + </members> +</doc> Modified: NMail/branches/luke-dev/NMail/DataTypes/Folder.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/Folder.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail/DataTypes/Folder.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -23,6 +23,7 @@ /// <summary> /// Represents a folder in the local store. /// </summary> + [Serializable] public class Folder { #region Constructors /// <summary> Modified: NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail/DataTypes/StoreFolder.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -23,6 +23,7 @@ /// <summary> /// A folder that has been obtained from the local store. /// </summary> + [Serializable] public class StoreFolder : Folder { /// <summary> /// Creates a new store folder. Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -431,6 +431,14 @@ /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> /// <returns>The result of the attempt to remove the user from the mail domain.</returns> LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid or unauthorized.</returns> + StoreFolder[] GetUserFolders(IAuthenticationToken authToken, int userId); #endregion #region Group Management Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -355,6 +355,13 @@ /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId); + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid.</returns> + StoreFolder[] GetUserFolders(int userId); #endregion #region Group Management Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/UserDataSource.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Data; +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; +using NMail.Authentication; +using NMail.DataTypes; + +namespace NMail.Administration.Web +{ + /// <summary> + /// Summary description for UserDataSource + /// </summary> + public static class UserDataSource + { + public static List<LocalStoreUser> GetUsers() + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + LocalStoreUser[] users = localStore.GetUsers(authToken); + + return new List<LocalStoreUser>(users); + } + + public static LocalStoreUser GetUser(int userId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.GetUser(authToken, userId); + } + + public static LocalStoreUserResult DeleteUser(int userId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return localStore.DeleteUser(authToken, userId); + } + + public static List<StoreFolder> GetUserFolders(int userId) + { + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + return new List<StoreFolder>(localStore.GetUserFolders(authToken, userId)); + } + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -13,6 +13,9 @@ { protected void Page_Load(object sender, EventArgs e) { - + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } } } Added: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx 2006-06-01 12:15:36 UTC (rev 39) @@ -0,0 +1,57 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="UserDetails.aspx.cs" Inherits="UserDetails" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <h2>User Details</h2> + <asp:Literal ID="StatusMessage" runat="server" Visible="False"></asp:Literal> + <asp:DetailsView ID="UserDetailsView" runat="server" AutoGenerateRows="False" CellPadding="4" + DataSourceID="UserDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <Fields> + <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> + <asp:BoundField DataField="UserId" HeaderText="User Id" ReadOnly="True" SortExpression="UserId" /> + <asp:BoundField DataField="UserFolderId" HeaderText="User Initial Folder Id" SortExpression="UserFolderId" /> + <asp:BoundField DataField="QuotaWarnLimit" HeaderText="Quota Warn Limit" SortExpression="QuotaWarnLimit" /> + <asp:BoundField DataField="QuotaHardLimit" HeaderText="Quota Hard Limit" SortExpression="QuotaHardLimit" /> + <asp:CommandField ShowDeleteButton="True" /> + </Fields> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="UserDataSource" runat="server" + SelectMethod="GetUser" TypeName="NMail.Administration.Web.UserDataSource" DeleteMethod="DeleteUser" OnDeleting="UserDataSource_Deleting" OnDeleted="UserDataSource_Deleted"> + <SelectParameters> + <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> + </SelectParameters> + <DeleteParameters> + <asp:Parameter Name="userId" Type="Int32" /> + </DeleteParameters> + </asp:ObjectDataSource> + <h2>User's Folders</h2> + <asp:GridView ID="UserFoldersGridView" runat="server" AutoGenerateColumns="False" CellPadding="4" + DataSourceID="UserFolderDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="FolderId" HeaderText="Folder Id" SortExpression="FolderId" /> + <asp:BoundField DataField="FolderName" HeaderText="Folder Name" ReadOnly="True" SortExpression="FolderName" /> + <asp:BoundField DataField="NameSpace" HeaderText="Namespace" ReadOnly="True" SortExpression="NameSpace" /> + <asp:CheckBoxField DataField="HasChildren" HeaderText="Has Children" SortExpression="HasChildren" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> + <asp:ObjectDataSource ID="UserFolderDataSource" runat="server" SelectMethod="GetUserFolders" + TypeName="NMail.Administration.Web.UserDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="userId" QueryStringField="UserId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/UserDetails.aspx.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -0,0 +1,42 @@ +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; + +using NMail; + +public partial class UserDetails : System.Web.UI.Page +{ + protected void UserDataSource_Deleting(object sender, ObjectDataSourceMethodEventArgs e) + { + e.InputParameters["userId"] = Request.QueryString["UserId"]; + } + + protected void UserDataSource_Deleted(object sender, ObjectDataSourceStatusEventArgs e) + { + LocalStoreUserResult result = (LocalStoreUserResult)e.ReturnValue; + + this.StatusMessage.Visible = true; + + switch (result) + { + case LocalStoreUserResult.UserStillHasFolders: + this.StatusMessage.Text = "Could not delete the user because they still own folders."; + break; + } + } + + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewUsers.aspx 2006-06-01 12:15:36 UTC (rev 39) @@ -0,0 +1,36 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %> + +<script runat="server"> + + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } +</script> + +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:GridView ID="GridView1" runat="server" DataSourceID="UserDataSource" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:BoundField DataField="UserId" HeaderText="UserId" SortExpression="UserId" /> + <asp:BoundField DataField="UserFolderId" HeaderText="UserFolderId" SortExpression="UserFolderId" /> + <asp:BoundField DataField="QuotaWarnLimit" HeaderText="QuotaWarnLimit" SortExpression="QuotaWarnLimit" /> + <asp:BoundField DataField="QuotaHardLimit" HeaderText="QuotaHardLimit" SortExpression="QuotaHardLimit" /> + <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> + <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="UserDetails.aspx?UserId={0}" + HeaderText="Edit" Text="edit" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> + <asp:ObjectDataSource ID="UserDataSource" runat="server" SelectMethod="GetUsers" + TypeName="NMail.Administration.Web.UserDataSource"></asp:ObjectDataSource> +</asp:Content> + Modified: NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-06-01 12:15:36 UTC (rev 39) @@ -3,5 +3,6 @@ <siteMapNode url="Default.aspx" title="Home" description=""> <siteMapNode url="Login.aspx" title="Login" description="" /> <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" /> + <siteMapNode url="ViewUsers.aspx" title="Users" description="" /> </siteMapNode> </siteMap> Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -992,6 +992,16 @@ public LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId) { return this.LocalStoreData.RemoveUserFromMailDomain(userId, mailDomainId); } + + /// <summary> + /// Gets a list of folder that belong to the user with the given user Id. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid or unauthorized.</returns> + public StoreFolder[] GetUserFolders(IAuthenticationToken authToken, int userId) { + return this.LocalStoreData.GetUserFolders(userId); + } #endregion #region Group Management Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-06-01 12:15:36 UTC (rev 39) @@ -515,7 +515,24 @@ END // +DROP PROCEDURE IF EXISTS GetUserFolders // +CREATE PROCEDURE GetUserFolders +( + UserId INT +) +BEGIN + SELECT + f.FolderId, f.Name, n.Name AS NameSpace + FROM + Folder f, Namespace n + WHERE + f.NameSpaceId = n.NameSpaceId + AND f.OwnerUserId = UserId; +END +// + + -- ----------------------------------------------------------------------- -- -- Group related stored procedures Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -980,8 +980,8 @@ // Parse out all the returned values string name = (string) cmd.Parameters["Name"].Value; - object quotaHardLimit = (int) cmd.Parameters["QuotaHardLimit"].Value; - object quotaWarnLimit = (int) cmd.Parameters["QuotaWarnLimit"].Value; + object quotaHardLimit = cmd.Parameters["QuotaHardLimit"].Value; + object quotaWarnLimit = cmd.Parameters["QuotaWarnLimit"].Value; int userFolderId = (int) cmd.Parameters["UserFolderId"].Value; int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?) quotaHardLimit; @@ -1015,9 +1015,11 @@ MySqlDataReader reader = cmd.ExecuteReader(); List<int> userIds = new List<int>(); - while (reader.NextResult()) { + while (reader.Read()) { int userId = (int) reader["UserId"]; + userIds.Add(userId); } + reader.Close(); List<LocalStoreUser> users = new List<LocalStoreUser>(); foreach (int userId in userIds) { @@ -1190,6 +1192,35 @@ public LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId) { throw new NotImplementedException(); } + + /// <summary> + /// Gets a list of folders that belong to the user with the given user Id. + /// </summary> + /// <param name="userId">The Id of the user to get the folder for.</param> + /// <returns>The list of folders or null if the user Id is invalid.</returns> + public StoreFolder[] GetUserFolders(int userId) { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetUserFolders"; + cmd.Parameters.Add("UserId", userId); + + List<StoreFolder> folders = new List<StoreFolder>(); + MySqlDataReader reader = cmd.ExecuteReader(); + + while (reader.Read()) { + int folderId = (int) reader["FolderId"]; + string nameSpace = (string) reader["NameSpace"]; + string name = (string) reader["Name"]; + + // TODO: Get HasChildren from the reader + folders.Add(new StoreFolder(nameSpace, name, folderId, false)); + } + + return folders.ToArray(); + } + } + } #endregion #region Group Management Modified: NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs =================================================================== --- NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs 2006-06-01 12:15:36 UTC (rev 39) @@ -60,31 +60,13 @@ // TODO: remove (for testing only) - NMail.LocalStoreData.MySql.MySqlLocalStoreData m = new NMail.LocalStoreData.MySql.MySqlLocalStoreData(); - LocalStoreFolderResult rda = m.CreateFolder(1, null, new NMail.DataTypes.Folder("LocalMail", "AAA")); - NMail.DataTypes.StoreFolder rff = m.GetStoreFolder(new NMail.DataTypes.Folder("LocalMail", "AAA")); - LocalStoreGroupResult r1 = m.CreateGroup("Test123"); - NMail.DataTypes.LocalStoreGroup g12 = m.GetGroup("Test123"); - NMail.DataTypes.LocalStoreGroup g1 = m.GetGroup("aaaAdministrators"); - LocalStoreUserResult r2 = m.CreateUser("Test123", 100, 100); - NMail.DataTypes.LocalStoreUser u = m.GetUser("Test123"); - r2 = m.DeleteUser(u.UserId); - rff = m.GetStoreFolder(new NMail.DataTypes.Folder("LocalMail", "Test123")); - rda = m.DeleteFolder(rff); - rff = m.GetStoreFolder(new NMail.DataTypes.Folder("LocalMail", "Test123.INBOX")); - rda = m.DeleteFolder(rff); - rff = m.GetStoreFolder(new NMail.DataTypes.Folder("LocalMail", "Test123")); - rda = m.DeleteFolder(rff); - //r2 = m.DeleteUser(u.UserId); - LocalStoreGroupResult rr = m.DeleteGroup(g12.GroupId); - rda = m.DeleteFolder(rff); + /*NMail.LocalStoreData.MySql.MySqlLocalStoreData m = new NMail.LocalStoreData.MySql.MySqlLocalStoreData(); + m.AddMailDomain(new NMail.DataTypes.LocalStore.MailDomain(1, new NMail.DataTypes.Host("localhost"))); */ - - // start the server server.Start(); Modified: NMail/branches/luke-dev/NMail.sln =================================================================== --- NMail/branches/luke-dev/NMail.sln 2006-05-30 10:25:50 UTC (rev 38) +++ NMail/branches/luke-dev/NMail.sln 2006-06-01 12:15:36 UTC (rev 39) @@ -40,8 +40,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NMail.Administration.Console", "NMail.Administration.Console\NMail.Administration.Console.csproj", "{93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NMail.Administration.WebLib", "NMail.Administration.WebLib\NMail.Administration.WebLib.csproj", "{614C9689-45BE-4047-8D32-10D266C28E98}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -128,10 +126,6 @@ {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Release|Any CPU.ActiveCfg = Release|Any CPU {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Release|Any CPU.Build.0 = Release|Any CPU - {614C9689-45BE-4047-8D32-10D266C28E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {614C9689-45BE-4047-8D32-10D266C28E98}.Debug|Any CPU.Build.0 = Debug|Any CPU - {614C9689-45BE-4047-8D32-10D266C28E98}.Release|Any CPU.ActiveCfg = Release|Any CPU - {614C9689-45BE-4047-8D32-10D266C28E98}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-05-30 10:26:23
|
Revision: 38 Author: tmyroadctfig Date: 2006-05-30 03:25:50 -0700 (Tue, 30 May 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=38&view=rev Log Message: ----------- Added initial administration website. Modified Paths: -------------- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.Server/NMailServer.cs NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs NMail/branches/luke-dev/NMail.sln Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Web/ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs NMail/branches/luke-dev/NMail.Administration.Web/App_Data/ NMail/branches/luke-dev/NMail.Administration.Web/Bin/ NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx NMail/branches/luke-dev/NMail.Administration.Web/Global.asax NMail/branches/luke-dev/NMail.Administration.Web/Images/ NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo.png NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap NMail/branches/luke-dev/NMail.Administration.Web/web.config NMail/branches/luke-dev/NMail.Administration.Web.sln Added: NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/App_Code/MailDomainDataSource.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,81 @@ +using System; +using System.Data; +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; +using NMail.Authentication; +using NMail.DataTypes; +using NMail.DataTypes.LocalStore; + +namespace NMail.Administration.Web +{ + /// <summary> + /// Summary description for MailDomainDataSource + /// </summary> + public static class MailDomainDataSource + { + public static DataTable GetMailDomains() + { + DataTable result = new DataTable("Mail Domains"); + result.Columns.Add("Id"); + result.Columns.Add("Primary Host"); + + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + MailDomain[] mailDomains = localStore.GetMailDomains(authToken); + + foreach (MailDomain mailDomain in mailDomains) + { + object[] p = { mailDomain.MailDomainId, mailDomain.PrimaryHost }; + result.Rows.Add(p); + } + + return result; + } + + public static DataTable GetMailDomain(int mailDomainId) + { + DataTable result = new DataTable("Mail Domain"); + result.Columns.Add("Id"); + result.Columns.Add("Primary Host"); + + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + MailDomain[] mailDomains = localStore.GetMailDomains(authToken); + + foreach (MailDomain mailDomain in mailDomains) + { + if (mailDomain.MailDomainId == mailDomainId) + { + object[] p = { mailDomain.MailDomainId, mailDomain.PrimaryHost }; + result.Rows.Add(p); + break; + } + } + + return result; + } + + public static void UpdateMailDomain(int mailDomainId, string primaryHost) + { + MailDomain updatedMailDomain = new MailDomain(mailDomainId, new Host(primaryHost)); + + IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); + IAuthenticationToken authToken = (IAuthenticationToken)session["AuthToken"]; + ILocalStore localStore = (ILocalStore)session["LocalStore"]; + + localStore.UpdateMailDomain(authToken, updatedMailDomain); + } + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Default.aspx 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,17 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" Title="Untitled Page" %> + +<script runat="server"> + + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } +</script> + +<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + Where here! +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/Global.asax =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Global.asax (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Global.asax 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,36 @@ +<%@ Application Language="C#" %> + +<script runat="server"> + + void Application_Start(object sender, EventArgs e) + { + } + + 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> Added: NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo.png =================================================================== (Binary files differ) Property changes on: NMail/branches/luke-dev/NMail.Administration.Web/Images/nmail-logo.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,15 @@ +<%@ Page Language="C#" CodeFile="Login.aspx.cs" Inherits="Login" MasterPageFile="~/MasterPage.master" Title="NMail Administration - Login" %> + +<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:LoginView ID="LoginView" runat="server"> + <LoggedInTemplate> + You are currently logged in as + <asp:LoginName ID="LoginName" runat="server" />. + </LoggedInTemplate> + <AnonymousTemplate> + <asp:Login ID="Login" runat="server" OnAuthenticate="Login_Authenticate" DestinationPageUrl="~/Default.aspx" DisplayRememberMe="False"> + </asp:Login> + </AnonymousTemplate> + </asp:LoginView> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Login.aspx.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,37 @@ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Net.Security; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +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.Authentication; +using NMail.IO; +using NMail.Server; + +public partial class Login : System.Web.UI.Page +{ + 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"); + IAuthenticationToken authToken = ra.NMailServer.AuthenticationProvider.Authenticate(login.UserName, login.Password); + + if (authToken != null) + { + e.Authenticated = true; + Session["AuthToken"] = authToken; + Session["LocalStore"] = ra.NMailServer.LocalStore; + } + } +} \ No newline at end of file Added: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,21 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="MailDomainDetails.aspx.cs" Inherits="MailDomainDetails" Title="Untitled Page" %> +<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:DetailsView ID="DetailsView1" runat="server" CellPadding="4" DataSourceID="MailDomainDataSource" + ForeColor="#333333" GridLines="None" Height="50px" Width="125px"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" /> + <EditRowStyle BackColor="#2461BF" /> + <RowStyle BackColor="#EFF3FB" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:DetailsView> + <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomain" + TypeName="NMail.Administration.Web.MailDomainDataSource"> + <SelectParameters> + <asp:QueryStringParameter Name="mailDomainId" QueryStringField="MailDomainId" Type="Int32" /> + </SelectParameters> + </asp:ObjectDataSource> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/MailDomainDetails.aspx.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -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 MailDomainDetails : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/MasterPage.master 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,48 @@ +<%@ Master Language="C#" %> + +<!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> + <link href="StyleSheet.css" rel="stylesheet" type="text/css" /> +</head> +<body> + <form id="form1" runat="server"> + <div> + <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> + <tr> + <td colspan="2" style="vertical-align: middle; width: 100%; border-bottom: darkgray thin solid;"> + <h1><img src="Images/nmail-logo.png" style="vertical-align: middle" /> NMail Web Administration</h1> + </td> + </tr> + <tr> + <td colspan="2" style="border-bottom: darkgray thick solid;"> + <table style="width: 100%"> + <tr> + <td style="width: 100%"><asp:SiteMapPath ID="SiteMapPath" runat="server" /></td> + <td style="text-align: right;"><asp:LoginStatus ID="LoginStatus" runat="server" /></td> + </tr> + </table> + </td> + </tr> + <tr> + <td style="border-right-style: solid; border-right-color: darkgray; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em;"> + <asp:TreeView ID="TreeView" runat="server" DataSourceID="SiteMapDataSource"> + </asp:TreeView> + <asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" /> + </td> + <td style="width: 100%; padding-right: 1em; padding-left: 1em; padding-bottom: 1em; padding-top: 1em;"> + <asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"> + </asp:ContentPlaceHolder> + </td> + </tr> + <tr> + <td colspan="2" style="border-top-style: solid; border-top-color: darkgray;"> + <a href="http://nmailserver.sourceforege.net">NMail homepage.</a></td> + </tr> + </table> + </div> + </form> +</body> +</html> Added: NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/StyleSheet.css 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,4 @@ +body +{ + font-family: Sans-Serif; +} Added: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,24 @@ +<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ViewMailDomains.aspx.cs" Inherits="ViewMailDomains" Title="Untitled Page" %> +<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server"> + <asp:ObjectDataSource ID="MailDomainDataSource" runat="server" SelectMethod="GetMailDomains" TypeName="NMail.Administration.Web.MailDomainDataSource" UpdateMethod="UpdateMailDomain"> + <UpdateParameters> + <asp:Parameter Name="mailDomainId" Type="Int32" /> + <asp:Parameter Name="primaryHost" Type="String" /> + </UpdateParameters> + </asp:ObjectDataSource> + <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" + CellPadding="4" DataSourceID="MailDomainDataSource" ForeColor="#333333" GridLines="None"> + <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <Columns> + <asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="MailDomainDetails.aspx?MailDomainId={0}" + HeaderText="Details" Text="details" /> + </Columns> + <RowStyle BackColor="#EFF3FB" /> + <EditRowStyle BackColor="#2461BF" /> + <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> + <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> + <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> + <AlternatingRowStyle BackColor="White" /> + </asp:GridView> +</asp:Content> + Added: NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/ViewMailDomains.aspx.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,26 @@ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +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; +using NMail.Authentication; +using NMail.DataTypes.LocalStore; + +public partial class ViewMailDomains : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + if (!Request.IsAuthenticated) + { + Response.Redirect("Login.aspx"); + } + } +} Added: NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/Web.sitemap 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" ?> +<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > + <siteMapNode url="Default.aspx" title="Home" description=""> + <siteMapNode url="Login.aspx" title="Login" description="" /> + <siteMapNode url="ViewMailDomains.aspx" title="Mail Domains" description="" /> + </siteMapNode> +</siteMap> Added: NMail/branches/luke-dev/NMail.Administration.Web/web.config =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web/web.config (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web/web.config 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- + Note: As an alternative to hand editing this file you can use the + web admin tool to configure settings for your application. Use + the Website->Asp.Net Configuration option in Visual Studio. + A full list of settings and comments can be found in + machine.config.comments usually located in + \Windows\Microsoft.Net\Framework\v2.x\Config +--> +<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> + <appSettings/> + <connectionStrings/> + <system.web> + <!-- + Set compilation debug="true" to insert debugging + symbols into the compiled page. Because this + affects performance, set this value to true only + during development. + --> + <compilation debug="true"> + <assemblies> + <add assembly="System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies></compilation> + <!-- + The <authentication> section enables configuration + of the security authentication mode used by + ASP.NET to identify an incoming user. + --> + <authentication mode="Forms"> + <forms loginUrl="Login.aspx" + timeout="60" + protection="All" + slidingExpiration="true"/> + </authentication> + <!-- + The <customErrors> section enables configuration + of what to do if/when an unhandled error occurs + during the execution of a request. Specifically, + it enables developers to configure html error pages + to be displayed in place of a error stack trace. + + <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> + <error statusCode="403" redirect="NoAccess.htm" /> + <error statusCode="404" redirect="FileNotFound.htm" /> + </customErrors> + --> + </system.web> + + <!--<system.runtime.remoting> + <application> + <client> + <wellknown + type="NMail.Server.RemoteAdministration, NMail.Server" + url="tcp://localhost:7877/RemoteAdministration.rem" + /> + </client> + </application> + </system.runtime.remoting>--> +</configuration> Added: NMail/branches/luke-dev/NMail.Administration.Web.sln =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Web.sln (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Web.sln 2006-05-30 10:25:50 UTC (rev 38) @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Web Developer Express 2005 +Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "C:\...\NMail.Administration.Web\", "NMail.Administration.Web\", "{C9095A2E-5198-49CA-B198-C6536A9143BD}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.VirtualPath = "/NMail.Administration.Web" + Debug.AspNetCompiler.PhysicalPath = "..\..\..\..\Desktop\NMail-trunk\branches\luke-dev\NMail.Administration.Web\" + Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\NMail.Administration.Web\" + Debug.AspNetCompiler.Updateable = "true" + Debug.AspNetCompiler.ForceOverwrite = "true" + Debug.AspNetCompiler.FixedNames = "false" + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.VirtualPath = "/NMail.Administration.Web" + Release.AspNetCompiler.PhysicalPath = "..\..\..\..\Desktop\NMail-trunk\branches\luke-dev\NMail.Administration.Web\" + Release.AspNetCompiler.TargetPath = "PrecompiledWeb\NMail.Administration.Web\" + Release.AspNetCompiler.Updateable = "true" + Release.AspNetCompiler.ForceOverwrite = "true" + Release.AspNetCompiler.FixedNames = "false" + Release.AspNetCompiler.Debug = "False" + VWDPort = "3245" + DefaultWebSiteLanguage = "Visual C#" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|.NET = Debug|.NET + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C9095A2E-5198-49CA-B198-C6536A9143BD}.Debug|.NET.ActiveCfg = Debug|.NET + {C9095A2E-5198-49CA-B198-C6536A9143BD}.Debug|.NET.Build.0 = Debug|.NET + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-20 15:56:30 UTC (rev 37) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -40,7 +40,7 @@ /// <summary> /// A MySql based local store data provider. /// </summary> - public class MySqlLocalStoreData : ILocalStoreData, IHashAuthProvider, ILocalStoreUserMap { + public class MySqlLocalStoreData : MarshalByRefObject, ILocalStoreData, IHashAuthProvider, ILocalStoreUserMap { private MySqlConnection GetConnection() { MySqlConnection cnn = new MySqlConnection(MySqlLocalStoreDataConfiguration.Current.ConnectionString); cnn.Open(); Modified: NMail/branches/luke-dev/NMail.Server/NMailServer.cs =================================================================== --- NMail/branches/luke-dev/NMail.Server/NMailServer.cs 2006-05-20 15:56:30 UTC (rev 37) +++ NMail/branches/luke-dev/NMail.Server/NMailServer.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -21,6 +21,7 @@ using log4net; +using NMail.Authentication; using NMail.Configuration; using NMail.DataTypes; @@ -308,5 +309,11 @@ return NMailConfiguration.Current.LocalStore; } } + + public IAuthenticationProvider AuthenticationProvider { + get { + return NMailConfiguration.Current.AuthenticationProvider; + } + } } } Modified: NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs =================================================================== --- NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs 2006-05-20 15:56:30 UTC (rev 37) +++ NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs 2006-05-30 10:25:50 UTC (rev 38) @@ -20,11 +20,11 @@ using System.Net.Security; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; +using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Serialization.Formatters; using System.Security.Cryptography.X509Certificates; using NMail.Configuration; -using NMail.IO; namespace NMail.Server { /// <summary> @@ -69,12 +69,12 @@ // Setup the remoting channel IDictionary props = new Hashtable(); props["port"] = "7877"; - props["isServer"] = "yes"; - props["certificate"] = new X509Certificate2("NMail.pfx", ""); - props["authProvider"] = NMailConfiguration.Current.AuthenticationProvider; -#if DEBUG - props["useTls"] = false; -#endif +// props["isServer"] = "yes"; +// props["certificate"] = new X509Certificate2("NMail.pfx", ""); +// props["authProvider"] = NMailConfiguration.Current.AuthenticationProvider; +//#if DEBUG +// props["useTls"] = false; +//#endif channel = new TcpChannel(props, null, provider); ChannelServices.RegisterChannel(channel, false); Modified: NMail/branches/luke-dev/NMail.sln =================================================================== --- NMail/branches/luke-dev/NMail.sln 2006-05-20 15:56:30 UTC (rev 37) +++ NMail/branches/luke-dev/NMail.sln 2006-05-30 10:25:50 UTC (rev 38) @@ -40,6 +40,8 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NMail.Administration.Console", "NMail.Administration.Console\NMail.Administration.Console.csproj", "{93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NMail.Administration.WebLib", "NMail.Administration.WebLib\NMail.Administration.WebLib.csproj", "{614C9689-45BE-4047-8D32-10D266C28E98}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -126,6 +128,10 @@ {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Release|Any CPU.ActiveCfg = Release|Any CPU {93F9B202-EB30-4FF8-B10F-BD45FD3B7E9F}.Release|Any CPU.Build.0 = Release|Any CPU + {614C9689-45BE-4047-8D32-10D266C28E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {614C9689-45BE-4047-8D32-10D266C28E98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {614C9689-45BE-4047-8D32-10D266C28E98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {614C9689-45BE-4047-8D32-10D266C28E98}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-05-20 15:57:19
|
Revision: 37 Author: tmyroadctfig Date: 2006-05-20 08:56:30 -0700 (Sat, 20 May 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=37&view=rev Log Message: ----------- Further work on local store. Added option to turn of TLS in remoting channel. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail/ILocalStoreDeliveryAction.cs NMail/branches/luke-dev/NMail/ILocalStoreRecipientValidator.cs NMail/branches/luke-dev/NMail/IO/TcpChannel.cs NMail/branches/luke-dev/NMail/IO/TcpClientChannel.cs NMail/branches/luke-dev/NMail/IO/TcpClientTransportSink.cs NMail/branches/luke-dev/NMail/IO/TcpClientTransportSinkProvider.cs NMail/branches/luke-dev/NMail/IO/TcpServerChannel.cs NMail/branches/luke-dev/NMail/IO/TcpServerTransportSink.cs NMail/branches/luke-dev/NMail.Administration.Console/Context/LocalStoreContext.cs NMail/branches/luke-dev/NMail.Administration.Console/Context/TopLevelContext.cs NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Copy.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Move.cs NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStore/NMail.LocalStore.csproj NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressDate.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressKeyword.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressSender.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/OnWhiteList.cs NMail/branches/luke-dev/NMail.LocalStore/Validators/OrdbBlackList.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs NMail/branches/luke-dev/NMail.Server/NMail.Server.csproj NMail/branches/luke-dev/NMail.Server/RemoteAdministration.cs NMail/branches/luke-dev/NMail.Server.Console/NMail.Server.Console.csproj NMail/branches/luke-dev/NMail.Server.Console/NMailConsoleServer.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs Removed Paths: ------------- NMail/branches/luke-dev/NMail.LocalStore/Configuration/ Modified: NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/DataTypes/LocalStore/MailDomain.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -20,6 +20,7 @@ using System.Text; using NMail; +using NMail.Authentication; using NMail.DataTypes; namespace NMail.DataTypes.LocalStore { @@ -27,6 +28,7 @@ /// A mail domain maps users and administrators to a set of hosts that the store /// accepts mail for. /// </summary> + [Serializable] public class MailDomain { public MailDomain(int mailDomainId, Host primaryHost) { this.mailDomainId = mailDomainId; @@ -61,76 +63,147 @@ } } - WildcardHost[] additionalHosts; + private List<WildcardHost> additionalHosts = new List<WildcardHost>(); /// <summary> /// Other hosts that this domain accepts mail for. /// </summary> public WildcardHost[] AdditionalHosts { get { - return this.additionalHosts; + return this.additionalHosts.ToArray(); } set { - this.additionalHosts = value; + this.additionalHosts.Clear(); + this.additionalHosts.AddRange(value); } } - private ILocalStoreUserMap[] mailboxMappings; + private List<ILocalStoreUserMap> mailboxMappings = new List<ILocalStoreUserMap>(); /// <summary> /// Gets the mailbox mappings for this domain. /// </summary> public ILocalStoreUserMap[] MailboxMappings { get { - return this.mailboxMappings; + return this.mailboxMappings.ToArray(); } set { - this.mailboxMappings = value; + this.mailboxMappings.Clear(); + this.mailboxMappings.AddRange(value); } } - private ILocalStoreDeliveryAction[] allowedActions; + private List<ILocalStoreDeliveryAction> allowedActions = new List<ILocalStoreDeliveryAction>(); /// <summary> /// The actions that user's of this domain are allowed to use. /// </summary> public ILocalStoreDeliveryAction[] AllowedActions { get { - return this.allowedActions; + return this.allowedActions.ToArray(); } - set { - this.allowedActions = value; - } + set { + this.allowedActions.Clear(); + this.allowedActions.AddRange(value); + } } - private ILocalStoreRecipientValidator[] allowedValidators; + private List<ILocalStoreRecipientValidator> allowedValidators = new List<ILocalStoreRecipientValidator>(); /// <summary> /// The validators that user's of this domain are allowed to use. /// </summary> public ILocalStoreRecipientValidator[] AllowedValidators { get { - return this.allowedValidators; + return this.allowedValidators.ToArray(); } set { - this.allowedValidators = value; + this.allowedValidators.Clear(); + this.allowedValidators.AddRange(value); } } - private ILocalStoreDeliveryAction[] defaultActions; + private List<ILocalStoreDeliveryAction> defaultActions = new List<ILocalStoreDeliveryAction>(); /// <summary> /// The default set of actions to apply to incoming messages. /// </summary> public ILocalStoreDeliveryAction[] DefaultActions { get { - return this.defaultActions; + return this.defaultActions.ToArray(); } set { - this.defaultActions = value; + this.defaultActions.Clear(); + this.defaultActions.AddRange(value); } } // TODO: add in a recipient validator tree here + + + /// <summary> + /// Maps a given mailbox to a user. + /// </summary> + /// <param name="mailbox">The mailbox to lookup.</param> + /// <returns>The username or null.</returns> + public string MapMailboxToUser(string mailbox) { + string result = null; + + // Search for a valid mapping for the mailbox + for (int i = 0; result == null && i < this.mailboxMappings.Count; i++) { + result = this.mailboxMappings[i].MapMailboxToUser(mailbox); + } + + return result; + } + + public ILocalStoreRecipientValidator GetRecipientValidator(string name) { + name = name.Trim().ToLower(); + + foreach (ILocalStoreRecipientValidator validator in this.allowedValidators) { + if (validator.Name.Trim().ToLower() == name) { + return validator; + } + } + + return null; + } + + + public ILocalStoreDeliveryAction GetDeliveryAction(string name) { + name = name.Trim().ToLower(); + + foreach (ILocalStoreDeliveryAction action in this.allowedActions) { + if (action.Name.Trim().ToLower() == name) { + return action; + } + } + + return null; + } + + /// <summary> + /// Processes the incomming message against the list of delivery actions. + /// </summary> + /// <param name="delivery">The delivery in progress.</param> + /// <param name="username">The associated username.</param> + /// <returns>The result of the delivery attempt.</returns> + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username) { + for (int i = 0; i < this.defaultActions.Count; i++) { + string name = this.defaultActions[i].Name; + string data = null; + if (delivery.Recipient != null) { + data = delivery.Recipient.Mailbox.GetDataPairValue(name); + } + + DeliveryResult result = this.defaultActions[i].ProcessDelivery(delivery, username, data); + + if (result.Type != DeliveryResultType.Success) { + return result; + } + } + + return new DeliveryResult(DeliveryResultType.Success, null); + } } } Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -525,13 +525,13 @@ /// <returns>The mail domains.</returns> MailDomain[] GetMailDomains(IAuthenticationToken authToken); - /// <summary> - /// Creates a new mail domain. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="primaryHost">The primary host for the mail domain.</param> - /// <returns>The result of the attempt to create the mail domain.</returns> - LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host primaryHost); + /// <summary> + /// Adds a new mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomain">The mail domain to add.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult AddMailDomain(IAuthenticationToken authToken, MailDomain mailDomain); /// <summary> /// Deletes a mail domain from the local store. @@ -683,21 +683,21 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A mail domain with the same primary host already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching mail domain exists in the local store. /// </summary> - NoSuchMailDomain, + NoSuchMailDomain = 2, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 3 } } Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -71,8 +71,8 @@ /// It is a requirement of the local store that each new folder get an incremented Id number. /// </remarks> /// <param name="newFolder">The folder to create.</param> - /// <returns>The newly created folder details.</returns> - StoreFolder CreateFolder(string userName, StoreFolder parent, Folder newFolder); + /// <returns>The result of the attempt to create the folder.</returns> + LocalStoreFolderResult CreateFolder(int userId, StoreFolder parent, Folder newFolder); /// <summary> /// Deletes an existing folder. @@ -441,11 +441,11 @@ MailDomain[] GetMailDomains(); /// <summary> - /// Creates a new mail domain. + /// Adds a new mail domain. /// </summary> - /// <param name="primaryHost">The primary host for the mail domain.</param> - /// <returns>The result of the attempt to create the mail domain.</returns> - LocalStoreMailDomainResult CreateMailDomain(Host primaryHost); + /// <param name="mailDomain">The mail domain to add.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + LocalStoreMailDomainResult AddMailDomain(MailDomain mailDomain); /// <summary> /// Deletes a mail domain from the local store. Modified: NMail/branches/luke-dev/NMail/ILocalStoreDeliveryAction.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreDeliveryAction.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/ILocalStoreDeliveryAction.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -26,12 +26,11 @@ /// An action that can occur during delivery into the local store. /// </summary> public interface ILocalStoreDeliveryAction { - /// <summary> - /// Sets up the instance of the action using the configuration in the XML node. - /// </summary> - /// <remarks>This will only be called if the validator is part of the default validator.</remarks> - /// <param name="node">The configuration node.</param> - void Create(XmlNode node); + /// <summary> + /// The name of the delivery action. E.g. "move" or "copy". + /// </summary> + /// <remarks>This is the key used to lookup data in the mailbox part of an address.</remarks> + string Name { get; } /// <summary> /// Passes the local store delivery data through this action. Modified: NMail/branches/luke-dev/NMail/ILocalStoreRecipientValidator.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreRecipientValidator.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/ILocalStoreRecipientValidator.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -26,12 +26,11 @@ /// A validation that can be performed on a recipient before accepting delivery. /// </summary> public interface ILocalStoreRecipientValidator { - /// <summary> - /// Sets up the instance of the validator using the configuration in the XML node. - /// </summary> - /// <remarks>This will only be called if the validator is part of the default validator.</remarks> - /// <param name="node">The configuration node.</param> - void Create(XmlNode node); + /// <summary> + /// The name of the validator. E.g. "date" or "sender". + /// </summary> + /// <remarks>This is the key used to lookup data in the mailbox part of an address.</remarks> + string Name { get; } /// <summary> /// Checks if the given recipient will be accepted for delivery. Modified: NMail/branches/luke-dev/NMail/IO/TcpChannel.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpChannel.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpChannel.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -39,6 +39,12 @@ private TcpServerChannel serverChannel; public TcpChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider) { + // Parse common properties + bool useTls = true; + if (properties.Contains("useTls")) { + useTls = (bool) properties["useTls"]; + } + // Create the client sink provider if needed if (clientSinkProvider == null) { clientSinkProvider = new BinaryClientFormatterSinkProvider(); @@ -52,7 +58,8 @@ this.clientChannel = new TcpClientChannel(clientSinkProvider, getAuthDetailsCallback, certValidationCallback, - authCompleteCallback); + authCompleteCallback, + useTls); if (properties["isServer"] != null && ((string) properties["isServer"]) == "yes") { // Create the server sink provider if needed @@ -68,7 +75,8 @@ this.serverChannel = new TcpServerChannel(port, certificate, authProvider, - serverSinkProvider); + serverSinkProvider, + useTls); } } Modified: NMail/branches/luke-dev/NMail/IO/TcpClientChannel.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpClientChannel.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpClientChannel.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -48,21 +48,11 @@ /// Creates a new client channel with the given provider. /// </summary> /// <param name="clientSinkProvider">The provider to use.</param> - public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, ChannelAuthComplete authCompleteCallback) { - this.clientSinkProvider = clientSinkProvider; - - this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, null, authCompleteCallback); - } - - /// <summary> - /// Creates a new client channel with the given provider. - /// </summary> - /// <param name="clientSinkProvider">The provider to use.</param> /// <param name="certValidationCallback">The certificate to use to validate the remote server's certificate.</param> - public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientChannel(IClientChannelSinkProvider clientSinkProvider, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.clientSinkProvider = clientSinkProvider; - this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, certValidationCallback, authCompleteCallback); + this.transportSinkProvider = new TcpClientTransportSinkProvider(getAuthDetailsCallback, certValidationCallback, authCompleteCallback, useTls); if (this.clientSinkProvider == null) { this.clientSinkProvider = new BinaryClientFormatterSinkProvider(); Modified: NMail/branches/luke-dev/NMail/IO/TcpClientTransportSink.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpClientTransportSink.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpClientTransportSink.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -62,16 +62,19 @@ ChannelAuthComplete authCompleteCallback; + private bool useTls; + /// <summary> /// Creates a new sink with the given url. /// </summary> /// <param name="url">The URL to connect to.</param> /// <param name="remoteChannelData">Channel data optionally containing the URL.</param> /// <param name="certValidationCallback">The callback to use to validate the remote certificate.</param> - public TcpClientTransportSink(string url, object remoteChannelData, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientTransportSink(string url, object remoteChannelData, GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.getAuthDetailsCallback = getAuthDetailsCallback; this.certValidationCallback = certValidationCallback; this.authCompleteCallback = authCompleteCallback; + this.useTls = useTls; if (TcpChannel.ValidUrl(url)) { string objectURI; @@ -225,33 +228,39 @@ if (response.Trim().ToLower() == "nmail remoting channel") { this.connection.WriteLine("OK"); - // Go encrypted... - if (this.certValidationCallback == null) { - this.connection.StartTlsAsClient(this.host.ToString()); - } else { - this.connection.StartTlsAsClient(this.host.ToString(), this.certValidationCallback); - } + if (this.useTls) + { + // Go encrypted... + if (this.certValidationCallback == null) + { + this.connection.StartTlsAsClient(this.host.ToString()); + } + else + { + this.connection.StartTlsAsClient(this.host.ToString(), this.certValidationCallback); + } - if (this.connection.Encrypted) { - while (this.connection.Connected && this.authToken == null) { - // Get the auth details - TcpUserPasswordPair authDetails = this.getAuthDetailsCallback(this); - - // Send them to the server - this.connection.Write(authDetails); - this.authToken = (IAuthenticationToken) this.connection.Read(); - } + if (!this.connection.Encrypted) + { + throw new InvalidOperationException("Failed to establish a secure connection to the server."); + } + } - if (this.authToken == null) { - throw new InvalidOperationException("Failed to authenticated to the server."); - } + while (this.connection.Connected && this.authToken == null) { + // Get the auth details + TcpUserPasswordPair authDetails = this.getAuthDetailsCallback(this); + + // Send them to the server + this.connection.Write(authDetails); + this.authToken = (IAuthenticationToken) this.connection.Read(); + } - // Notify the caller that the auth token has arrived - this.authCompleteCallback(authToken); + if (this.authToken == null) { + throw new InvalidOperationException("Failed to authenticated to the server."); + } - } else { - throw new InvalidOperationException("Failed to establish a secure connection to the server."); - } + // Notify the caller that the auth token has arrived + this.authCompleteCallback(authToken); } } } Modified: NMail/branches/luke-dev/NMail/IO/TcpClientTransportSinkProvider.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpClientTransportSinkProvider.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpClientTransportSinkProvider.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -44,14 +44,17 @@ private ChannelAuthComplete authCompleteCallback; + private bool useTls; + /// <summary> /// Creates a new provider with the given certificate validation callback. /// </summary> /// <param name="certValidationCallback">The callback to use to validation teh remote server's certificate null for the default.</param> - public TcpClientTransportSinkProvider(GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback) { + public TcpClientTransportSinkProvider(GetAuthDetailsDelegate getAuthDetailsCallback, RemoteCertificateValidationCallback certValidationCallback, ChannelAuthComplete authCompleteCallback, bool useTls) { this.getAuthDetailsCallback = getAuthDetailsCallback; this.certValidationCallback = certValidationCallback; this.authCompleteCallback = authCompleteCallback; + this.useTls = useTls; } #region IClientChannelSinkProvider Members @@ -91,7 +94,7 @@ // Create a transport if needed if (!sinkMap.ContainsKey(key)) { - this.sinkMap.Add(key, new TcpClientTransportSink(url, remoteChannelData, this.getAuthDetailsCallback, this.certValidationCallback, this.authCompleteCallback)); + this.sinkMap.Add(key, new TcpClientTransportSink(url, remoteChannelData, this.getAuthDetailsCallback, this.certValidationCallback, this.authCompleteCallback, this.useTls)); } return this.sinkMap[key]; Modified: NMail/branches/luke-dev/NMail/IO/TcpServerChannel.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpServerChannel.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpServerChannel.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -68,16 +68,19 @@ /// </summary> private IServerChannelSink nextSink; + private bool useTls; + /// <summary> /// Creates a new server channel with the given details. /// </summary> /// <param name="port">The port to listen on.</param> /// <param name="certificate">The certificate to use for SSL.</param> /// <param name="serverSinkProvider">The provider.</param> - public TcpServerChannel(int port, X509Certificate2 certificate, IAuthenticationProvider authProvider, IServerChannelSinkProvider serverSinkProvider) { + public TcpServerChannel(int port, X509Certificate2 certificate, IAuthenticationProvider authProvider, IServerChannelSinkProvider serverSinkProvider, bool useTls) { this.port = port; this.certificate = certificate; this.authProvider = authProvider; + this.useTls = useTls; // This is needed to report a valid IP to clients asking for channel data IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); @@ -238,7 +241,7 @@ while (true) { Socket client = socket.AcceptSocket(); - new TcpServerTransportSink(this.nextSink, this.certificate, this.authProvider, client); + new TcpServerTransportSink(this.nextSink, this.certificate, this.authProvider, client, this.useTls); } } catch (SocketException e) { // Ignore interrupted exception during shutdown Modified: NMail/branches/luke-dev/NMail/IO/TcpServerTransportSink.cs =================================================================== --- NMail/branches/luke-dev/NMail/IO/TcpServerTransportSink.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail/IO/TcpServerTransportSink.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -54,17 +54,20 @@ protected IAuthenticationProvider authProvider; + private bool useTls; + /// <summary> /// Creates a new transport sink with the given details. /// </summary> /// <param name="nextSink">The next sink in the chain.</param> /// <param name="certificate">The certificate to use in SSL.</param> /// <param name="client">The socket to the remote client.</param> - public TcpServerTransportSink(IServerChannelSink nextSink, X509Certificate2 certificate, IAuthenticationProvider authProvider, Socket client) { + public TcpServerTransportSink(IServerChannelSink nextSink, X509Certificate2 certificate, IAuthenticationProvider authProvider, Socket client, bool useTls) { this.nextSink = nextSink; this.connection.Create(client); this.connection.Certificate = certificate; this.authProvider = authProvider; + this.useTls = useTls; // Create a new thread to read requests with ThreadHelper th = new ThreadHelper(new WaitCallback(processConnection), null); @@ -90,8 +93,11 @@ this.connection.Close(); } - // Go encrypted... - this.connection.StartTlsAsServer(); + if (this.useTls) + { + // Go encrypted... + this.connection.StartTlsAsServer(); + } int authAttempts = 0; bool authenticated = false; Added: NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Console/Command/AddMailDomainCommand.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -0,0 +1,98 @@ +/* + * 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 NMail; +using NMail.Authentication; +using NMail.DataTypes; +using NMail.DataTypes.LocalStore; + +namespace NMail.Administration.Console.Command { + class AddMailDomainCommand : IConsoleCommand { + + private ILocalStore localStore; + + private IAuthenticationToken authToken; + + internal AddMailDomainCommand(ILocalStore localStore, IAuthenticationToken authToken) { + this.localStore = localStore; + this.authToken = authToken; + } + + #region IConsoleCommand Members + + public string Description { + get { return "Adds a new mail domain to the local store."; } + } + + public string[] Usage { + get { + List<string> usage = new List<string>(); + + usage.Add("addmaildomain PrimaryHost"); + + return usage.ToArray(); + } + } + + public string Remarks { + get { + return null; + } + } + + public ConsoleExample[] Examples { + get { + List<ConsoleExample> examples = new List<ConsoleExample>(); + + examples.Add(new ConsoleExample("addmaildomain localhost.local", "Add a new mail domain for the domain \"localhost.local\".")); + + return examples.ToArray(); + } + } + + public void Process(string[] commandTokens) { + if (commandTokens.Length == 0) { + System.Console.WriteLine("A primary host is required."); + return; + } + + Host host = new Host(commandTokens[0]); + + if (commandTokens.Length > 1) { + System.Console.WriteLine("Invalid arguments."); + return; + } + + MailDomain mailDomain = new MailDomain(-1, host); + + LocalStoreMailDomainResult result = this.localStore.AddMailDomain(this.authToken, mailDomain); + + if (result == LocalStoreMailDomainResult.OkSuccessful) { + System.Console.WriteLine("Added new mail domain."); + } else { + System.Console.WriteLine("Error adding mail domain."); + } + System.Console.WriteLine(); + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Console/Context/LocalStoreContext.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Context/LocalStoreContext.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.Administration.Console/Context/LocalStoreContext.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -34,7 +34,8 @@ this.commands.Add("listmaildomains", new ListMailDomainsCommand(this.localStore, authToken)); this.commands.Add("listaddresses", new ListUsersAddressesCommand(this.localStore)); this.commands.Add("adduser", new AddUserCommand(this.localStore, authToken)); - this.commands.Add("deleteuser", new DeleteUserCommand(this.localStore)); + this.commands.Add("deleteuser", new DeleteUserCommand(this.localStore)); + this.commands.Add("addmaildomain", new AddMailDomainCommand(this.localStore, authToken)); } private ILocalStore localStore; Modified: NMail/branches/luke-dev/NMail.Administration.Console/Context/TopLevelContext.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Context/TopLevelContext.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.Administration.Console/Context/TopLevelContext.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -44,8 +44,14 @@ IDictionary props = new Hashtable(); props["port"] = "7877"; props["certificateValidation"] = new RemoteCertificateValidationCallback(remoteCertificateValidation); - //TcpChannel channel = new TcpChannel(props, null, null); - TcpClientChannel channel = new TcpClientChannel(null, new GetAuthDetailsDelegate(GetAuthDetails), new RemoteCertificateValidationCallback(remoteCertificateValidation), new ChannelAuthComplete(AuthCompleteCallback)); + + bool useTls = true; + +#if DEBUG + useTls = false; +#endif + + TcpClientChannel channel = new TcpClientChannel(null, new GetAuthDetailsDelegate(GetAuthDetails), new RemoteCertificateValidationCallback(remoteCertificateValidation), new ChannelAuthComplete(AuthCompleteCallback), useTls); ChannelServices.RegisterChannel(channel, false); string url = "nmtcp://127.0.0.1:7877/RemoteAdministration.rem"; Modified: NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj 2006-05-20 15:56:30 UTC (rev 37) @@ -23,7 +23,7 @@ <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> + <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -36,6 +36,7 @@ <ItemGroup> <Compile Include="Command\AddUserCommand.cs" /> <Compile Include="Command\AddUserToMailDomainCommand.cs" /> + <Compile Include="Command\AddMailDomainCommand.cs" /> <Compile Include="Command\RemoveUserFromMailDomainCommand.cs" /> <Compile Include="Command\ListFoldersCommand.cs" /> <Compile Include="Command\DeleteUserCommand.cs" /> Modified: NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ClamAvScanner.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -29,8 +29,17 @@ /// </summary> public class ClamAvScanner : ILocalStoreDeliveryAction { - public void Create(XmlNode node) {} + string name = "antivirus"; + public string Name { + get { + return this.name; + } + set { + this.name = value; + } + } + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username, string additionalData) { try { bool passed = false; Modified: NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Copy.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Copy.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Copy.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -21,7 +21,6 @@ using NMail; using NMail.Authentication; using NMail.DataTypes; -using NMail.LocalStore.Configuration; namespace NMail.LocalStore.DeliveryActions { /// <summary> @@ -31,10 +30,17 @@ string targetFolder; - public void Create(XmlNode node) { - this.targetFolder = node.SelectSingleNode("@folder").Value; - } + string name = "cp"; + public string Name { + get { + return this.name; + } + set { + this.name = value; + } + } + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username, string additionalData) { try { if (this.targetFolder == null) { Modified: NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -25,12 +25,20 @@ using NMail.Authentication; using NMail.Configuration; using NMail.DataTypes; -using NMail.LocalStore.Configuration; namespace NMail.LocalStore.DeliveryActions { public class ManageWhiteList : ILocalStoreDeliveryAction { - public void Create(System.Xml.XmlNode node) { } + string name = "wl"; + public string Name { + get { + return this.name; + } + set { + this.name = value; + } + } + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username, string additionalData) { if (delivery.Sender == null) { // A null sender indicates that the message has been added directly by the user @@ -103,15 +111,16 @@ } public bool withinLocalStore(EmailAddress sender) { - AcceptCaseCollection acceptCases = LocalStoreConfiguration.Current.AcceptCases; + //AcceptCaseCollection acceptCases = LocalStoreConfiguration.Current.AcceptCases; - for (int i = 0; i < acceptCases.Count; i++) { - if (acceptCases[i].Matches(sender.Host)) { - return true; - } - } + //for (int i = 0; i < acceptCases.Count; i++) { + // if (acceptCases[i].Matches(sender.Host)) { + // return true; + // } + //} - return false; + //return false; + throw new NotImplementedException(); } } Modified: NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Move.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Move.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/DeliveryActions/Move.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -21,7 +21,6 @@ using NMail; using NMail.Authentication; using NMail.DataTypes; -using NMail.LocalStore.Configuration; namespace NMail.LocalStore.DeliveryActions { /// <summary> @@ -31,10 +30,17 @@ string targetFolder; - public void Create(XmlNode node) { - this.targetFolder = node.SelectSingleNode("@folder").Value; - } + string name = "mv"; + public string Name { + get { + return this.name; + } + set { + this.name = value; + } + } + public DeliveryResult ProcessDelivery(LocalStoreDelivery delivery, IAuthenticationToken username, string additionalData) { try { if (this.targetFolder == null) { Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -26,7 +26,6 @@ using NMail.DataTypes.ACLs; using NMail.DataTypes.LocalStore; using NMail.Configuration; -using NMail.LocalStore.Configuration; using NMail.LocalStore.DeliveryActions; using NMail.LocalStore.Validators; @@ -50,13 +49,13 @@ string rawMailbox = recipient.Mailbox.MailboxName; // Check if this local store will accept devliery for this recipient - AcceptCase ac = ResolveAccept(recipient.Host); - if (ac == null) { + MailDomain mailDomain = ResolveMailDomain(recipient.Host); + if (mailDomain == null) { return new DeliveryResult(DeliveryResultType.PermanentError, "Local Store does not accept this address."); } // Get the username for this mailbox. E.g. "John.Smith" -> "jsmith" - string username = ac.MapMailboxToUser(rawMailbox); + string username = mailDomain.MapMailboxToUser(rawMailbox); StoreFolder folder = null; // Ensure the user's folder exists @@ -72,20 +71,21 @@ // Pass through the default chain DeliveryResult result; + // TODO: sort out the configuration for the validator tree! - RecipientValidatorElement validationChain = null; //LocalStoreConfiguration.Current.ValidationChain; - if (validationChain != null) { - result = validationChain.ValidateRecipient(recipient, authToken); - } else { + //RecipientValidatorElement validationChain = null; //LocalStoreConfiguration.Current.ValidationChain; + //if (validationChain != null) { + // result = validationChain.ValidateRecipient(recipient, authToken); + //} else { result = new DeliveryResult(DeliveryResultType.Success, null); - } + //} if (result.Type == DeliveryResultType.Success) { // Pass through each allowed user validator IDictionaryEnumerator e = recipient.Mailbox.GetDataPairNames(); while (e.MoveNext() && result.Type == DeliveryResultType.Success) { - ILocalStoreRecipientValidator validator = ac.GetRecipientValidator((string) e.Key); + ILocalStoreRecipientValidator validator = mailDomain.GetRecipientValidator((string) e.Key); if (validator != null) { // Pass through the user chain @@ -103,7 +103,7 @@ /// <param name="host">The host to check.</param> /// <returns>True if the store accepts delivery.</returns> public bool WithinLocalStore(Host host) { - return (ResolveAccept(host) != null); + return (ResolveMailDomain(host) != null); } #endregion @@ -118,8 +118,8 @@ string rawMailbox = recipient.Mailbox.MailboxName; // Check if this local store will accept devliery for this recipient - AcceptCase ac = ResolveAccept(recipient.Host); - if (ac == null) { + MailDomain mailDomain = ResolveMailDomain(recipient.Host); + if (mailDomain == null) { return new RecipientDeliveryResult( recipient, DeliveryResultType.PermanentError, @@ -127,7 +127,7 @@ } // Get the username for this mailbox. E.g. "John.Smith" -> "jsmith" - string username = ac.MapMailboxToUser(rawMailbox); + string username = mailDomain.MapMailboxToUser(rawMailbox); if (username == null) { return new RecipientDeliveryResult( recipient, @@ -158,15 +158,14 @@ LocalStoreDelivery lsd = new LocalStoreDelivery(recipient, inboxFolder); // Pass through the default chain - DeliveryActionList deliveryChain = LocalStoreConfiguration.Current.DeliveryChain; - DeliveryResult result = deliveryChain.ProcessDelivery(lsd, authToken); + DeliveryResult result = mailDomain.ProcessDelivery(lsd, authToken); if (result.Type == DeliveryResultType.Success) { // Pass through each allowed user action IDictionaryEnumerator e = recipient.Mailbox.GetDataPairNames(); while (e.MoveNext() && result.Type == DeliveryResultType.Success) { - ILocalStoreDeliveryAction action = ac.GetDeliveryAction((string)e.Key); + ILocalStoreDeliveryAction action = mailDomain.GetDeliveryAction((string)e.Key); if (action != null) { // Pass through the user chain @@ -203,42 +202,56 @@ LocalStoreDelivery lsd = new LocalStoreDelivery((Message) null, folder); - // Pass through the default chain - DeliveryActionList deliveryChain = LocalStoreConfiguration.Current.DeliveryChain; - DeliveryResult result = deliveryChain.ProcessDelivery(lsd, authToken); - - // TODO: check the localstoredelivery and ensure the user has the POST - // privilege on every folder that will be delivered to + // Need to get a mail domain for the user here... + throw new NotImplementedException(); - if (result.Type == DeliveryResultType.Success) { - try { - // Save the message to the store data - LocalStoreData.DeliverMessage(message, folder); - } catch (Exception) { - result.Type = DeliveryResultType.TemporaryError; - result.Message = "Internal error while delivering message."; - } - } + //// Pass through the default chain + //DeliveryActionList deliveryChain = LocalStoreConfiguration.Current.DeliveryChain; + //DeliveryResult result = deliveryChain.ProcessDelivery(lsd, authToken); + + //// TODO: check the localstoredelivery and ensure the user has the POST + //// privilege on every folder that will be delivered to - return result; + //if (result.Type == DeliveryResultType.Success) { + // try { + // // Save the message to the store data + // LocalStoreData.DeliverMessage(message, folder); + // } catch (Exception) { + // result.Type = DeliveryResultType.TemporaryError; + // result.Message = "Internal error while delivering message."; + // } + //} + + //return result; } #endregion - /// <summary> - /// Determines the accept case that matches the given host, if any. - /// </summary> - /// <param name="host">The host to accept delivery for.</param> - /// <returns>The accept case or null if non exists.</returns> - private AcceptCase ResolveAccept(Host host) { - // Matches the given host to an accept case - foreach(AcceptCase acc in LocalStoreConfiguration.Current.AcceptCases) { - if (acc.Matches(host)) { - return acc; - } - } + private MailDomain ResolveMailDomain(Host host) { + MailDomain[] mailDomains = this.LocalStoreData.GetMailDomains(); - return null; - } + // First check primary hosts + foreach (MailDomain mailDomain in mailDomains) { + if (mailDomain.PrimaryHost == host) { + return mailDomain; + } + } + + // No match, check secondary hosts + foreach (MailDomain mailDomain in mailDomains) { + if (mailDomain.AdditionalHosts == null) { + continue; + } + + foreach (WildcardHost wildCardHost in mailDomain.AdditionalHosts) { + if (wildCardHost.MatchesHost(host)) { + return mailDomain; + } + } + } + + // Nothing matches + return null; + } #endregion #region Folder Retrieval and Manipulation @@ -311,8 +324,20 @@ // Ensure the user has rights to get the message flags if (hasFolderPrivilege(authToken.Username, parent, StoreFolderPrivilege.CreateFolders)) { + // Get the user Id + int? userId = LocalStoreData.GetUserId(authToken.Username); + if (!userId.HasValue) { + throw new InvalidOperationException("Can't get a user Id for the current user."); + } + // Create the mailbox - StoreFolder createdFolder = LocalStoreData.CreateFolder(authToken.Username, parent, resolvedFolder); + LocalStoreFolderResult result = LocalStoreData.CreateFolder(userId.Value, parent, resolvedFolder); + if (result != LocalStoreFolderResult.OkSuccessful) { + return result; + } + + // Get the folder + StoreFolder createdFolder = LocalStoreData.GetStoreFolder(resolvedFolder); // Create an ACL for the folder StoreFolderAce ace = new StoreFolderAce(authToken.Username, StoreFolderPrivilegeHelper.AllPrivileges, AcePrivilegeType.Allow); @@ -1120,17 +1145,17 @@ return this.LocalStoreData.GetMailDomains(); } - /// <summary> - /// Creates a new mail domain. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="primaryHost">The primary host for the mail domain.</param> - /// <returns>The result of the attempt to create the mail domain.</returns> - public LocalStoreMailDomainResult CreateMailDomain(IAuthenticationToken authToken, Host primaryHost) { + /// <summary> + /// Adds a new mail domain. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="mailDomain">The mail domain to add.</param> + /// <returns>The result of the attempt to add the mail domain.</returns> + public LocalStoreMailDomainResult AddMailDomain(IAuthenticationToken authToken, MailDomain mailDomain) { + // TODO: check ACLs - // TODO: check acls - return this.LocalStoreData.CreateMailDomain(primaryHost); - } + return this.LocalStoreData.AddMailDomain(mailDomain); + } /// <summary> /// Deletes a mail domain from the local store. Modified: NMail/branches/luke-dev/NMail.LocalStore/NMail.LocalStore.csproj =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/NMail.LocalStore.csproj 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/NMail.LocalStore.csproj 2006-05-20 15:56:30 UTC (rev 37) @@ -94,12 +94,6 @@ <Compile Include="AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> - <Compile Include="Configuration\AcceptCase.cs" /> - <Compile Include="Configuration\DelieryActionList.cs" /> - <Compile Include="Configuration\LocalStoreConfiguration.cs"> - <SubType>Code</SubType> - </Compile> - <Compile Include="Configuration\RecipientValidatorTree.cs" /> <Compile Include="DeliveryActions\ClamAvScanner.cs" /> <Compile Include="DeliveryActions\Copy.cs"> <SubType>Code</SubType> Modified: NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressDate.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressDate.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressDate.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -32,7 +32,11 @@ /// </summary> public class AddressDate : ILocalStoreRecipientValidator { - public void Create(XmlNode node) {} + public string Name { + get { + return "date"; + } + } public DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient, IAuthenticationToken username, string additionalData) { try { Modified: NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressKeyword.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressKeyword.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressKeyword.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -32,7 +32,11 @@ /// </summary> public class AddressKeyword : ILocalStoreRecipientValidator { - public void Create(XmlNode node) {} + public string Name { + get { + return "keyword"; + } + } public DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient, IAuthenticationToken username, string additionalData) { try { Modified: NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressSender.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressSender.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/Validators/AddressSender.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -32,7 +32,11 @@ /// </summary> public class AddressSender : ILocalStoreRecipientValidator { - public void Create(XmlNode node) {} + public string Name { + get { + return "sender"; + } + } public DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient, IAuthenticationToken username, string additionalData) { try { Modified: NMail/branches/luke-dev/NMail.LocalStore/Validators/OnWhiteList.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/Validators/OnWhiteList.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/Validators/OnWhiteList.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -27,7 +27,11 @@ namespace NMail.LocalStore.Validators { public class OnWhiteList : ILocalStoreRecipientValidator { - public void Create(System.Xml.XmlNode node) { } + public string Name { + get { + return "wl"; + } + } public DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient, IAuthenticationToken username, string additionalData) { // Get the user's whitelist Modified: NMail/branches/luke-dev/NMail.LocalStore/Validators/OrdbBlackList.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/Validators/OrdbBlackList.cs 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStore/Validators/OrdbBlackList.cs 2006-05-20 15:56:30 UTC (rev 37) @@ -29,8 +29,13 @@ /// A chain that checks the sender against the ORDB blacklist. /// </summary> public class OrdbBlackList : ILocalStoreRecipientValidator { - public void Create(XmlNode node) {} + public string Name { + get { + return "ordb"; + } + } + public DeliveryResult ValidateRecipient(SmtpMessageRecipient recipient, IAuthenticationToken username, string additionalData) { IPAddress source = recipient.Message.SourceAddress; byte[] sourceBytes = source.GetAddressBytes(); Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-20 07:15:35 UTC (rev 36) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-20 15:56:30 UTC (rev 37) @@ -214,7 +214,8 @@ START TRANSACTION; /* Check if the parameters are valid. */ - IF EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = ParentId) THEN + IF ParentId IS NULL OR + EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = ParentId) THEN /* Check for duplicate folders. */ IF NOT EXISTS (SELECT f.FolderId FROM Folder f WHERE f.Name LIKE Name) THEN @@ -239,7 +240,40 @@ END // +DROP PROCEDURE IF EXISTS DeleteFolder // +CREATE PROCEDURE DeleteFolder +( + DeleteFolderId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + /* Check if the folder Id is valid. */ + IF EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = DeleteFolderId) THEN + + /* Check if the folder still has sub-folders. */ + IF NOT EXISTS (SELECT * FROM Folder f WHERE f.ParentFolderId = DeleteFolderId) THEN + + DELETE FROM Folder WHERE FolderId = DeleteFolderId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* User still has sub-folders. */ + SELECT 2 INTO Result; + END IF; + ELSE + /* No such folder. */ + SELECT 3 INTO Result; + END IF; + + COMMIT; +END +// + + -- ----------------------------------------------------------------------- -- -- User related stored procedures @@ -259,7 +293,7 @@ BEGIN START TRANSACTION; - IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.Name LIKE Name) THEN + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.Username LIKE Name) THEN SELECT u.UserId, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId @@ -268,7 +302,7 @@ FROM `User` u WHERE - u.Name LIKE Name; + u.Username LIKE Name; /* Ok successful. */ SELECT 0 INTO Result; @@ -298,7 +332,7 @@ IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN SELECT - u.Name, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId + u.Username, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId INTO Name, QuotaHardLimit, QuotaWarnLimit, UserFolderId FROM @@ -349,7 +383,7 @@ START TRANSACTION; /* Check if the name is valid. */ - IF NOT EXISTS (SELECT u.UserId FROM User u WHERE u.Name LIKE Name) THEN + IF NOT EXISTS (SELECT u.UserId FROM `User` u WHERE u.Username LIKE Name) THEN SET InboxName = CONCAT_WS(".", Name, "INBOX"); @@ -357,7 +391,7 @@ IF NOT EXISTS (SELECT * FROM Folder f WHERE f.Name LIKE Name and f.NamespaceId = NamespaceId) AND NOT EXISTS (SELECT * FROM Folder f WHERE f.Name LIKE InboxName and f.NamespaceId = NamespaceId) THEN - INSERT INTO User (Name, QuotaHardLimit, QuotaWarnLimit) VALUES (Name, QuotaHardLimit, QuotaWarnLimit); + INSERT INTO User (Username, QuotaHardLimit, QuotaWarnLimit) VALUES (Name, QuotaHardLimit, QuotaWarnLimit); SELECT LAST_INSERT_ID() INTO UserId; /* Create the user's base folder. */ @@ -406,19 +440,19 @@ DROP PROCEDURE IF EXISTS DeleteUser // CREATE PROCEDURE DeleteUser ( - UserId INT + DeleteUserId INT, OUT Result INT ) BEGIN START TRANSACTION; /* Check if the user Id is valid. */ - IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = DeleteUserId) THEN /* Check if the user still has folders. */ - IF NOT EXISTS (SELECT * FROM Folder WHERE OwnerUserId = UserId) THEN + IF NOT EXISTS (SELECT * FROM Folder WHERE OwnerUserId = DeleteUserId) THEN - DELETE FROM `User` WHERE UserId = UserId; + DELETE FROM `User` WHERE UserId = DeleteUserId; /* Ok successful. */ SELECT 0 INTO Result; @@ -452,13 +486,13 @@ IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN /* Check if the new name is valid. */ - IF EXISTS (SELECT u.Name FROM `User` u WHERE u.UserId = UserId AND u.Name LIKE Name) OR - NOT EXISTS (SELECT U.Name FROM `User` u WHERE u.Name LIKE Name) THEN + IF EXISTS (SELECT u.Username FROM `User` u WHERE u.UserId = UserId AND u.Username LIKE Name) OR + NOT EXISTS (SELECT U.Username FROM `User` u WHERE u.Username LIKE Name) THEN UPDATE `User` u SET - u.Name = Name, + u.Username = Name, u.QuotaHardLimit = QuotaHardLimit, u.QuotaWarnLimit = QuotaWarnLimit WHERE @@ -612,16 +646,16 @@ DROP PROCEDURE IF EXISTS DeleteGroup // CREATE PROCEDURE DeleteGroup ( - GroupId INT, + DeleteGroupId INT, OUT Result INT ) BEGIN START TRANSACTION; /* Check if the Id is valid. */ - IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = DeleteGroupId) THEN - DELETE FROM `Group` WHERE GroupId = GroupId; + DELETE FROM `Group` WHERE GroupId = DeleteGroupId; /* Ok successful. */ SELECT 0 INTO Result; @@ -716,18 +750,18 @@ DROP PROCEDURE IF EXISTS RemoveGroupFromGroup // CREATE PROCEDURE RemoveGroupFromGroup ( - ParentId INT, - GroupId INT, + DeleteParentId INT, + DeleteGroupId INT, OUT Result INT ) BEGIN START TRANSACTION; /* Check if the Ids is valid. */ - IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) AND - EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = ParentId) THEN + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = DeleteGroupId) AND + EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = DeleteParentId) THEN - DELETE FROM GroupGroupMap WHERE GroupId = GroupId AND ParentId = ParentId; + DELETE FROM GroupGroupMap WHERE GroupId = DeleteGroupId AND ParentId = DeleteParentId; /* Ok successful. */ SELECT 0 INTO Result; @@ -741,6 +775,55 @@ END // + +-- ----------------------------------------------------------------------- +-- +-- Mail domain related stored procedures +-- +-- ----------------------------------------------------------------------- + + +DROP PROCEDURE IF EXISTS GetMailDomainIds // +CREATE PROCEDURE GetMailDomainIds +() +BEGIN + + SELECT MailDomainId FROM MailDomain; + +END +// + +DROP PROCEDURE IF EXISTS AddMailDomain // +CREATE PROCEDURE AddMailDomain +( + PrimaryHost VARCHAR(255), + ObjectData LONGBLOB, + OUT MailDomainId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the name is valid. */ + IF NOT EXISTS (SELECT m.MailDomainId FROM MailDomain m WHERE m.PrimaryHost LIKE PrimaryHost) THEN + + INSERT INTO MailDomain (PrimaryHost, ObjectData) VALUES (PrimaryHost, ObjectData); + + SELECT LAST_INSERT_ID() INTO MailDomainId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + COMMIT; +END +// + + delimiter ; Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================... [truncated message content] |
|
From: <tmy...@us...> - 2006-05-20 07:15:58
|
Revision: 36 Author: tmyroadctfig Date: 2006-05-20 00:15:35 -0700 (Sat, 20 May 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=36&view=rev Log Message: ----------- Further work on local store. Modified Paths: -------------- NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-20 01:44:04 UTC (rev 35) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-20 07:15:35 UTC (rev 36) @@ -473,14 +473,33 @@ /// <returns>The result of the attempt to delete a group.</returns> LocalStoreGroupResult DeleteGroup(IAuthenticationToken authToken, int groupId); - /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - LocalStoreGroupResult UpdateGroup(IAuthenticationToken authToken, LocalStoreGroup group); + /// <summary> + /// Renames the group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + LocalStoreGroupResult RenameGroup(IAuthenticationToken authToken, LocalStoreGroup group); + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToGroup(IAuthenticationToken authToken, int parentId, int groupId); + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromGroup(IAuthenticationToken authToken, int parentId, int groupId); + /// <summary> /// Adds a group to the given mail domain. /// </summary> @@ -557,29 +576,29 @@ /// <summary> /// The operation was completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// The create or rename failed because a folder with the same name already existed. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// The folder was not deleted because it contained child folders. /// </summary> - HasChildren, + HasChildren = 2, /// <summary> /// The operation failed because the source folder was not found on the server. /// If the operation is on a subfolder that the user can't see due to permissions /// this will be returned. /// </summary> - NonExistent, + NonExistent = 3, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 4 } /// <summary> @@ -614,7 +633,17 @@ /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted = 5 + NotPermitted = 5, + + /// <summary> + /// The user cannot be created because there is existing folders with the same details. + /// </summary> + FoldersAlreadyExist = 6, + + /// <summary> + /// An unknown error occurred trying to perform the operation. + /// </summary> + UnkownError = 7 } /// <summary> Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-20 01:44:04 UTC (rev 35) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-20 07:15:35 UTC (rev 36) @@ -317,7 +317,7 @@ /// </summary> /// <param name="username">The username to lookup.</param> /// <returns>The user Id or null if non is found.</returns> - int GetUserId(string username); + int? GetUserId(string username); /// <summary> /// Creates a new user in the local store and creates an initial folder. @@ -393,24 +393,43 @@ LocalStoreGroupResult DeleteGroup(int groupId); /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - LocalStoreGroupResult UpdateGroup(LocalStoreGroup group); + /// Renames the group. + /// </summary> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + LocalStoreGroupResult RenameGroup(int groupId, string newName); + + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + LocalStoreGroupResult AddGroupToGroup(int parentId, int groupId); + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + LocalStoreGroupResult RemoveGroupFromGroup(int parentId, int groupId); /// <summary> /// Adds a group to the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> + /// <returns>The result of the attempt to add.</returns> LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId); /// <summary> /// Removes group from the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to remove.</param> - /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> + /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> + /// <returns>The result of the attempt to remove.</returns> LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId); #endregion Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-20 01:44:04 UTC (rev 35) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-20 07:15:35 UTC (rev 36) @@ -1017,20 +1017,43 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to delete.</param> /// <returns>The result of the attempt to delete a group.</returns> - public LocalStoreGroupResult DeleteGroup(IAuthenticationToken authToken, int groupId) { - return LocalStoreData.DeleteGroup(groupId); - } + public LocalStoreGroupResult DeleteGroup(IAuthenticationToken authToken, int groupId) { + return LocalStoreData.DeleteGroup(groupId); + } - /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="authToken">The authentication credentials.</param> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - public LocalStoreGroupResult UpdateGroup(IAuthenticationToken authToken, LocalStoreGroup group) { - return LocalStoreData.UpdateGroup(group); - } + /// <summary> + /// Renames the group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + public LocalStoreGroupResult RenameGroup(IAuthenticationToken authToken, LocalStoreGroup group) { + return LocalStoreData.RenameGroup(group.GroupId, group.Name); + } + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + public LocalStoreGroupResult AddGroupToGroup(IAuthenticationToken authToken, int parentId, int groupId) { + return LocalStoreData.AddGroupToGroup(parentId, groupId); + } + + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="authToken">The authentication credentials.</param> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + public LocalStoreGroupResult RemoveGroupFromGroup(IAuthenticationToken authToken, int parentId, int groupId) { + return LocalStoreData.RemoveGroupFromGroup(parentId, groupId); + } + /// <summary> /// Adds a group to the given mail domain. /// </summary> Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-20 01:44:04 UTC (rev 35) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-20 07:15:35 UTC (rev 36) @@ -73,6 +73,28 @@ PRIMARY KEY (MailDomainId) ) TYPE=InnoDb; +DROP TABLE IF EXISTS UserMailDomainMap; +CREATE TABLE UserMailDomainMap ( + UserId INT NOT NULL, + MailDomainId INT NOT NULL, + INDEX UserId (UserId), + FOREIGN KEY (UserId) REFERENCES `User` (UserId) ON DELETE CASCADE, + INDEX MailDomainId (MailDomainId), + FOREIGN KEY (MailDomainId) REFERENCES MailDomain (MailDomainId) ON DELETE CASCADE, + PRIMARY KEY(UserId, MailDomainId) +) TYPE=InnoDb; + +DROP TABLE IF EXISTS GroupMailDomainMap; +CREATE TABLE GroupMailDomainMap ( + GroupId INT NOT NULL, + MailDomainId INT NOT NULL, + INDEX GroupId (GroupId), + FOREIGN KEY (GroupId) REFERENCES `Group` (GroupId) ON DELETE CASCADE, + INDEX ParentId (MailDomainId), + FOREIGN KEY (MailDomainId) REFERENCES MailDomain (MailDomainId) ON DELETE CASCADE, + PRIMARY KEY(GroupId, MailDomainId) +) TYPE=InnoDb; + DROP TABLE IF EXISTS MailboxMapping; CREATE TABLE MailboxMapping ( MailboxMappingId INT AUTO_INCREMENT NOT NULL, @@ -167,28 +189,305 @@ FOREIGN KEY (FolderId) REFERENCES Folder (FolderId) ON DELETE CASCADE ) TYPE=InnoDB; -DROP TABLE IF EXISTS MailDomain; -CREATE TABLE MailDomain ( - MailDomainId INT AUTO_INCREMENT NOT NULL, - PrimaryHost VARCHAR(256) NOT NULL, - AdditionalHosts LONGBLOB, - MailboxMappings LONGBLOB, - AllowedActions LONGBLOB, - DefaultActions LONGBLOB, - AllowedValidators LONGBLOB, - PRIMARY KEY(MailDomainId) -) TYPE=InnoDB; +delimiter // + -- ----------------------------------------------------------------------- -- --- Stored procedures +-- Folder related stored procedures -- -- ----------------------------------------------------------------------- -delimiter // +DROP PROCEDURE IF EXISTS CreateFolder // +CREATE PROCEDURE CreateFolder +( + ParentId INT, + NamespaceId INT, + Name VARCHAR(1000), + UserId INT, + OUT FolderId INT, + OUT Result INT +) +BEGIN + + START TRANSACTION; + + /* Check if the parameters are valid. */ + IF EXISTS (SELECT f.FolderId FROM Folder f WHERE f.FolderId = ParentId) THEN + + /* Check for duplicate folders. */ + IF NOT EXISTS (SELECT f.FolderId FROM Folder f WHERE f.Name LIKE Name) THEN + + INSERT INTO Folder (ParentFolderId, NamespaceId, Name, OwnerUserId, NextMessageId) VALUES (ParentId, NamespaceId, Name, UserId, 1); + SELECT LAST_INSERT_ID() INTO FolderId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Folder already exists. */ + SELECT 1 INTO Result; + END IF; + + ELSE + /* No such parent. */ + SELECT 3 INTO Result; + END IF; + + COMMIT; +END +// +-- ----------------------------------------------------------------------- +-- +-- User related stored procedures +-- +-- ----------------------------------------------------------------------- + +DROP PROCEDURE IF EXISTS GetUserFromName // +CREATE PROCEDURE GetUserFromName +( + Name VARCHAR(100), + OUT UserId INT, + OUT QuotaHardLimit INT, + OUT QuotaWarnLimit INT, + OUT UserFolderId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.Name LIKE Name) THEN + + SELECT + u.UserId, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId + INTO + UserId, QuotaHardLimit, QuotaWarnLimit, UserFolderId + FROM + `User` u + WHERE + u.Name LIKE Name; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS GetUserFromId // +CREATE PROCEDURE GetUserFromId +( + UserId INT, + OUT Name VARCHAR(100), + OUT QuotaHardLimit INT, + OUT QuotaWarnLimit INT, + OUT UserFolderId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN + + SELECT + u.Name, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId + INTO + Name, QuotaHardLimit, QuotaWarnLimit, UserFolderId + FROM + `User` u + WHERE + u.UserId = UserId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS GetUserIds // +CREATE PROCEDURE GetUserIds +() +BEGIN + + SELECT u.UserId FROM `User` u; + +END +// + +DROP PROCEDURE IF EXISTS CreateUser // +CREATE PROCEDURE CreateUser +( + Name VARCHAR(100), + QuotaHardLimit INT, + QuotaWarnLimit INT, + OUT UserId INT, + OUT Result INT +) +BEGIN + DECLARE NamespaceId INT; + DECLARE InboxName VARCHAR(1000); + DECLARE UserFolderId INT; + DECLARE UserInboxId INT; + DECLARE CreateResult INT; + + SET NamespaceId = 1; + + START TRANSACTION; + + /* Check if the name is valid. */ + IF NOT EXISTS (SELECT u.UserId FROM User u WHERE u.Name LIKE Name) THEN + + SET InboxName = CONCAT_WS(".", Name, "INBOX"); + + /* Check if the user's folders exist */ + IF NOT EXISTS (SELECT * FROM Folder f WHERE f.Name LIKE Name and f.NamespaceId = NamespaceId) AND + NOT EXISTS (SELECT * FROM Folder f WHERE f.Name LIKE InboxName and f.NamespaceId = NamespaceId) THEN + + INSERT INTO User (Name, QuotaHardLimit, QuotaWarnLimit) VALUES (Name, QuotaHardLimit, QuotaWarnLimit); + SELECT LAST_INSERT_ID() INTO UserId; + + /* Create the user's base folder. */ + CALL CreateFolder(NULL, NamespaceId, Name, UserId, UserFolderId, CreateResult); + + IF CreateResult = 0 THEN + + /* Create an INBOX for the user. */ + CALL CreateFolder(UserFolderId, NamespaceId, InboxName, UserId, UserInboxId, CreateResult); + + IF CreateResult = 0 THEN + + /* Update the user to have the correct folder. */ + UPDATE User u SET u.UserFolderId = UserFolderId WHERE u.UserId = UserId; + + /* Ok successful. */ + SELECT 0 INTO Result; + COMMIT; + + ELSE + /* Error creating folder. Return unknown error. */ + SELECT 7 INTO Result; + ROLLBACK; + END IF; + + ELSE + /* Error creating folder. Return unknown error. */ + SELECT 7 INTO Result; + ROLLBACK; + END IF; + + ELSE + /* Folder's already exist. */ + SELECT 6 INTO Result; + ROLLBACK; + END IF; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + COMMIT; + END IF; +END +// + +DROP PROCEDURE IF EXISTS DeleteUser // +CREATE PROCEDURE DeleteUser +( + UserId INT + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the user Id is valid. */ + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN + + /* Check if the user still has folders. */ + IF NOT EXISTS (SELECT * FROM Folder WHERE OwnerUserId = UserId) THEN + + DELETE FROM `User` WHERE UserId = UserId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* User still has folders. */ + SELECT 4 INTO Result; + END IF; + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS UpdateUser // +CREATE PROCEDURE UpdateUser +( + UserId INT, + Name VARCHAR(100), + QuotaHardLimit INT, + QuotaWarnLimit INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the user Id is valid. */ + IF EXISTS (SELECT u.UserId FROM `User` u WHERE u.UserId = UserId) THEN + + /* Check if the new name is valid. */ + IF EXISTS (SELECT u.Name FROM `User` u WHERE u.UserId = UserId AND u.Name LIKE Name) OR + NOT EXISTS (SELECT U.Name FROM `User` u WHERE u.Name LIKE Name) THEN + + UPDATE + `User` u + SET + u.Name = Name, + u.QuotaHardLimit = QuotaHardLimit, + u.QuotaWarnLimit = QuotaWarnLimit + WHERE + u.UserId = UserId; + + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + + +-- ----------------------------------------------------------------------- +-- +-- Group related stored procedures +-- +-- ----------------------------------------------------------------------- + DROP PROCEDURE IF EXISTS GetGroupFromName // CREATE PROCEDURE GetGroupFromName ( @@ -222,7 +521,7 @@ SELECT 0 INTO Result; ELSE - /* No such user. */ + /* No such group. */ SELECT 2 INTO Result; END IF; @@ -263,7 +562,7 @@ SELECT 1 INTO Result; ELSE - /* No such user. */ + /* No such group. */ SELECT 2 INTO Result; END IF; @@ -291,12 +590,12 @@ BEGIN START TRANSACTION; - /* Check if the Id is valid. */ - IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + /* Check if the name is valid. */ + IF NOT EXISTS (SELECT g.GroupId FROM `Group` g WHERE g.Name LIKE Name) THEN INSERT INTO `Group` (Name) VALUES (Name); - SELECT g.GroupId INTO GroupId FROM `Group` g WHERE g.GroupId = LAST_INSERT_ID(); + SELECT LAST_INSERT_ID() INTO GroupId; /* Ok successful. */ SELECT 0 INTO Result; @@ -336,8 +635,8 @@ END // -DROP PROCEDURE IF EXISTS UpdateGroup // -CREATE PROCEDURE UpdateGroupName +DROP PROCEDURE IF EXISTS RenameGroup // +CREATE PROCEDURE RenameGroup ( GroupId INT, Name VARCHAR(100), @@ -350,12 +649,12 @@ IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN /* Check if the name has changed. */ - IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId AND g.Name = Name) THEN + IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId AND g.Name LIKE Name) THEN /* Check if the name already exists. */ IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.Name LIKE Name) THEN - UPDATE `Group` g SET g.Name = Name; + UPDATE `Group` g SET g.Name = Name WHERE g.GroupId = GroupId; /* Ok successful. */ SELECT 0 INTO Result; @@ -378,6 +677,70 @@ END // +DROP PROCEDURE IF EXISTS AddGroupToGroup // +CREATE PROCEDURE AddGroupToGroup +( + ParentId INT, + GroupId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the Ids is valid. */ + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) AND + EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = ParentId) THEN + + /* Check if an entry already exists */ + IF NOT EXISTS (SELECT * FROM GroupGroupMap WHERE g.GroupId = GroupId AND g.ParentId = ParentId) THEN + + INSERT INTO GroupGroupMap (GroupId, ParentId) VALUES (GroupId, ParentId); + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + ELSE + /* No such group. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS RemoveGroupFromGroup // +CREATE PROCEDURE RemoveGroupFromGroup +( + ParentId INT, + GroupId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the Ids is valid. */ + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) AND + EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = ParentId) THEN + + DELETE FROM GroupGroupMap WHERE GroupId = GroupId AND ParentId = ParentId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such group. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + delimiter ; Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-20 01:44:04 UTC (rev 35) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-20 07:15:35 UTC (rev 36) @@ -33,7 +33,6 @@ using NMail.LocalStoreData.MySql.Configuration; // TODO: implement quotas -// TODO: case insensitive folder names? // TODO: password expiry // TODO: account lockout if too many bad attempts @@ -60,7 +59,7 @@ userIds.Add(3); LocalStoreGroup g = m.GetGroup("Administrators"); g.UserIds = userIds.ToArray(); - m.UpdateGroup(g); + //m.UpdateGroup(g); g = m.GetGroup("Administrators"); } @@ -234,7 +233,7 @@ private int? getStoreFolderId(Folder folder, MySqlConnection cnn, MySqlTransaction transaction) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.Transaction = transaction; - cmd.CommandText = "SELECT f.FolderId FROM Namespace n, Folder f WHERE n.NamespaceId = f.NamespaceId AND n.Name = ?Namespace AND f.Name = ?FolderName"; + cmd.CommandText = "SELECT f.FolderId FROM Namespace n, Folder f WHERE n.NamespaceId = f.NamespaceId AND n.Name = ?Namespace AND f.Name LIKE ?FolderName"; cmd.Parameters.Add("FolderName", folder.FolderName); cmd.Parameters.Add("Namespace", folder.NameSpace); @@ -325,8 +324,9 @@ try { trans = cnn.BeginTransaction(); - int userId = getUserId(userName, cnn, trans); - StoreFolder result = createFolder(userId, parent, newFolder, cnn, null); + int? userId = getUserId(userName, cnn, trans); + // TODO: handle invalid userId properly + StoreFolder result = createFolder(userId.Value, parent, newFolder, cnn, null); trans.Commit(); return result; @@ -884,8 +884,12 @@ } #endregion - #region Load and Save Object - + #region Load and Save Object + /// <summary> + /// Gets a serialized object that can be used by either an validation or a delivery action. + /// </summary> + /// <param name="key">A key to identify which object to get.</param> + /// <returns>The object.</returns> public object LoadObject(string key) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { @@ -896,8 +900,12 @@ return SerializationHelper.Deserialize(data); } } - } + } + /// <summary> + /// Serializes an object that can be used later by either an validation or a delivery action. + /// </summary> + /// <param name="key">A key to identify the object at load time.</param> public void SaveObject(object o, string key) { using (MySqlConnection cnn = GetConnection()) { MySqlTransaction trans = cnn.BeginTransaction(); @@ -926,35 +934,67 @@ #region User Management #region Get User - public LocalStoreUser GetUser(string username) { - using (MySqlConnection cnn = GetConnection()) { - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "SELECT u.UserId, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId FROM User u WHERE u.Username = ?Username"; - cmd.Parameters.Add("Username", username); + /// <summary> + /// Gets the user for the given username. + /// </summary> + /// <param name="username">The username to look up.</param> + /// <returns>The matching user or null if non is found.</returns> + public LocalStoreUser GetUser(string name) { + using (MySqlConnection cnn = GetConnection()) { + return getUser(name, cnn, null); + } + } - using (MySqlDataReader reader = cmd.ExecuteReader()) { - if (reader.Read()) { - int userId = (int)reader["UserId"]; - object quotaHardLimit = reader["QuotaHardLimit"]; - object quotaWarnLimit = reader["QuotaWarnLimit"]; - int userFolderId = (int)reader["UserFolderId"]; + private LocalStoreUser getUser(string name, MySqlConnection cnn, MySqlTransaction transaction) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.Transaction = transaction; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetUserFromName"; + cmd.Parameters.Add("Name", name); + cmd.Parameters.Add("UserId", MySqlDbType.Int32); + cmd.Parameters.Add("QuotaHardLimit", MySqlDbType.Int32); + cmd.Parameters.Add("QuotaWarnLimit", MySqlDbType.Int32); + cmd.Parameters.Add("UserFolderId", MySqlDbType.Int32); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["UserId"].Direction = ParameterDirection.Output; + cmd.Parameters["QuotaHardLimit"].Direction = ParameterDirection.Output; + cmd.Parameters["QuotaWarnLimit"].Direction = ParameterDirection.Output; + cmd.Parameters["UserFolderId"].Direction = ParameterDirection.Output; + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?)quotaHardLimit; - int? quotaWarnLimitVal = (quotaWarnLimit == DBNull.Value) ? null : (int?)quotaWarnLimit; + cmd.ExecuteNonQuery(); + + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreUserResult result = (LocalStoreUserResult) resultValue; - return new LocalStoreUser(username, - userId, - userFolderId, - quotaWarnLimitVal, - quotaHardLimitVal); - } + // Check if the lookup succeeded + if (result != LocalStoreUserResult.OkSuccessful) { + return null; + } + + // Parse out all the returned values + int userId = (int) cmd.Parameters["UserId"].Value; + object quotaHardLimit = (int) cmd.Parameters["QuotaHardLimit"].Value; + object quotaWarnLimit = (int) cmd.Parameters["QuotaWarnLimit"].Value; + int userFolderId = (int) cmd.Parameters["UserFolderId"].Value; - return null; - } - } - } - } + int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?) quotaHardLimit; + int? quotaWarnLimitVal = (quotaWarnLimit == DBNull.Value) ? null : (int?) quotaWarnLimit; + // Return the user object + return new LocalStoreUser(name, + userId, + userFolderId, + quotaWarnLimitVal, + quotaHardLimitVal); + } + } + + /// <summary> + /// Gets the user for the given user Id. + /// </summary> + /// <param name="userId">The Id of the user to look up.</param> + /// <returns>The matching user or null if non is found.</returns> public LocalStoreUser GetUser(int userId) { using (MySqlConnection cnn = GetConnection()) { return getUser(userId, cnn, null); @@ -963,68 +1003,98 @@ public LocalStoreUser getUser(int userId, MySqlConnection cnn, MySqlTransaction transaction) { using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.Transaction = transaction; - cmd.CommandText = "SELECT u.Username, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId FROM User u WHERE u.UserId = ?UserId"; - cmd.Parameters.Add("UserId", userId); + cmd.Transaction = transaction; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetUserFromId"; + cmd.Parameters.Add("UserId", userId); + cmd.Parameters.Add("Name", MySqlDbType.VarChar); + cmd.Parameters.Add("QuotaHardLimit", MySqlDbType.Int32); + cmd.Parameters.Add("QuotaWarnLimit", MySqlDbType.Int32); + cmd.Parameters.Add("UserFolderId", MySqlDbType.Int32); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Name"].Direction = ParameterDirection.Output; + cmd.Parameters["QuotaHardLimit"].Direction = ParameterDirection.Output; + cmd.Parameters["QuotaWarnLimit"].Direction = ParameterDirection.Output; + cmd.Parameters["UserFolderId"].Direction = ParameterDirection.Output; + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - using (MySqlDataReader reader = cmd.ExecuteReader()) { - if (reader.Read()) { - string username = (string)reader["Username"]; - object quotaHardLimit = reader["QuotaHardLimit"]; - object quotaWarnLimit = reader["QuotaWarnLimit"]; - int userFolderId = (int)reader["UserFolderId"]; + cmd.ExecuteNonQuery(); - int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?)quotaHardLimit; - int? quotaWarnLimitVal = (quotaWarnLimit == DBNull.Value) ? null : (int?)quotaWarnLimit; + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreUserResult result = (LocalStoreUserResult) resultValue; - return new LocalStoreUser(username, - userId, - userFolderId, - quotaWarnLimitVal, - quotaHardLimitVal); - } + // Check if the lookup succeeded + if (result != LocalStoreUserResult.OkSuccessful) { + return null; + } - return null; - } + // Parse out all the returned values + string name = (string) cmd.Parameters["Name"].Value; + object quotaHardLimit = (int) cmd.Parameters["QuotaHardLimit"].Value; + object quotaWarnLimit = (int) cmd.Parameters["QuotaWarnLimit"].Value; + int userFolderId = (int) cmd.Parameters["UserFolderId"].Value; + + int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?) quotaHardLimit; + int? quotaWarnLimitVal = (quotaWarnLimit == DBNull.Value) ? null : (int?) quotaWarnLimit; + + // Return the user object + return new LocalStoreUser(name, + userId, + userFolderId, + quotaWarnLimitVal, + quotaHardLimitVal); } } #endregion #region Get Users - public LocalStoreUser[] GetUsers() { + /// <summary> + /// Gets the list of users that currently exist in the local store. + /// </summary> + /// <returns>The list of users.</returns> + public LocalStoreUser[] GetUsers() { using (MySqlConnection cnn = GetConnection()) { - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "SELECT u.Username, u.UserId, u.QuotaHardLimit, u.QuotaWarnLimit, u.UserFolderId FROM User u"; + MySqlTransaction transaction = cnn.BeginTransaction(); - using (MySqlDataReader reader = cmd.ExecuteReader()) { - List<LocalStoreUser> users = new List<LocalStoreUser>(); + try { + MySqlCommand cmd = cnn.CreateCommand(); + cmd.Transaction = transaction; - while (reader.Read()) { - string username = (string)reader["Username"]; - int userId = (int)reader["UserId"]; - object quotaHardLimit = reader["QuotaHardLimit"]; - object quotaWarnLimit = reader["QuotaWarnLimit"]; - int userFolderId = (int)reader["UserFolderId"]; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetUserIds"; + MySqlDataReader reader = cmd.ExecuteReader(); + List<int> userIds = new List<int>(); - int? quotaHardLimitVal = (quotaHardLimit == DBNull.Value) ? null : (int?)quotaHardLimit; - int? quotaWarnLimitVal = (quotaWarnLimit == DBNull.Value) ? null : (int?)quotaWarnLimit; + while (reader.NextResult()) { + int userId = (int) reader["UserId"]; + } - users.Add(new LocalStoreUser(username, - userId, - userFolderId, - quotaWarnLimitVal, - quotaHardLimitVal)); - } + List<LocalStoreUser> users = new List<LocalStoreUser>(); + foreach (int userId in userIds) { + users.Add(getUser(userId, cnn, transaction)); + } - return users.ToArray(); + transaction.Commit(); + return users.ToArray(); + + } catch (Exception ex) { + if (transaction != null) { + transaction.Rollback(); } + + throw ex; } } } #endregion #region Get Username - public string GetUsername(int userId) { + /// <summary> + /// Gets the username associated with the given Id. + /// </summary> + /// <param name="userId">The user Id to lookup.</param> + /// <returns>The username or null if non is found.</returns> + public string GetUsername(int userId) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.CommandText = "SELECT u.Username FROM User u WHERE UserId = ?UserId"; @@ -1042,13 +1112,18 @@ #endregion #region Get User Id - public int GetUserId(string username) { + /// <summary> + /// Gets the user Id for the associated username. + /// </summary> + /// <param name="username">The username to lookup.</param> + /// <returns>The user Id or null if non is found.</returns> + public int? GetUserId(string username) { using (MySqlConnection cnn = GetConnection()) { return getUserId(username, cnn, null); } } - private int getUserId(string username, MySqlConnection cnn, MySqlTransaction trans) { + private int? getUserId(string username, MySqlConnection cnn, MySqlTransaction trans) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.CommandText = "SELECT u.UserId FROM User u WHERE Username = ?Username"; cmd.Parameters.Add("Username", username); @@ -1056,192 +1131,116 @@ object o = cmd.ExecuteScalar(); if (o == null || o == DBNull.Value) { - return -1; + return null; } else { return (int)o; } } } #endregion - - /// <summary> - /// Adds a user to the given mail domain. - /// </summary> - /// <param name="userId">The Id of the user to add.</param> - /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - public LocalStoreUserResult AddUserToMailDomain(int userId, int mailDomainId) { - throw new NotImplementedException(); - } - /// <summary> - /// Removes user from the given mail domain. - /// </summary> - /// <param name="userId">The Id of the user to remove.</param> - /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - public LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId) { - throw new NotImplementedException(); - } - - public LocalStoreUserResult CreateUser(string username, int? warnQuota, int? hardQuota) { + #region Create User + /// <summary> + /// Creates a new user in the local store and creates an initial folder. + /// </summary> + /// <param name="userName">The name of the new user.</param> + /// <param name="warnQuota">The warning quota level.</param> + /// <param name="hardQuota">The hard quota.</param> + /// <returns>The result of the attemp to create a new user.</returns> + public LocalStoreUserResult CreateUser(string username, int? warnQuota, int? hardQuota) { using (MySqlConnection cnn = GetConnection()) { - MySqlTransaction transaction = null; - - try { - transaction = cnn.BeginTransaction(); - - MySqlCommand cmd = cnn.CreateCommand(); - cmd.Transaction = transaction; - cmd.Connection = cnn; - - //TODO: make adjustable - int namespaceId = 1; - string namespaceStr = "LocalMail"; - - // Check if the user has a folder - cmd.CommandText = "SELECT COUNT(*) FROM Folder WHERE Name = ?Name and NamespaceId = ?NamespaceId"; + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "CreateUser"; cmd.Parameters.Add("Name", username); - cmd.Parameters.Add("NamespaceId", namespaceId); - long count = (long) cmd.ExecuteScalar(); + cmd.Parameters.Add("QuotaHardLimit", hardQuota); + cmd.Parameters.Add("QuotaWarnLimit", warnQuota); + cmd.Parameters.Add("UserId", MySqlDbType.Int32); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["UserId"].Direction = ParameterDirection.Output; + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - if (count != 0) { - throw new InvalidOperationException("Folder with the same username already exists."); - } + cmd.ExecuteNonQuery(); - // Check if the user has an inbox folder - cmd.CommandText = "SELECT COUNT(*) FROM Folder WHERE Name = ?Name and NamespaceId = ?NamespaceId"; - cmd.Parameters.Add("Name", username + ".INBOX"); - cmd.Parameters.Add("NamespaceId", namespaceId); - count = (long) cmd.ExecuteScalar(); + int result = (int) cmd.Parameters["Result"].Value; - if (count != 0) { - throw new InvalidOperationException("User's inbox already exists."); - } - - // Check if the user exists - cmd.CommandText = "SELECT COUNT(*) FROM User WHERE Username = ?Username"; - cmd.Parameters.Add("Username", username); - count = (long) cmd.ExecuteScalar(); - - if (count != 0) { - transaction.Commit(); - return LocalStoreUserResult.AlreadyExists; - } - - // Add the user - cmd.CommandText = "INSERT INTO User (Username, QuotaHardLimit, QuotaWarnLimit, Password) VALUES (?Username, ?QuotaHardLimit, ?QuotaWarnLimit, NULL)"; - cmd.Parameters.Add("Username", username); - cmd.Parameters.Add("QuotaHardLimit", hardQuota); - cmd.Parameters.Add("QuotaWarnLimit", warnQuota); - if (cmd.ExecuteNonQuery() != 1) { - throw new System.Data.DataException("Error inserting user."); - } - - int userId = getUserId(username, cnn, transaction); - - // Add the user's folder - Folder newFolder = new Folder(namespaceStr, username); - StoreFolder baseFolder = createFolder(userId, namespaceId, null, newFolder, cnn, transaction); - - // Add the user's inbox - Folder inboxFolder = new Folder(baseFolder, "INBOX"); - StoreFolder createdFolder = createFolder(userId, namespaceId, baseFolder.FolderId, inboxFolder, cnn, transaction); - - // Give the new user full privileges to their folders - setStoreFolderAce(baseFolder, new StoreFolderAce(username, StoreFolderPrivilegeHelper.AllPrivileges, AcePrivilegeType.Allow), cnn, transaction); - setStoreFolderAce(createdFolder, new StoreFolderAce(username, StoreFolderPrivilegeHelper.AllPrivileges, AcePrivilegeType.Allow), cnn, transaction); - - // Update the user's entry to include the folder Id - cmd.CommandText = "UPDATE User SET UserFolderId = ?UserFolderId WHERE UserId = ?UserId"; - cmd.Parameters.Add("UserFolderId", baseFolder.FolderId); - cmd.Parameters.Add("UserId", userId); - - if (cmd.ExecuteNonQuery() != 1) { - throw new System.Data.DataException("Error updating user's folder Id."); - } - - transaction.Commit(); - return LocalStoreUserResult.OkSuccessful; - - } catch (Exception e) { - if (transaction != null) { - transaction.Rollback(); - } - - throw e; + return (LocalStoreUserResult) result; } } - } + } + #endregion - #region Delete User - public LocalStoreUserResult DeleteUser(int userId) { + #region Delete User + /// <summary> + /// Removes a user from the local store. + /// </summary> + /// <param name="userId">The Id of the user to delete.</param> + /// <returns>The result of the attempt to delete a user.</returns> + public LocalStoreUserResult DeleteUser(int userId) { using (MySqlConnection cnn = GetConnection()) { - MySqlTransaction transaction = null; + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "DeleteUser"; + cmd.Parameters.Add("UserId", userId); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - try { - transaction = cnn.BeginTransaction(); + cmd.ExecuteNonQuery(); - // Check if the user exists - LocalStoreUser user = getUser(userId, cnn, transaction); - if (user == null) { - transaction.Commit(); - return LocalStoreUserResult.NoSuchUser; - } + int result = (int) cmd.Parameters["Result"].Value; - using (MySqlCommand cmd = cnn.CreateCommand()) { - // Check if the user still owns any folders - cmd.Transaction = transaction; - cmd.CommandText = "SELECT COUNT(*) FROM Folder WHERE OwnerUserId = ?UserId"; - cmd.Parameters.Add("UserId", userId); - long folders = (long)cmd.ExecuteScalar(); - - if (folders != 0) { - transaction.Commit(); - return LocalStoreUserResult.UserStillHasFolders; - } - - // Delete the user - cmd.CommandText = "DELETE FROM User WHERE UserId = ?UserId"; - cmd.Parameters.Add("UserId", userId); - - if (cmd.ExecuteNonQuery() != 1) { - throw new System.Data.DataException("Error deleting user."); - } - - transaction.Commit(); - return LocalStoreUserResult.OkSuccessful; - } - } catch (Exception ex) { - if (transaction != null) { - transaction.Rollback(); - } - - throw ex; - } + return (LocalStoreUserResult) result; + } } } #endregion #region Update User + /// <summary> + /// Updates the any changes to the user into the local store. + /// </summary> + /// <param name="user">The user details to update.</param> + /// <returns>The result of the attempt to update the user.</returns> public LocalStoreUserResult UpdateUser(LocalStoreUser user) { using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandText = "UPDATE User SET Username = ?Username, UserFolderId = ?UserFolderId, QuotaHardLimit = ?QuotaHardLimit, QuotaWarnLimit = ?QuotaWarnLimit WHERE UserId = ?UserId"; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "UpdateUser"; cmd.Parameters.Add("UserId", user.UserId); - cmd.Parameters.Add("Username", user.Username); - cmd.Parameters.Add("UserFolderId", user.UserFolderId); + cmd.Parameters.Add("Name", user.Username); cmd.Parameters.Add("QuotaHardLimit", user.QuotaHardLimit); cmd.Parameters.Add("QuotaWarnLimit", user.QuotaWarnLimit); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - if (cmd.ExecuteNonQuery() != 1) { - throw new System.Data.DataException("Error updating user."); - } + cmd.ExecuteNonQuery(); - return LocalStoreUserResult.OkSuccessful; + int result = (int) cmd.Parameters["Result"].Value; + + return (LocalStoreUserResult) result; } } } + #endregion + + /// <summary> + /// Adds a user to the given mail domain. + /// </summary> + /// <param name="userId">The Id of the user to add.</param> + /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> + public LocalStoreUserResult AddUserToMailDomain(int userId, int mailDomainId) { + throw new NotImplementedException(); + } + + /// <summary> + /// Removes user from the given mail domain. + /// </summary> + /// <param name="userId">The Id of the user to remove.</param> + /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> + public LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId) { + throw new NotImplementedException(); + } #endregion - #endregion #region Group Management #region GetGroup @@ -1432,7 +1431,7 @@ using (MySqlConnection cnn = GetConnection()) { using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.CommandType = CommandType.StoredProcedure; - cmd.CommandText = "SELECT DeleteGroup(?GroupId)"; + cmd.CommandText = "DeleteGroup"; cmd.Parameters.Add("GroupId", groupId); cmd.Parameters.Add("Result", MySqlDbType.Int32); cmd.Parameters["Result"].Direction = ParameterDirection.Output; @@ -1447,99 +1446,106 @@ } #endregion - #region Update Group - /// <summary> - /// Updates the any changes to the group into the local store. - /// </summary> - /// <param name="group">The group details to update.</param> - /// <returns>The result of the attempt to update the group.</returns> - public LocalStoreGroupResult UpdateGroup(LocalStoreGroup group) { + #region Rename Group + /// <summary> + /// Renames the group. + /// </summary> + /// <param name="groupId">The Id of the group to delete.</param> + /// <param name="newName">The new name for the group.</param> + /// <returns>The result of the attempt to rename the group.</returns> + public LocalStoreGroupResult RenameGroup(int groupId, string newName) { using (MySqlConnection cnn = GetConnection()) { - MySqlTransaction transaction = cnn.BeginTransaction(); - - try { - MySqlCommand cmd = cnn.CreateCommand(); - cmd.Transaction = transaction; - + using (MySqlCommand cmd = cnn.CreateCommand()) { cmd.CommandType = CommandType.StoredProcedure; - cmd.CommandText = "UpdateGroupName"; - cmd.Parameters.Add("GroupId", group.GroupId); - cmd.Parameters.Add("Name", group.Name); + cmd.CommandText = "RenameGroup"; + cmd.Parameters.Add("GroupId", groupId); + cmd.Parameters.Add("Name", newName); cmd.Parameters.Add("Result", MySqlDbType.Int32); cmd.Parameters["Result"].Direction = ParameterDirection.Output; cmd.ExecuteNonQuery(); - int resultValue = (int) cmd.Parameters["Result"].Value; - LocalStoreGroupResult result = (LocalStoreGroupResult) resultValue; + int result = (int) cmd.Parameters["Result"].Value; - // Check for any errors updating the group name - if (result != LocalStoreGroupResult.OkSuccessful) { - transaction.Rollback(); - return result; - } + return (LocalStoreGroupResult) result; + } + } + } + #endregion - // Delete and re-add all the group's users - cmd = cnn.CreateCommand(); - cmd.Transaction = transaction; - cmd.CommandText = "DELETE FROM UserGroupMap WHERE GroupId = ?GroupId"; - cmd.Parameters.Add("GroupId", group.GroupId); - cmd.ExecuteNonQuery(); + #region Add Group to Group + /// <summary> + /// Adds a child group to the given group. + /// </summary> + /// <param name="groupId">The child group to add.</param> + /// <param name="parentId">The group to add the child to.</param> + /// <returns>The result of the attempt to add.</returns> + public LocalStoreGroupResult AddGroupToGroup(int parentId, int groupId) { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "AddGroupToGroup"; + cmd.Parameters.Add("ParentId", parentId); + cmd.Parameters.Add("GroupId", groupId); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - cmd.CommandText = "INSERT INTO UserGroupMap (UserId, GroupId) VALUES (?UserId, ?GroupId)"; - cmd.Parameters.Add("GroupId", group.GroupId); - cmd.Parameters.Add("UserId", -1); - foreach (int userId in group.UserIds) { - cmd.Parameters["UserId"].Value = userId; - cmd.ExecuteNonQuery(); - } + cmd.ExecuteNonQuery(); - // Delete and re-add all the group's sub-groups - cmd = cnn.CreateCommand(); - cmd.Transaction = transaction; - cmd.CommandText = "DELETE FROM GroupGroupMap WHERE ParentId = ?ParentId"; - cmd.Parameters.Add("ParentId", group.GroupId); - cmd.ExecuteNonQuery(); + int result = (int) cmd.Parameters["Result"].Value; - cmd.CommandText = "INSERT INTO GroupGroupMap (ParentId, GroupId) VALUES (?ParentId, ?GroupId)"; - cmd.Parameters.Add("ParentId", group.GroupId); - cmd.Parameters.Add("GroupId", -1); - foreach (int groupId in group.SubGroupIds) { - cmd.Parameters["GroupId"].Value = groupId; - cmd.ExecuteNonQuery(); - } + return (LocalStoreGroupResult) result; + } + } + } + #endregion - transaction.Commit(); - return LocalStoreGroupResult.OkSuccessful; + #region Remove Group from Group + /// <summary> + /// Removes a child group from the given group. + /// </summary> + /// <param name="groupId">The child group to remove.</param> + /// <param name="parentId">The group to remove the child from.</param> + /// <returns>The result of the attempt to remove.</returns> + public LocalStoreGroupResult RemoveGroupFromGroup(int parentId, int groupId) { + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "RemoveGroupFromGroup"; + cmd.Parameters.Add("ParentId", parentId); + cmd.Parameters.Add("GroupId", groupId); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - } catch (Exception ex) { - if (transaction != null) { - transaction.Rollback(); - } + cmd.ExecuteNonQuery(); - throw ex; - } - } - } - #endregion + int result = (int) cmd.Parameters["Result"].Value; - /// <summary> - /// Adds a group to the given mail domain. - /// </summary> - /// <param name="groupId">The Id of the group to add.</param> - /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - public LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId) { - throw new NotImplementedException(); - } + return (LocalStoreGroupResult) result; + } + } + } + #endregion - /// <summary> - /// Removes group from the given mail domain. - /// </summary> - /// <param name="groupId">The Id of the group to remove.</param> - /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - public LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId) { - throw new NotImplementedException(); - } + /// <summary> + /// Adds a group to the given mail domain. + /// </summary> + /// <param name="groupId">The Id of the group to add.</param> + /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> + /// <returns>The result of the attempt to add.</returns> + public LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId) { + throw new NotImplementedException(); + } + + /// <summary> + /// Removes group from the given mail domain. + /// </summary> + /// <param name="groupId">The Id of the group to remove.</param> + /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> + /// <returns>The result of the attempt to remove.</returns> + public LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId) { + throw new NotImplementedException(); + } #endregion #region ACLs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-05-20 01:44:32
|
Revision: 35 Author: tmyroadctfig Date: 2006-05-19 18:44:04 -0700 (Fri, 19 May 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=35&view=rev Log Message: ----------- Work on local store. Modified Paths: -------------- NMail/branches/luke-dev/NMail/DataTypes/LocalStoreGroup.cs NMail/branches/luke-dev/NMail/ILocalStore.cs NMail/branches/luke-dev/NMail/ILocalStoreData.cs NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Added Paths: ----------- NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs NMail/branches/luke-dev/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs Modified: NMail/branches/luke-dev/NMail/DataTypes/LocalStoreGroup.cs =================================================================== --- NMail/branches/luke-dev/NMail/DataTypes/LocalStoreGroup.cs 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail/DataTypes/LocalStoreGroup.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -35,6 +35,8 @@ public LocalStoreGroup(string name, int groupId, int[] userIds, int[] groupIds) { this.name = name; this.groupId = groupId; + this.userIds = userIds; + this.groupIds = groupIds; } private string name; Modified: NMail/branches/luke-dev/NMail/ILocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail/ILocalStore.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -420,7 +420,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - void AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + /// <returns>The result of the attempt to add the user to the mail domain.</returns> + LocalStoreUserResult AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); /// <summary> /// Removes user from the given mail domain. @@ -428,7 +429,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - void RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); + /// <returns>The result of the attempt to remove the user from the mail domain.</returns> + LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId); #endregion #region Group Management @@ -485,7 +487,7 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - void AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + LocalStoreGroupResult AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); /// <summary> /// Removes group from the given mail domain. @@ -493,7 +495,7 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - void RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); + LocalStoreGroupResult RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId); #endregion #region Mail Domain Management @@ -587,27 +589,32 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A user with the same name already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching user exists in the local store. /// </summary> - NoSuchUser, + NoSuchUser = 2, /// <summary> + /// Cannot add or remove the user from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> /// The user cannot be deleted because they still own folders. /// </summary> - UserStillHasFolders, + UserStillHasFolders = 4, /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 5 } /// <summary> @@ -617,22 +624,27 @@ /// <summary> /// The operation completed successfully. /// </summary> - OkSuccessful, + OkSuccessful = 0, /// <summary> /// A group with the same name already exists. /// </summary> - AlreadyExists, + AlreadyExists = 1, /// <summary> /// No matching group exists in the local store. /// </summary> - NoSuchUser, + NoSuchGroup = 2, /// <summary> + /// Cannot add or remove the group from the mail domain because it doens't exist. + /// </summary> + NoSuchMailDomain = 3, + + /// <summary> /// The user is not permitted to perform the operation. /// </summary> - NotPermitted + NotPermitted = 4 } /// <summary> Modified: NMail/branches/luke-dev/NMail/ILocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail/ILocalStoreData.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -347,14 +347,14 @@ /// </summary> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - void AddUserToMailDomain(int userId, int mailDomainId); + LocalStoreUserResult AddUserToMailDomain(int userId, int mailDomainId); /// <summary> /// Removes user from the given mail domain. /// </summary> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - void RemoveUserFromMailDomain(int userId, int mailDomainId); + LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId); #endregion #region Group Management @@ -404,14 +404,14 @@ /// </summary> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - void AddGroupToMailDomain(int groupId, int mailDomainId); + LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId); /// <summary> /// Removes group from the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - void RemoveGroupFromMailDomain(int groupId, int mailDomainId); + LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId); #endregion #region Mail Domain Management Added: NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Console/Command/AddUserToMailDomainCommand.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -0,0 +1,99 @@ +/* + * 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; +using NMail.Authentication; +using NMail.DataTypes; + +namespace NMail.Administration.Console.Command { + class AddUserToMailDomainCommand : IConsoleCommand { + + private ILocalStore localStore; + + private IAuthenticationToken authToken; + + internal AddUserToMailDomainCommand(ILocalStore localStore, IAuthenticationToken authToken) { + this.localStore = localStore; + this.authToken = authToken; + } + + #region IConsoleCommand Members + + public string Description { + get { return "Adds an existing user to a mail domain."; } + } + + public string[] Usage { + get { + List<string> usage = new List<string>(); + + usage.Add("addusertomaildomain Username MailDomainId"); + + return usage.ToArray(); + } + } + + public string Remarks { + get { + return null; + } + } + + public ConsoleExample[] Examples { + get { + List<ConsoleExample> examples = new List<ConsoleExample>(); + + examples.Add(new ConsoleExample("addusertomaildomain jsmith 1", "Add the user with the username \"jsmith\" to the mail domain with Id 1.")); + + return examples.ToArray(); + } + } + + public void Process(string[] commandTokens) { + string username; + int mailDomainId; + + if (commandTokens.Length != 2) { + System.Console.WriteLine("A username and mail domain Id are required."); + return; + } + username = commandTokens[0]; + try { + mailDomainId = Int32.Parse(commandTokens[1]); + } catch (Exception) { + System.Console.WriteLine("Error parsing mail domain Id."); + return; + } + + LocalStoreUser user = this.localStore.GetUser(this.authToken, username); + if (user == null) { + System.Console.WriteLine("No such user."); + return; + } + + this.localStore.AddUserToMailDomain(this.authToken, user.UserId, mailDomainId); + System.Console.WriteLine("Added user to mail domain."); + System.Console.WriteLine(); + } + + #endregion + } +} Added: NMail/branches/luke-dev/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs (rev 0) +++ NMail/branches/luke-dev/NMail.Administration.Console/Command/RemoveUserFromMailDomainCommand.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -0,0 +1,103 @@ +/* + * 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; +using NMail.Authentication; +using NMail.DataTypes; + +namespace NMail.Administration.Console.Command { + class RemoveUserFromMailDomainCommand : IConsoleCommand { + + private ILocalStore localStore; + + private IAuthenticationToken authToken; + + internal RemoveUserFromMailDomainCommand(ILocalStore localStore, IAuthenticationToken authToken) { + this.localStore = localStore; + this.authToken = authToken; + } + + #region IConsoleCommand Members + + public string Description { + get { return "Removes a user from a mail domain."; } + } + + public string[] Usage { + get { + List<string> usage = new List<string>(); + + usage.Add("removeuserfrommaildomain Username MailDomainId"); + + return usage.ToArray(); + } + } + + public string Remarks { + get { + return null; + } + } + + public ConsoleExample[] Examples { + get { + List<ConsoleExample> examples = new List<ConsoleExample>(); + + examples.Add(new ConsoleExample("removeuserfrommaildomain jsmith 1", "Removes the user with the username \"jsmith\" from the mail domain with Id 1.")); + + return examples.ToArray(); + } + } + + public void Process(string[] commandTokens) { + string username; + int mailDomainId; + + if (commandTokens.Length != 2) { + System.Console.WriteLine("A username and mail domain Id are required."); + return; + } + username = commandTokens[0]; + try { + mailDomainId = Int32.Parse(commandTokens[1]); + } catch (Exception) { + System.Console.WriteLine("Error parsing mail domain Id."); + return; + } + + LocalStoreUser user = this.localStore.GetUser(this.authToken, username); + if (user == null) { + System.Console.WriteLine("No such user."); + return; + } + + LocalStoreUserResult result = this.localStore.RemoveUserFromMailDomain(this.authToken, user.UserId, mailDomainId); + if (result == LocalStoreUserResult.OkSuccessful) { + System.Console.WriteLine("Removed user from mail domain."); + } else { + System.Console.WriteLine("An error occurred removing the user from the mail domain."); + } + System.Console.WriteLine(); + } + + #endregion + } +} Modified: NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj =================================================================== --- NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail.Administration.Console/NMail.Administration.Console.csproj 2006-05-20 01:44:04 UTC (rev 35) @@ -35,6 +35,8 @@ </ItemGroup> <ItemGroup> <Compile Include="Command\AddUserCommand.cs" /> + <Compile Include="Command\AddUserToMailDomainCommand.cs" /> + <Compile Include="Command\RemoveUserFromMailDomainCommand.cs" /> <Compile Include="Command\ListFoldersCommand.cs" /> <Compile Include="Command\DeleteUserCommand.cs" /> <Compile Include="Command\ListMailDomainsCommand.cs" /> Modified: NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail.LocalStore/LocalStore.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -954,8 +954,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - public void AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId) { - this.LocalStoreData.AddUserToMailDomain(userId, mailDomainId); + public LocalStoreUserResult AddUserToMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId) { + return this.LocalStoreData.AddUserToMailDomain(userId, mailDomainId); } /// <summary> @@ -964,8 +964,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - public void RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId) { - this.LocalStoreData.RemoveUserFromMailDomain(userId, mailDomainId); + public LocalStoreUserResult RemoveUserFromMailDomain(IAuthenticationToken authToken, int userId, int mailDomainId) { + return this.LocalStoreData.RemoveUserFromMailDomain(userId, mailDomainId); } #endregion @@ -1037,8 +1037,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - public void AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId) { - LocalStoreData.AddGroupToMailDomain(groupId, mailDomainId); + public LocalStoreGroupResult AddGroupToMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId) { + return LocalStoreData.AddGroupToMailDomain(groupId, mailDomainId); } /// <summary> @@ -1047,8 +1047,8 @@ /// <param name="authToken">The authentication credentials.</param> /// <param name="groupId">The Id of the group to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - public void RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId) { - LocalStoreData.RemoveGroupFromMailDomain(groupId, mailDomainId); + public LocalStoreGroupResult RemoveGroupFromMailDomain(IAuthenticationToken authToken, int groupId, int mailDomainId) { + return LocalStoreData.RemoveGroupFromMailDomain(groupId, mailDomainId); } #endregion Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStore.sql 2006-05-20 01:44:04 UTC (rev 35) @@ -39,34 +39,40 @@ DROP TABLE IF EXISTS `Group`; CREATE TABLE `Group` ( GroupId INT AUTO_INCREMENT NOT NULL, - GroupName VARCHAR(100) NOT NULL, + Name VARCHAR(100) NOT NULL, PRIMARY KEY(GroupId) ) TYPE=InnoDb; DROP TABLE IF EXISTS UserGroupMap; CREATE TABLE UserGroupMap ( - UserGroupMapId INT AUTO_INCREMENT NOT NULL, UserId INT NOT NULL, GroupId INT NOT NULL, INDEX UserId (UserId), FOREIGN KEY (UserId) REFERENCES `User` (UserId) ON DELETE CASCADE, INDEX GroupId (GroupId), FOREIGN KEY (GroupId) REFERENCES `Group` (GroupId) ON DELETE CASCADE, - PRIMARY KEY(UserGroupMapId) + PRIMARY KEY(UserId, GroupId) ) TYPE=InnoDb; DROP TABLE IF EXISTS GroupGroupMap; CREATE TABLE GroupGroupMap ( - GroupGroupMapId INT AUTO_INCREMENT NOT NULL, ParentId INT NOT NULL, GroupId INT NOT NULL, INDEX ParentId (ParentId), FOREIGN KEY (ParentId) REFERENCES `Group` (GroupId) ON DELETE CASCADE, INDEX GroupId (GroupId), FOREIGN KEY (GroupId) REFERENCES `Group` (GroupId) ON DELETE CASCADE, - PRIMARY KEY(GroupGroupMapId) + PRIMARY KEY(ParentId, GroupId) ) TYPE=InnoDb; +DROP TABLE IF EXISTS MailDomain; +CREATE TABLE MailDomain ( + MailDomainId INT AUTO_INCREMENT NOT NULL, + PrimaryHost VARCHAR(255) NOT NULL, + ObjectData LONGBLOB NOT NULL, + PRIMARY KEY (MailDomainId) +) TYPE=InnoDb; + DROP TABLE IF EXISTS MailboxMapping; CREATE TABLE MailboxMapping ( MailboxMappingId INT AUTO_INCREMENT NOT NULL, @@ -184,38 +190,194 @@ DROP PROCEDURE IF EXISTS GetGroupFromName // -CREATE PROCEDURE GetGroup +CREATE PROCEDURE GetGroupFromName ( Name VARCHAR(100), - OUT GroupId INT + OUT GroupId INT, + OUT Result INT ) BEGIN - START TRANSACTION; - SELECT g.GroupId INTO GroupId FROM `Group` g WHERE g.Name = Name; + IF EXISTS (SELECT g.GroupId FROM `Group` g WHERE g.Name LIKE Name) THEN + + SELECT g.GroupId INTO GroupId FROM `Group` g WHERE g.Name LIKE Name; + SELECT + gm.GroupId + FROM + GroupGroupMap gm + WHERE + gm.ParentId = GroupId; - SELECT - gm.GroupId - FROM - GroupGroupMap gm - WHERE - gm.ParentId = GroupId; + SELECT + um.UserId + FROM + UserGroupMap um + WHERE + um.GroupId = GroupId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// - SELECT - um.UserId - FROM - UserGroupMap um - WHERE - um.GroupId = GroupId; +DROP PROCEDURE IF EXISTS GetGroupFromId // +CREATE PROCEDURE GetGroupFromId +( + GroupId INT, + OUT Name VARCHAR(100), + OUT Result INT +) +BEGIN + START TRANSACTION; + + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + + SELECT g.Name INTO Name FROM `Group` g WHERE g.GroupId = GroupId; + + SELECT + gm.GroupId + FROM + GroupGroupMap gm + WHERE + gm.ParentId = GroupId; + + + SELECT + um.UserId + FROM + UserGroupMap um + WHERE + um.GroupId = GroupId; + + /* Ok successful. */ + SELECT 1 INTO Result; + + ELSE + /* No such user. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + +DROP PROCEDURE IF EXISTS GetGroupIds // +CREATE PROCEDURE GetGroupIds +() +BEGIN + + SELECT g.GroupId FROM `Group` g; + +END +// + +DROP PROCEDURE IF EXISTS CreateGroup // +CREATE PROCEDURE CreateGroup +( + Name VARCHAR(100), + OUT GroupId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the Id is valid. */ + IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + INSERT INTO `Group` (Name) VALUES (Name); + + SELECT g.GroupId INTO GroupId FROM `Group` g WHERE g.GroupId = LAST_INSERT_ID(); + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + COMMIT; +END +// +DROP PROCEDURE IF EXISTS DeleteGroup // +CREATE PROCEDURE DeleteGroup +( + GroupId INT, + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the Id is valid. */ + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + + DELETE FROM `Group` WHERE GroupId = GroupId; + + /* Ok successful. */ + SELECT 0 INTO Result; + + ELSE + /* No such group. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; END // +DROP PROCEDURE IF EXISTS UpdateGroup // +CREATE PROCEDURE UpdateGroupName +( + GroupId INT, + Name VARCHAR(100), + OUT Result INT +) +BEGIN + START TRANSACTION; + + /* Check if the Id is valid. */ + IF EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId) THEN + + /* Check if the name has changed. */ + IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.GroupId = GroupId AND g.Name = Name) THEN + + /* Check if the name already exists. */ + IF NOT EXISTS (SELECT g.Name FROM `Group` g WHERE g.Name LIKE Name) THEN + + UPDATE `Group` g SET g.Name = Name; + + /* Ok successful. */ + SELECT 0 INTO Result; + ELSE + /* Already exists. */ + SELECT 1 INTO Result; + END IF; + + ELSE + /* No name change needed. Return "Ok successful". */ + SELECT 0 INTO Result; + END IF; + + ELSE + /* No such group. */ + SELECT 2 INTO Result; + END IF; + + COMMIT; +END +// + delimiter ; @@ -231,4 +393,23 @@ INSERT INTO Folder (NamespaceId, Name, OwnerUserId, NextMessageId, ParentFolderId) VALUES (1, "Administrator.INBOX", 1, 1, 1); INSERT INTO FolderAcl (FolderId, Identifier, Allow, Privilege) VALUES (1, "Administrator", 1, 0xffffff); -- All privs INSERT INTO FolderAcl (FolderId, Identifier, Allow, Privilege) VALUES (2, "Administrator", 1, 0xffffff); -- All privs -INSERT INTO Subscription (UserId, FolderId) VALUES (1, 2); \ No newline at end of file +INSERT INTO Subscription (UserId, FolderId) VALUES (1, 2); +INSERT INTO `Group` (Name) VALUES ("Administrators"); +INSERT INTO UserGroupMap (GroupId, UserId) VALUES (1, 1); + + +-- TODO: remove, for testing only +INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing1", "changeme", 2); +INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing2", "changeme", 2); +INSERT INTO User (UserName, Password, UserFolderId) VALUES ("Testing3", "changeme", 2); + +INSERT INTO `Group` (Name) VALUES ("Test1"); +INSERT INTO `Group` (Name) VALUES ("Test2"); +INSERT INTO `Group` (Name) VALUES ("Test3"); + +INSERT INTO UserGroupMap (UserId, GroupId) VALUES (2, 1); +INSERT INTO UserGroupMap (UserId, GroupId) VALUES (2, 2); +INSERT INTO UserGroupMap (UserId, GroupId) VALUES (3, 3); + + +INSERT INTO GroupGroupMap (ParentId, GroupId) VALUES (3, 2); \ No newline at end of file Modified: NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-14 08:18:20 UTC (rev 34) +++ NMail/branches/luke-dev/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-20 01:44:04 UTC (rev 35) @@ -51,7 +51,17 @@ // TODO: remove (for testing only) static MySqlLocalStoreData() { MySqlLocalStoreData m = new MySqlLocalStoreData(); - m.GetGroup("Administrators"); + //m.CreateGroup("Test123"); + //m.GetGroup("aaaAdministrators"); + //m.CreateUser("Test123", 100, 100); + + List<int> userIds = new List<int>(); + userIds.Add(2); + userIds.Add(3); + LocalStoreGroup g = m.GetGroup("Administrators"); + g.UserIds = userIds.ToArray(); + m.UpdateGroup(g); + g = m.GetGroup("Administrators"); } #region ILocalStoreData Members @@ -1052,13 +1062,14 @@ } } } + #endregion /// <summary> /// Adds a user to the given mail domain. /// </summary> /// <param name="userId">The Id of the user to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the user to.</param> - public void AddUserToMailDomain(int userId, int mailDomainId) { + public LocalStoreUserResult AddUserToMailDomain(int userId, int mailDomainId) { throw new NotImplementedException(); } @@ -1067,10 +1078,9 @@ /// </summary> /// <param name="userId">The Id of the user to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the user from.</param> - public void RemoveUserFromMailDomain(int userId, int mailDomainId) { + public LocalStoreUserResult RemoveUserFromMailDomain(int userId, int mailDomainId) { throw new NotImplementedException(); } - #endregion public LocalStoreUserResult CreateUser(string username, int? warnQuota, int? hardQuota) { using (MySqlConnection cnn = GetConnection()) { @@ -1234,6 +1244,7 @@ #endregion #region Group Management + #region GetGroup /// <summary> /// Gets the group for the given name. /// </summary> @@ -1241,20 +1252,50 @@ /// <returns>The matching group or null if non is found.</returns> public LocalStoreGroup GetGroup(string name) { using (MySqlConnection cnn = GetConnection()) { + return getGroup(name, cnn, null); + } + } - using (MySqlCommand cmd = cnn.CreateCommand()) { - cmd.CommandType = CommandType.StoredProcedure; - cmd.CommandText = "GetGroup()"; - cmd.Parameters.Add("Name", name); + private LocalStoreGroup getGroup(string name, MySqlConnection cnn, MySqlTransaction transaction) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.Transaction = transaction; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetGroupFromName"; + cmd.Parameters.Add("Name", name); + cmd.Parameters.Add("GroupId", MySqlDbType.Int32); + cmd.Parameters["GroupId"].Direction = ParameterDirection.Output; + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; - DataSet groupData = new DataSet(); - MySqlDataAdapter da = new MySqlDataAdapter(cmd); - da.Fill(groupData); + DataSet groupData = new DataSet(); + MySqlDataAdapter da = new MySqlDataAdapter(cmd); + da.Fill(groupData); - int groupId = (int) cmd.Parameters["GroupId"].Value; + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreUserResult result = (LocalStoreUserResult) resultValue; + // Check if the lookup succeeded + if (result != LocalStoreUserResult.OkSuccessful) { return null; } + + int groupId = (int) cmd.Parameters["GroupId"].Value; + + // Get the group's sub-group Ids + List<int> groupIds = new List<int>(); + DataTable groupGroupTable = groupData.Tables[0]; + foreach (DataRow row in groupGroupTable.Rows) { + groupIds.Add((int) row[0]); + } + + // The the group's user Ids + List<int> userIds = new List<int>(); + DataTable userGroupTable = groupData.Tables[1]; + foreach (DataRow row in userGroupTable.Rows) { + userIds.Add((int) row[0]); + } + + return new LocalStoreGroup(name, groupId, userIds.ToArray(), groupIds.ToArray()); } } @@ -1264,50 +1305,230 @@ /// <param name="groupId">The Id of the group to look up.</param> /// <returns>The matching group or null if non is found.</returns> public LocalStoreGroup GetGroup(int groupId) { - throw new NotImplementedException(); + using (MySqlConnection cnn = GetConnection()) { + return getGroup(groupId, cnn, null); + } } + private LocalStoreGroup getGroup(int groupId, MySqlConnection cnn, MySqlTransaction transaction) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.Transaction = transaction; + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetGroupFromId"; + cmd.Parameters.Add("GroupId", groupId); + cmd.Parameters.Add("Name", MySqlDbType.VarChar); + cmd.Parameters["Name"].Direction = ParameterDirection.Output; + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; + + DataSet groupData = new DataSet(); + MySqlDataAdapter da = new MySqlDataAdapter(cmd); + da.Fill(groupData); + + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreUserResult result = (LocalStoreUserResult) resultValue; + + // Check if the lookup succeeded + if (result != LocalStoreUserResult.OkSuccessful) { + return null; + } + + string name = (string) cmd.Parameters["Name"].Value; + + // Get the group's sub-group Ids + List<int> groupIds = new List<int>(); + DataTable groupGroupTable = groupData.Tables[0]; + foreach (DataRow row in groupGroupTable.Rows) { + groupIds.Add((int) row[0]); + } + + // The the group's user Ids + List<int> userIds = new List<int>(); + DataTable userGroupTable = groupData.Tables[1]; + foreach (DataRow row in userGroupTable.Rows) { + userIds.Add((int) row[0]); + } + + return new LocalStoreGroup(name, groupId, userIds.ToArray(), groupIds.ToArray()); + } + } + #endregion + + #region GetGroups /// <summary> /// Gets the list of groups that currently exist in the local store. /// </summary> /// <returns>The list of groups.</returns> public LocalStoreGroup[] GetGroups() { - throw new NotImplementedException(); + using (MySqlConnection cnn = GetConnection()) { + MySqlTransaction transaction = cnn.BeginTransaction(); + + try { + MySqlCommand cmd = cnn.CreateCommand(); + cmd.Transaction = transaction; + + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "GetGroupIds"; + MySqlDataReader reader = cmd.ExecuteReader(); + List<int> groupIds = new List<int>(); + + while (reader.NextResult()) { + int groupId = (int) reader["GroupId"]; + } + + List<LocalStoreGroup> groups = new List<LocalStoreGroup>(); + foreach (int groupId in groupIds) { + groups.Add(getGroup(groupId, cnn, transaction)); + } + + transaction.Commit(); + return groups.ToArray(); + + } catch (Exception ex) { + if (transaction != null) { + transaction.Rollback(); + } + + throw ex; + } + } } + #endregion + #region CreateGroup /// <summary> /// Creates a new group in the local store. /// </summary> /// <param name="name">The name of the new group.</param> /// <returns>The result of the attemp to create a new group.</returns> public LocalStoreGroupResult CreateGroup(string name) { - throw new NotImplementedException(); + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "CreateGroup"; + cmd.Parameters.Add("Name", name); + cmd.Parameters.Add("GroupId", MySqlDbType.Int32); + cmd.Parameters["GroupId"].Direction = ParameterDirection.Output; + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; + + cmd.ExecuteNonQuery(); + + int result = (int) cmd.Parameters["Result"].Value; + + return (LocalStoreGroupResult) result; + } + } } + #endregion + #region Delete Group /// <summary> /// Removes a group from the local store. /// </summary> /// <param name="groupId">The Id of the group to delete.</param> /// <returns>The result of the attempt to delete a group.</returns> public LocalStoreGroupResult DeleteGroup(int groupId) { - throw new NotImplementedException(); + using (MySqlConnection cnn = GetConnection()) { + using (MySqlCommand cmd = cnn.CreateCommand()) { + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "SELECT DeleteGroup(?GroupId)"; + cmd.Parameters.Add("GroupId", groupId); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; + + cmd.ExecuteNonQuery(); + + int result = (int) cmd.Parameters["Result"].Value; + + return (LocalStoreGroupResult) result; + } + } } + #endregion + #region Update Group /// <summary> /// Updates the any changes to the group into the local store. /// </summary> /// <param name="group">The group details to update.</param> /// <returns>The result of the attempt to update the group.</returns> public LocalStoreGroupResult UpdateGroup(LocalStoreGroup group) { - throw new NotImplementedException(); + using (MySqlConnection cnn = GetConnection()) { + MySqlTransaction transaction = cnn.BeginTransaction(); + + try { + MySqlCommand cmd = cnn.CreateCommand(); + cmd.Transaction = transaction; + + cmd.CommandType = CommandType.StoredProcedure; + cmd.CommandText = "UpdateGroupName"; + cmd.Parameters.Add("GroupId", group.GroupId); + cmd.Parameters.Add("Name", group.Name); + cmd.Parameters.Add("Result", MySqlDbType.Int32); + cmd.Parameters["Result"].Direction = ParameterDirection.Output; + + cmd.ExecuteNonQuery(); + + int resultValue = (int) cmd.Parameters["Result"].Value; + LocalStoreGroupResult result = (LocalStoreGroupResult) resultValue; + + // Check for any errors updating the group name + if (result != LocalStoreGroupResult.OkSuccessful) { + transaction.Rollback(); + return result; + } + + // Delete and re-add all the group's users + cmd = cnn.CreateCommand(); + cmd.Transaction = transaction; + cmd.CommandText = "DELETE FROM UserGroupMap WHERE GroupId = ?GroupId"; + cmd.Parameters.Add("GroupId", group.GroupId); + cmd.ExecuteNonQuery(); + + cmd.CommandText = "INSERT INTO UserGroupMap (UserId, GroupId) VALUES (?UserId, ?GroupId)"; + cmd.Parameters.Add("GroupId", group.GroupId); + cmd.Parameters.Add("UserId", -1); + foreach (int userId in group.UserIds) { + cmd.Parameters["UserId"].Value = userId; + cmd.ExecuteNonQuery(); + } + + // Delete and re-add all the group's sub-groups + cmd = cnn.CreateCommand(); + cmd.Transaction = transaction; + cmd.CommandText = "DELETE FROM GroupGroupMap WHERE ParentId = ?ParentId"; + cmd.Parameters.Add("ParentId", group.GroupId); + cmd.ExecuteNonQuery(); + + cmd.CommandText = "INSERT INTO GroupGroupMap (ParentId, GroupId) VALUES (?ParentId, ?GroupId)"; + cmd.Parameters.Add("ParentId", group.GroupId); + cmd.Parameters.Add("GroupId", -1); + foreach (int groupId in group.SubGroupIds) { + cmd.Parameters["GroupId"].Value = groupId; + cmd.ExecuteNonQuery(); + } + + transaction.Commit(); + return LocalStoreGroupResult.OkSuccessful; + + } catch (Exception ex) { + if (transaction != null) { + transaction.Rollback(); + } + + throw ex; + } + } } - + #endregion + /// <summary> /// Adds a group to the given mail domain. /// </summary> /// <param name="groupId">The Id of the group to add.</param> /// <param name="mailDomainId">The Id of the mail domain to add the group to.</param> - public void AddGroupToMailDomain(int groupId, int mailDomainId) { + public LocalStoreGroupResult AddGroupToMailDomain(int groupId, int mailDomainId) { throw new NotImplementedException(); } @@ -1316,7 +1537,7 @@ /// </summary> /// <param name="groupId">The Id of the group to remove.</param> /// <param name="mailDomainId">The Id of the mail domain to revome the group from.</param> - public void RemoveGroupFromMailDomain(int groupId, int mailDomainId) { + public LocalStoreGroupResult RemoveGroupFromMailDomain(int groupId, int mailDomainId) { throw new NotImplementedException(); } #endregion This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <tmy...@us...> - 2006-05-14 08:18:25
|
Revision: 34 Author: tmyroadctfig Date: 2006-05-14 01:18:20 -0700 (Sun, 14 May 2006) ViewCVS: http://svn.sourceforge.net/nmailserver/?rev=34&view=rev Log Message: ----------- Removed test code. Modified Paths: -------------- NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs Modified: NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs =================================================================== --- NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-14 08:09:03 UTC (rev 33) +++ NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs 2006-05-14 08:18:20 UTC (rev 34) @@ -48,12 +48,6 @@ return cnn; } - // TODO: remove (for testing only) - static MySqlLocalStoreData() { - MySqlLocalStoreData m = new MySqlLocalStoreData(); - m.GetGroup("Administrators"); - } - #region ILocalStoreData Members #region Message Delivery This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |