This commit is contained in:
Alexander Trofimov 2015-05-28 09:20:31 +03:00
commit 1b5f9765d0
35 changed files with 8593 additions and 6066 deletions

View file

@ -57,6 +57,8 @@ namespace WebsitePanel.EnterpriseServer
public const string WEBDAV_PASSWORD_RESET_ENABLED_KEY = "WebdavPswResetEnabled"; public const string WEBDAV_PASSWORD_RESET_ENABLED_KEY = "WebdavPswResetEnabled";
public const string WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN = "WebdavPswdResetLinkLifeSpan"; public const string WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN = "WebdavPswdResetLinkLifeSpan";
public const string WEBDAV_OWA_ENABLED_KEY = "WebdavOwaEnabled";
public const string WEBDAV_OWA_URL = "WebdavOwaUrl";
// key to access to wpi main & custom feed in wpi settings // key to access to wpi main & custom feed in wpi settings
public const string WPI_MAIN_FEED_KEY = "WpiMainFeedUrl"; public const string WPI_MAIN_FEED_KEY = "WpiMainFeedUrl";

View file

@ -34,6 +34,8 @@ using System.Data;
using System.Linq; using System.Linq;
using System.Net.Mail; using System.Net.Mail;
using System.Threading; using System.Threading;
using System.Drawing;
using System.IO;
using WebsitePanel.EnterpriseServer.Code.HostedSolution; using WebsitePanel.EnterpriseServer.Code.HostedSolution;
using WebsitePanel.Providers; using WebsitePanel.Providers;
using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Common;
@ -47,6 +49,8 @@ namespace WebsitePanel.EnterpriseServer
{ {
public class ExchangeServerController public class ExchangeServerController
{ {
public const int MAX_THUMBNAILPHOTO_SIZE = 96;
#region Organizations #region Organizations
public static DataSet GetRawExchangeOrganizationsPaged(int packageId, bool recursive, public static DataSet GetRawExchangeOrganizationsPaged(int packageId, bool recursive,
string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows)
@ -6033,6 +6037,125 @@ namespace WebsitePanel.EnterpriseServer
} }
#endregion #endregion
#region Pictures
// proportional resizing
private static Bitmap ResizeBitmap(Bitmap srcBitmap, Size newSize)
{
try
{
Bitmap destBitmap = new Bitmap(newSize.Width, newSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Rectangle srcRect = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
Rectangle destRect = new Rectangle(0, 0, destBitmap.Width, destBitmap.Height);
float kWidth = Convert.ToSingle(srcBitmap.Width) / Convert.ToSingle(destBitmap.Width);
float kHeight = Convert.ToSingle(srcBitmap.Height) / Convert.ToSingle(destBitmap.Height);
if (kHeight > kWidth)
{
int l = (srcBitmap.Height - Convert.ToInt32(kWidth * destBitmap.Height));
srcRect.Y = l / 2;
srcRect.Height = srcBitmap.Height - l;
}
else if (kHeight < kWidth)
{
int l = (srcBitmap.Width - Convert.ToInt32(kHeight * destBitmap.Width));
srcRect.X = l / 2;
srcRect.Width = srcBitmap.Width - l;
}
Graphics g = Graphics.FromImage(destBitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
g.DrawImage(srcBitmap, destRect, srcRect, GraphicsUnit.Pixel);
g.Dispose();
return destBitmap;
}
catch
{
return null;
}
}
public static ResultObject SetPicture(int itemId, int accountID, byte[] picture)
{
ResultObject res = TaskManager.StartResultTask<ResultObject>("EXCHANGE", "SET_PICTURE", itemId);
Organization org = GetOrganization(itemId);
if (org == null)
throw new ApplicationException("Organization is null");
ExchangeAccount account = GetAccount(itemId, accountID);
try
{
int exchangeServiceId = GetExchangeServiceID(org.PackageId);
if (exchangeServiceId > 0)
{
ExchangeServer exchange = GetExchangeServer(exchangeServiceId, org.ServiceId);
Bitmap bitmap;
if (picture == null)
bitmap = new Bitmap(1, 1);
else
bitmap = new Bitmap(new MemoryStream(picture));
MemoryStream pictureStream = new MemoryStream();
if ((bitmap.Width > MAX_THUMBNAILPHOTO_SIZE) || (bitmap.Height > MAX_THUMBNAILPHOTO_SIZE))
bitmap = ResizeBitmap(bitmap, new Size(MAX_THUMBNAILPHOTO_SIZE, MAX_THUMBNAILPHOTO_SIZE));
bitmap.Save(pictureStream, System.Drawing.Imaging.ImageFormat.Jpeg);
res = exchange.SetPicture(account.AccountName, pictureStream.ToArray());
}
}
catch (Exception ex)
{
TaskManager.WriteError(ex);
TaskManager.CompleteResultTask(res);
return res;
}
TaskManager.CompleteResultTask();
return res;
} }
public static BytesResult GetPicture(int itemId, int accountID)
{
BytesResult res = TaskManager.StartResultTask<BytesResult>("EXCHANGE", "GET_PICTURE", itemId);
Organization org = GetOrganization(itemId);
if (org == null)
throw new ApplicationException("Organization is null");
ExchangeAccount account = GetAccount(itemId, accountID);
try
{
int exchangeServiceId = GetExchangeServiceID(org.PackageId);
if (exchangeServiceId > 0)
{
ExchangeServer exchange = GetExchangeServer(exchangeServiceId, org.ServiceId);
res = exchange.GetPicture(account.AccountName);
}
}
catch (Exception ex)
{
TaskManager.WriteError(ex);
TaskManager.CompleteResultTask(res);
return res;
}
TaskManager.CompleteResultTask();
return res;
}
#endregion
}
} }

View file

@ -1596,7 +1596,14 @@ namespace WebsitePanel.EnterpriseServer
var rds = RemoteDesktopServicesHelpers.GetRemoteDesktopServices(RemoteDesktopServicesHelpers.GetRemoteDesktopServiceID(org.PackageId)); var rds = RemoteDesktopServicesHelpers.GetRemoteDesktopServices(RemoteDesktopServicesHelpers.GetRemoteDesktopServiceID(org.PackageId));
var collection = ObjectUtils.FillObjectFromDataReader<RdsCollection>(DataProvider.GetRDSCollectionById(collectionId)); var collection = ObjectUtils.FillObjectFromDataReader<RdsCollection>(DataProvider.GetRDSCollectionById(collectionId));
var users = rds.GetApplicationUsers(collection.Name, remoteApp.Alias); string alias = "";
if (remoteApp != null)
{
alias = remoteApp.Alias;
}
var users = rds.GetApplicationUsers(collection.Name, alias);
result.AddRange(users); result.AddRange(users);
return result; return result;

View file

@ -51,6 +51,7 @@
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.DirectoryServices" /> <Reference Include="System.DirectoryServices" />
<Reference Include="System.Drawing" />
<Reference Include="System.Security" /> <Reference Include="System.Security" />
<Reference Include="System.ServiceProcess" /> <Reference Include="System.ServiceProcess" />
<Reference Include="System.Web" /> <Reference Include="System.Web" />

View file

@ -768,8 +768,8 @@ namespace WebsitePanel.EnterpriseServer
{ {
return ExchangeServerController.SetExchangeAccountDisclaimerId(itemId, AccountID, ExchangeDisclaimerId); return ExchangeServerController.SetExchangeAccountDisclaimerId(itemId, AccountID, ExchangeDisclaimerId);
} }
[WebMethod]
[WebMethod]
public int GetExchangeAccountDisclaimerId(int itemId, int AccountID) public int GetExchangeAccountDisclaimerId(int itemId, int AccountID)
{ {
return ExchangeServerController.GetExchangeAccountDisclaimerId(itemId, AccountID); return ExchangeServerController.GetExchangeAccountDisclaimerId(itemId, AccountID);
@ -777,5 +777,19 @@ namespace WebsitePanel.EnterpriseServer
#endregion #endregion
#region Picture
[WebMethod]
public ResultObject SetPicture(int itemId, int accountId, byte[] picture)
{
return ExchangeServerController.SetPicture(itemId, accountId, picture);
}
[WebMethod]
public BytesResult GetPicture(int itemId, int accountId)
{
return ExchangeServerController.GetPicture(itemId, accountId);
}
#endregion
} }
} }

View file

@ -28,6 +28,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.ResultObjects;
namespace WebsitePanel.Providers.HostedSolution namespace WebsitePanel.Providers.HostedSolution
{ {
@ -151,5 +152,9 @@ namespace WebsitePanel.Providers.HostedSolution
ResultObject RemoveRetentionPolicyTag(string Identity); ResultObject RemoveRetentionPolicyTag(string Identity);
ResultObject SetRetentionPolicy(string Identity, string[] RetentionPolicyTagLinks); ResultObject SetRetentionPolicy(string Identity, string[] RetentionPolicyTagLinks);
ResultObject RemoveRetentionPolicy(string Identity); ResultObject RemoveRetentionPolicy(string Identity);
// Picture
ResultObject SetPicture(string accountName, byte[] picture);
BytesResult GetPicture(string accountName);
} }
} }

View file

@ -49,6 +49,7 @@ using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.Utils; using WebsitePanel.Providers.Utils;
using WebsitePanel.Server.Utils; using WebsitePanel.Server.Utils;
using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.ResultObjects;
using Microsoft.Exchange.Data.Directory.Recipient; using Microsoft.Exchange.Data.Directory.Recipient;
using Microsoft.Win32; using Microsoft.Win32;
@ -7969,6 +7970,67 @@ namespace WebsitePanel.Providers.HostedSolution
#endregion #endregion
#region Picture
public virtual ResultObject SetPicture(string accountName, byte[] picture)
{
ExchangeLog.LogStart("SetPicture");
ResultObject res = new ResultObject() { IsSuccess = true };
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd;
cmd = new Command("Import-RecipientDataProperty");
cmd.Parameters.Add("Identity", accountName);
cmd.Parameters.Add("Picture", true);
cmd.Parameters.Add("FileData", picture);
ExecuteShellCommand(runSpace, cmd, res);
}
finally
{
CloseRunspace(runSpace);
}
ExchangeLog.LogEnd("SetPicture");
return res;
}
public virtual BytesResult GetPicture(string accountName)
{
ExchangeLog.LogStart("GetPicture");
BytesResult res = new BytesResult() { IsSuccess = true };
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd;
cmd = new Command("Export-RecipientDataProperty");
cmd.Parameters.Add("Identity", accountName);
cmd.Parameters.Add("Picture", true);
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, res);
if (result.Count > 0)
{
res.Value =
((Microsoft.Exchange.Data.BinaryFileDataObject)
(result[0].ImmediateBaseObject)).FileData;
}
}
finally
{
CloseRunspace(runSpace);
}
ExchangeLog.LogEnd("GetPicture");
return res;
}
#endregion
} }
} }

View file

@ -48,6 +48,7 @@ using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.HostedSolution; using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.Utils; using WebsitePanel.Providers.Utils;
using WebsitePanel.Server.Utils; using WebsitePanel.Server.Utils;
using WebsitePanel.Providers.ResultObjects;
using Microsoft.Exchange.Data.Directory.Recipient; using Microsoft.Exchange.Data.Directory.Recipient;
using Microsoft.Win32; using Microsoft.Win32;
@ -7146,5 +7147,17 @@ namespace WebsitePanel.Providers.HostedSolution
#endregion #endregion
#region Picture
public virtual ResultObject SetPicture(string accountName, byte[] picture)
{
// not implemented
return null;
}
public virtual BytesResult GetPicture(string accountName)
{
// not implemented
return null;
}
#endregion
} }
} }

View file

@ -48,6 +48,8 @@ using WebsitePanel.Providers.Utils;
using WebsitePanel.Server.Utils; using WebsitePanel.Server.Utils;
using Microsoft.Exchange.Data.Directory.Recipient; using Microsoft.Exchange.Data.Directory.Recipient;
using Microsoft.Win32; using Microsoft.Win32;
using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.ResultObjects;
using Microsoft.Exchange.Data; using Microsoft.Exchange.Data;
using Microsoft.Exchange.Data.Directory; using Microsoft.Exchange.Data.Directory;
@ -501,6 +503,21 @@ namespace WebsitePanel.Providers.HostedSolution
} }
} }
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, ResultObject res, bool setIsSuccess)
{
object[] errors;
Collection<PSObject> ret = ExecuteShellCommand(runSpace, cmd, out errors);
if (errors.Length > 0)
{
foreach (object error in errors)
res.ErrorCodes.Add(error.ToString());
if (setIsSuccess)
res.IsSuccess = false;
}
return ret;
}
#endregion #endregion
#region Storage #region Storage
@ -536,6 +553,66 @@ namespace WebsitePanel.Providers.HostedSolution
} }
#endregion #endregion
#region Picture
public virtual ResultObject SetPicture(string accountName, byte[] picture)
{
ExchangeLog.LogStart("SetPicture");
ResultObject res = new ResultObject() { IsSuccess = true };
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd;
cmd = new Command("Import-RecipientDataProperty");
cmd.Parameters.Add("Identity", accountName);
cmd.Parameters.Add("Picture", true);
cmd.Parameters.Add("FileData", picture);
ExecuteShellCommand(runSpace, cmd, res, true);
}
finally
{
CloseRunspace(runSpace);
}
ExchangeLog.LogEnd("SetPicture");
return res;
}
public virtual BytesResult GetPicture(string accountName)
{
ExchangeLog.LogStart("GetPicture");
BytesResult res = new BytesResult() { IsSuccess = true };
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd;
cmd = new Command("Export-RecipientDataProperty");
cmd.Parameters.Add("Identity", accountName);
cmd.Parameters.Add("Picture", true);
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, res, true);
if (result.Count > 0)
{
res.Value =
((Microsoft.Exchange.Data.BinaryFileDataObject)
(result[0].ImmediateBaseObject)).FileData;
}
}
finally
{
CloseRunspace(runSpace);
}
ExchangeLog.LogEnd("GetPicture");
return res;
}
#endregion
public override bool IsInstalled() public override bool IsInstalled()
{ {

View file

@ -379,7 +379,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
string collectionComputersPath = GetComputerGroupPath(organizationId, collection.Name); string collectionComputersPath = GetComputerGroupPath(organizationId, collection.Name);
CreatePolicy(runSpace, organizationId, string.Format("{0}-administrators", collection.Name), CreatePolicy(runSpace, organizationId, string.Format("{0}-administrators", collection.Name),
new DirectoryEntry(GetGroupPath(organizationId, collection.Name, GetLocalAdminsGroupName(collection.Name))), new DirectoryEntry(collectionComputersPath), collection.Name); new DirectoryEntry(GetGroupPath(organizationId, collection.Name, GetLocalAdminsGroupName(collection.Name))), new DirectoryEntry(collectionComputersPath), collection.Name);
CreatePolicy(runSpace, organizationId, string.Format("{0}-users", collection.Name), new DirectoryEntry(GetUsersGroupPath(organizationId, collection.Name)) CreateUsersPolicy(runSpace, organizationId, string.Format("{0}-users", collection.Name), new DirectoryEntry(GetUsersGroupPath(organizationId, collection.Name))
, new DirectoryEntry(collectionComputersPath), collection.Name); , new DirectoryEntry(collectionComputersPath), collection.Name);
CreateHelpDeskPolicy(runSpace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collection.Name); CreateHelpDeskPolicy(runSpace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collection.Name);
} }
@ -709,7 +709,11 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
Command cmd = new Command("Get-RDRemoteApp"); Command cmd = new Command("Get-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName); cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker); cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
if (!string.IsNullOrEmpty(applicationName))
{
cmd.Parameters.Add("Alias", applicationName); cmd.Parameters.Add("Alias", applicationName);
}
var application = ExecuteShellCommand(runspace, cmd, false).FirstOrDefault(); var application = ExecuteShellCommand(runspace, cmd, false).FirstOrDefault();
@ -1137,7 +1141,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
CreatePolicy(runspace, organizationId, string.Format("{0}-administrators", collectionName), CreatePolicy(runspace, organizationId, string.Format("{0}-administrators", collectionName),
new DirectoryEntry(GetGroupPath(organizationId, collectionName, GetLocalAdminsGroupName(collectionName))), new DirectoryEntry(collectionComputersPath), collectionName); new DirectoryEntry(GetGroupPath(organizationId, collectionName, GetLocalAdminsGroupName(collectionName))), new DirectoryEntry(collectionComputersPath), collectionName);
CreatePolicy(runspace, organizationId, string.Format("{0}-users", collectionName), CreateUsersPolicy(runspace, organizationId, string.Format("{0}-users", collectionName),
new DirectoryEntry(GetUsersGroupPath(organizationId, collectionName)), new DirectoryEntry(collectionComputersPath), collectionName); new DirectoryEntry(GetUsersGroupPath(organizationId, collectionName)), new DirectoryEntry(collectionComputersPath), collectionName);
CreateHelpDeskPolicy(runspace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collectionName); CreateHelpDeskPolicy(runspace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collectionName);
RemoveRegistryValue(runspace, ScreenSaverGpoKey, administratorsGpo); RemoveRegistryValue(runspace, ScreenSaverGpoKey, administratorsGpo);
@ -1329,6 +1333,13 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
} }
} }
private string CreateUsersPolicy(Runspace runspace, string organizationId, string gpoName, DirectoryEntry entry, DirectoryEntry collectionComputersEntry, string collectionName)
{
string gpoId = CreatePolicy(runspace, organizationId, gpoName, entry, collectionComputersEntry, collectionName);
ExcludeAdminsFromUsersPolicy(runspace, gpoId, collectionName);
return gpoId;
}
private string CreatePolicy(Runspace runspace, string organizationId, string gpoName, DirectoryEntry entry, DirectoryEntry collectionComputersEntry, string collectionName) private string CreatePolicy(Runspace runspace, string organizationId, string gpoName, DirectoryEntry entry, DirectoryEntry collectionComputersEntry, string collectionName)
{ {
string gpoId = GetPolicyId(runspace, gpoName); string gpoId = GetPolicyId(runspace, gpoName);
@ -1360,6 +1371,22 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
Collection<PSObject> result = ExecuteRemoteShellCommand(runspace, PrimaryDomainController, cmd); Collection<PSObject> result = ExecuteRemoteShellCommand(runspace, PrimaryDomainController, cmd);
} }
private void ExcludeAdminsFromUsersPolicy(Runspace runspace, string gpoId, string collectionName)
{
var scripts = new List<string>
{
string.Format("$adgpo = [ADSI]\"{0}\"", GetGpoPath(gpoId)),
string.Format("$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule([System.Security.Principal.NTAccount]\"{0}\\{1}\",\"ExtendedRight\",\"Deny\",[GUID]\"edacfd8f-ffb3-11d1-b41d-00a0c968f939\")",
RootDomain.Split('.').First(), GetLocalAdminsGroupName(collectionName)),
string.Format("$acl = $adgpo.ObjectSecurity"),
string.Format("$acl.AddAccessRule($rule)"),
string.Format("$adgpo.CommitChanges()")
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, PrimaryDomainController, scripts, out errors);
}
private void SetPolicyPermissions(Runspace runspace, string gpoName, DirectoryEntry entry, DirectoryEntry collectionComputersEntry) private void SetPolicyPermissions(Runspace runspace, string gpoName, DirectoryEntry entry, DirectoryEntry collectionComputersEntry)
{ {
var scripts = new List<string> var scripts = new List<string>
@ -1752,7 +1779,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
string collectionComputersPath = GetComputerGroupPath(organizationId, collection.Name); string collectionComputersPath = GetComputerGroupPath(organizationId, collection.Name);
CreatePolicy(runSpace, organizationId, string.Format("{0}-administrators", collection.Name), CreatePolicy(runSpace, organizationId, string.Format("{0}-administrators", collection.Name),
new DirectoryEntry(GetGroupPath(organizationId, collection.Name, GetLocalAdminsGroupName(collection.Name))), new DirectoryEntry(collectionComputersPath), collection.Name); new DirectoryEntry(GetGroupPath(organizationId, collection.Name, GetLocalAdminsGroupName(collection.Name))), new DirectoryEntry(collectionComputersPath), collection.Name);
CreatePolicy(runSpace, organizationId, string.Format("{0}-users", collection.Name), new DirectoryEntry(GetUsersGroupPath(organizationId, collection.Name)) CreateUsersPolicy(runSpace, organizationId, string.Format("{0}-users", collection.Name), new DirectoryEntry(GetUsersGroupPath(organizationId, collection.Name))
, new DirectoryEntry(collectionComputersPath), collection.Name); , new DirectoryEntry(collectionComputersPath), collection.Name);
CreateHelpDeskPolicy(runSpace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collection.Name); CreateHelpDeskPolicy(runSpace, new DirectoryEntry(GetHelpDeskGroupPath(RDSHelpDeskGroup)), new DirectoryEntry(collectionComputersPath), organizationId, collection.Name);
@ -2434,6 +2461,19 @@ namespace WebsitePanel.Providers.RemoteDesktopServices
return sb.ToString(); return sb.ToString();
} }
private string GetGpoPath(string gpoId)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendCNPath(sb, gpoId);
AppendCNPath(sb, "Policies");
AppendCNPath(sb, "System");
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
internal string GetTenantComputerGroupPath(string organizationId) internal string GetTenantComputerGroupPath(string organizationId)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();

View file

@ -33,6 +33,7 @@ using System.Web.Services.Protocols;
using System.Collections.Generic; using System.Collections.Generic;
using WebsitePanel.Providers; using WebsitePanel.Providers;
using WebsitePanel.Providers.HostedSolution; using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.ResultObjects;
using WebsitePanel.Server.Utils; using WebsitePanel.Server.Utils;
using Microsoft.Web.Services3; using Microsoft.Web.Services3;
using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Common;
@ -1389,6 +1390,46 @@ namespace WebsitePanel.Server
#endregion #endregion
#region Picture
[WebMethod, SoapHeader("settings")]
public ResultObject SetPicture(string accountName, byte[] picture)
{
ResultObject res = null;
try
{
LogStart("SetPicture");
res = ES.SetPicture(accountName, picture);
LogEnd("SetPicture");
}
catch (Exception ex)
{
LogError("SetPicture", ex);
throw;
}
return res;
}
[WebMethod, SoapHeader("settings")]
public BytesResult GetPicture(string accountName)
{
BytesResult res = null;
try
{
LogStart("GetPicture");
res = ES.GetPicture(accountName);
LogEnd("SetPicture");
}
catch (Exception ex)
{
LogError("GetPicture", ex);
throw;
}
return res;
}
#endregion
protected void LogStart(string func) protected void LogStart(string func)
{ {
Log.WriteStart("'{0}' {1}", ProviderSettings.ProviderName, func); Log.WriteStart("'{0}' {1}", ProviderSettings.ProviderName, func);

View file

@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using WebsitePanel.EnterpriseServer;
using WebsitePanel.WebDavPortal.WebConfigSections; using WebsitePanel.WebDavPortal.WebConfigSections;
namespace WebsitePanel.WebDav.Core.Config.Entities namespace WebsitePanel.WebDav.Core.Config.Entities
@ -11,15 +12,30 @@ namespace WebsitePanel.WebDav.Core.Config.Entities
public OfficeOnlineCollection() public OfficeOnlineCollection()
{ {
IsEnabled = ConfigSection.OfficeOnline.IsEnabled;
Url = ConfigSection.OfficeOnline.Url;
NewFilePath = ConfigSection.OfficeOnline.CobaltNewFilePath; NewFilePath = ConfigSection.OfficeOnline.CobaltNewFilePath;
CobaltFileTtl = ConfigSection.OfficeOnline.CobaltFileTtl; CobaltFileTtl = ConfigSection.OfficeOnline.CobaltFileTtl;
_officeExtensions = ConfigSection.OfficeOnline.Cast<OfficeOnlineElement>().ToList(); _officeExtensions = ConfigSection.OfficeOnline.Cast<OfficeOnlineElement>().ToList();
} }
public bool IsEnabled { get; private set; } public bool IsEnabled {
public string Url { get; private set; } get
{
return GetWebdavSystemSettigns().GetValueOrDefault(EnterpriseServer.SystemSettings.WEBDAV_OWA_ENABLED_KEY, false);
}
}
public string Url
{
get
{
return GetWebdavSystemSettigns().GetValueOrDefault(EnterpriseServer.SystemSettings.WEBDAV_OWA_URL, string.Empty);
}
}
private SystemSettings GetWebdavSystemSettigns()
{
return WspContext.Services.Organizations.GetWebDavSystemSettings() ?? new SystemSettings();
}
public string NewFilePath { get; private set; } public string NewFilePath { get; private set; }
public int CobaltFileTtl { get; private set; } public int CobaltFileTtl { get; private set; }

View file

@ -6,25 +6,9 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections
[ConfigurationCollection(typeof(OfficeOnlineElement))] [ConfigurationCollection(typeof(OfficeOnlineElement))]
public class OfficeOnlineElementCollection : ConfigurationElementCollection public class OfficeOnlineElementCollection : ConfigurationElementCollection
{ {
private const string UrlKey = "url";
private const string IsEnabledKey = "isEnabled";
private const string CobaltFileTtlKey = "cobaltFileTtl"; private const string CobaltFileTtlKey = "cobaltFileTtl";
private const string CobaltNewFilePathKey = "cobaltNewFilePath"; private const string CobaltNewFilePathKey = "cobaltNewFilePath";
[ConfigurationProperty(UrlKey, IsKey = true, IsRequired = true)]
public string Url
{
get { return this[UrlKey].ToString(); }
set { this[UrlKey] = value; }
}
[ConfigurationProperty(IsEnabledKey, IsKey = true, IsRequired = true, DefaultValue = false)]
public bool IsEnabled
{
get { return Boolean.Parse(this[IsEnabledKey].ToString()); }
set { this[IsEnabledKey] = value; }
}
[ConfigurationProperty(CobaltNewFilePathKey, IsKey = true, IsRequired = true)] [ConfigurationProperty(CobaltNewFilePathKey, IsKey = true, IsRequired = true)]
public string CobaltNewFilePath public string CobaltNewFilePath
{ {

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
@ -15,18 +16,23 @@ namespace WebsitePanel.WebDavPortal.FileOperations
{ {
public class FileOpenerManager public class FileOpenerManager
{ {
private readonly IDictionary<string, FileOpenerType> _officeOperationTypes = new Dictionary<string, FileOpenerType>();
private readonly IDictionary<string, FileOpenerType> _operationTypes = new Dictionary<string, FileOpenerType>(); private readonly IDictionary<string, FileOpenerType> _operationTypes = new Dictionary<string, FileOpenerType>();
public FileOpenerManager() private readonly Lazy<IDictionary<string, FileOpenerType>> _officeOperationTypes = new Lazy<IDictionary<string, FileOpenerType>>(
() =>
{ {
if (WebDavAppConfigManager.Instance.OfficeOnline.IsEnabled) if (WebDavAppConfigManager.Instance.OfficeOnline.IsEnabled)
{ {
_officeOperationTypes.AddRange( return
WebDavAppConfigManager.Instance.OfficeOnline.ToDictionary(x => x.Extension, WebDavAppConfigManager.Instance.OfficeOnline.ToDictionary(x => x.Extension,
y => FileOpenerType.OfficeOnline)); y => FileOpenerType.OfficeOnline);
} }
return new Dictionary<string, FileOpenerType>();
});
public FileOpenerManager()
{
_operationTypes.AddRange( _operationTypes.AddRange(
WebDavAppConfigManager.Instance.FileOpener.ToDictionary(x => x.Extension, WebDavAppConfigManager.Instance.FileOpener.ToDictionary(x => x.Extension,
y => FileOpenerType.Open)); y => FileOpenerType.Open));
@ -94,7 +100,7 @@ namespace WebsitePanel.WebDavPortal.FileOperations
get get
{ {
FileOpenerType result; FileOpenerType result;
if (_officeOperationTypes.TryGetValue(fileExtension, out result) && CheckBrowserSupport()) if (_officeOperationTypes.Value.TryGetValue(fileExtension, out result) && CheckBrowserSupport())
{ {
return result; return result;
} }

View file

@ -87,7 +87,7 @@
<add browser="InternetExplorer;IE" version="8" /> <add browser="InternetExplorer;IE" version="8" />
<add browser="Safari" version="4" /> <add browser="Safari" version="4" />
</owaSupportedBrowsers> </owaSupportedBrowsers>
<officeOnline isEnabled="True" url="https://owa.websitepanel.net" cobaltFileTtl="1" cobaltNewFilePath="~/Content/OwaFiles/New"> <officeOnline cobaltFileTtl="1" cobaltNewFilePath="~/Content/OwaFiles/New">
<add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" /> <add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" />
<add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" /> <add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" />
<add extension=".xls" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?new=1&amp;" /> <add extension=".xls" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?new=1&amp;" />

View file

@ -5862,6 +5862,9 @@
<data name="ERROR.RDSLOCALADMINS_NOT_ADDED" xml:space="preserve"> <data name="ERROR.RDSLOCALADMINS_NOT_ADDED" xml:space="preserve">
<value>Local admins not added</value> <value>Local admins not added</value>
</data> </data>
<data name="ERROR.RDS_USERS_NOT_DELETED" xml:space="preserve">
<value>Unable to remove the following user(s) since they are local admins or they were granted access to remote applications:</value>
</data>
<data name="ERROR.REMOTE_DESKTOP_SERVICES_LOG_OFF_USER" xml:space="preserve"> <data name="ERROR.REMOTE_DESKTOP_SERVICES_LOG_OFF_USER" xml:space="preserve">
<value>RDS User logging off error</value> <value>RDS User logging off error</value>
</data> </data>

View file

@ -195,4 +195,16 @@
<data name="lblPasswordResetLinkLifeSpan.Text" xml:space="preserve"> <data name="lblPasswordResetLinkLifeSpan.Text" xml:space="preserve">
<value>Password Reset Link Life Span (hours):</value> <value>Password Reset Link Life Span (hours):</value>
</data> </data>
<data name="OwaSettings.Text" xml:space="preserve">
<value>Office Web Apps</value>
</data>
<data name="locEnableOwa.Text" xml:space="preserve">
<value>Enable OWA:</value>
</data>
<data name="chkEnableOwa.Text" xml:space="preserve">
<value>Yes</value>
</data>
<data name="locOwaUrl.Text" xml:space="preserve">
<value>OWA URL:</value>
</data>
</root> </root>

View file

@ -38,6 +38,9 @@
<uc1:MailboxTabs ID="MailboxTabsId" runat="server" SelectedTab="edit_user" /> <uc1:MailboxTabs ID="MailboxTabsId" runat="server" SelectedTab="edit_user" />
<wsp:SimpleMessageBox id="messageBox" runat="server" /> <wsp:SimpleMessageBox id="messageBox" runat="server" />
<table>
<tr>
<td>
<table> <table>
<tr> <tr>
<td class="FormLabel150"> <asp:Localize ID="locUserPrincipalName" runat="server" meta:resourcekey="locUserPrincipalName" Text="Login Name:"></asp:Localize></td> <td class="FormLabel150"> <asp:Localize ID="locUserPrincipalName" runat="server" meta:resourcekey="locUserPrincipalName" Text="Login Name:"></asp:Localize></td>
@ -115,6 +118,27 @@
</tr> </tr>
</table> </table>
</td>
<td>
<asp:Panel ID="pnlThumbnailphoto" runat="server" HorizontalAlign="Right" Width="200px">
<div class="FormLabel150">
<asp:Localize ID="locThumbnailphoto" runat="server" meta:resourcekey="locThumbnailphoto" Text="Thumbnail photo:"></asp:Localize>
</div>
<asp:Image ID="imgThumbnailphoto" runat="server" />
<br />
<asp:FileUpload ID="upThumbnailphoto" ClientIDMode="Static" runat="server" Style="display: none;"
onchange="__doPostBack('<%= btnLoadThumbnailphoto.ClientID %>', '')" />
<asp:Button ID="btnLoadThumbnailphoto" runat="server" meta:resourcekey="btnLoadThumbnailphoto"
CssClass="CommandButton" Text="Load"
OnClientClick="$('#upThumbnailphoto').click(); return false;" />
<asp:Button ID="btnClearThumbnailphoto" runat="server" meta:resourcekey="btnClearThumbnailphoto"
CssClass="CommandButton" Text="Clear"
OnClick="btnClearThumbnailphoto_Click" />
</asp:Panel>
</td>
</tr>
</table>
<table> <table>
<tr> <tr>
<td class="FormLabel150"><asp:Localize ID="locNotes" runat="server" meta:resourcekey="locNotes" Text="Notes:"></asp:Localize></td> <td class="FormLabel150"><asp:Localize ID="locNotes" runat="server" meta:resourcekey="locNotes" Text="Notes:"></asp:Localize></td>
@ -283,8 +307,6 @@
</table> </table>
</asp:Panel> </asp:Panel>
<div class="FormFooterClean"> <div class="FormFooterClean">
<wsp:ItemButtonPanel id="buttonPanel" runat="server" ValidationGroup="EditMailbox" <wsp:ItemButtonPanel id="buttonPanel" runat="server" ValidationGroup="EditMailbox"
OnSaveClick="btnSave_Click" OnSaveExitClick="btnSaveExit_Click" /> OnSaveClick="btnSave_Click" OnSaveExitClick="btnSaveExit_Click" />
@ -293,6 +315,7 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -33,6 +33,7 @@ using System.Web.UI.WebControls;
using WebsitePanel.EnterpriseServer; using WebsitePanel.EnterpriseServer;
using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.EnterpriseServer.Base.HostedSolution;
using WebsitePanel.Providers.HostedSolution; using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.ResultObjects; using WebsitePanel.Providers.ResultObjects;
namespace WebsitePanel.Portal.HostedSolution namespace WebsitePanel.Portal.HostedSolution
@ -47,12 +48,45 @@ namespace WebsitePanel.Portal.HostedSolution
BindSettings(); BindSettings();
BindPicture();
MailboxTabsId.Visible = (PanelRequest.Context == "Mailbox"); MailboxTabsId.Visible = (PanelRequest.Context == "Mailbox");
UserTabsId.Visible = (PanelRequest.Context == "User"); UserTabsId.Visible = (PanelRequest.Context == "User");
if (GetLocalizedString("buttonPanel.OnSaveClientClick") != null) if (GetLocalizedString("buttonPanel.OnSaveClientClick") != null)
buttonPanel.OnSaveClientClick = GetLocalizedString("buttonPanel.OnSaveClientClick"); buttonPanel.OnSaveClientClick = GetLocalizedString("buttonPanel.OnSaveClientClick");
} }
else
{
if (upThumbnailphoto.HasFile)
SavePicture(upThumbnailphoto.FileBytes);
}
}
private void BindPicture()
{
try
{
// get settings
OrganizationUser user = ES.Services.Organizations.GetUserGeneralSettings(PanelRequest.ItemID,
PanelRequest.AccountID);
if ((user.AccountType== ExchangeAccountType.Mailbox) ||
(user.AccountType== ExchangeAccountType.Room) ||
(user.AccountType== ExchangeAccountType.SharedMailbox) ||
(user.AccountType== ExchangeAccountType.Equipment))
{
imgThumbnailphoto.Visible = true;
imgThumbnailphoto.ImageUrl = "~/DesktopModules/WebsitePanel/ThumbnailPhoto.ashx" + "?" + "ItemID=" + PanelRequest.ItemID +
"&AccountID=" + PanelRequest.AccountID;
}
else
{
imgThumbnailphoto.Visible = false;
}
}
catch { } // skip
} }
private void BindSettings() private void BindSettings()
@ -450,5 +484,35 @@ namespace WebsitePanel.Portal.HostedSolution
"Context=" + ((PanelRequest.Context == "Mailbox") ? "Mailbox" : "User"), "Context=" + ((PanelRequest.Context == "Mailbox") ? "Mailbox" : "User"),
"AccountID=" + PanelRequest.AccountID)); "AccountID=" + PanelRequest.AccountID));
} }
private void SavePicture(byte[] picture)
{
try
{
ResultObject result = ES.Services.ExchangeServer.SetPicture(
PanelRequest.ItemID, PanelRequest.AccountID,
picture);
if (!result.IsSuccess)
{
messageBox.ShowErrorMessage("ORGANIZATION_UPDATE_USER_SETTINGS");
return;
}
messageBox.ShowSuccessMessage("ORGANIZATION_UPDATE_USER_SETTINGS");
}
catch (Exception ex)
{
messageBox.ShowErrorMessage("ORGANIZATION_UPDATE_USER_SETTINGS", ex);
}
BindPicture();
}
protected void btnClearThumbnailphoto_Click(object sender, EventArgs e)
{
SavePicture(null);
}
} }
} }

View file

@ -336,6 +336,60 @@ namespace WebsitePanel.Portal.HostedSolution {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtExternalEmailAddress; protected global::System.Web.UI.WebControls.TextBox txtExternalEmailAddress;
/// <summary>
/// pnlThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel pnlThumbnailphoto;
/// <summary>
/// locThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locThumbnailphoto;
/// <summary>
/// imgThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Image imgThumbnailphoto;
/// <summary>
/// upThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.FileUpload upThumbnailphoto;
/// <summary>
/// btnLoadThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnLoadThumbnailphoto;
/// <summary>
/// btnClearThumbnailphoto control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnClearThumbnailphoto;
/// <summary> /// <summary>
/// locNotes control. /// locNotes control.
/// </summary> /// </summary>

View file

@ -10,7 +10,7 @@
<wsp:EnableAsyncTasksSupport id="asyncTasks" runat="server"/> <wsp:EnableAsyncTasksSupport id="asyncTasks" runat="server"/>
<div id="ExchangeContainer"> <div id="ExchangeContainer">
<div class="Module"> <div class="Module">
<div class="Left"> <div class="Left">
</div> </div>
@ -23,13 +23,15 @@
<asp:Literal ID="litCollectionName" runat="server" Text="" /> <asp:Literal ID="litCollectionName" runat="server" Text="" />
</div> </div>
<div class="FormContentRDS"> <div class="FormContentRDS">
<asp:UpdatePanel runat="server" ID="messageUpdatePanel">
<ContentTemplate>
<wsp:SimpleMessageBox id="messageBox" runat="server" /> <wsp:SimpleMessageBox id="messageBox" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<wsp:CollectionTabs id="tabs" runat="server" SelectedTab="rds_collection_edit_users" /> <wsp:CollectionTabs id="tabs" runat="server" SelectedTab="rds_collection_edit_users" />
<wsp:CollapsiblePanel id="secRdsUsers" runat="server" <wsp:CollapsiblePanel id="secRdsUsers" runat="server"
TargetControlID="panelRdsUsers" meta:resourcekey="secRdsUsers" Text=""> TargetControlID="panelRdsUsers" meta:resourcekey="secRdsUsers" Text="">
</wsp:CollapsiblePanel> </wsp:CollapsiblePanel>
<asp:Panel runat="server" ID="panelRdsUsers"> <asp:Panel runat="server" ID="panelRdsUsers">
<div style="padding: 10px;"> <div style="padding: 10px;">
<wsp:CollectionUsers id="users" runat="server" /> <wsp:CollectionUsers id="users" runat="server" />
@ -48,4 +50,4 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -26,7 +26,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using AjaxControlToolkit;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web.UI.WebControls; using System.Web.UI.WebControls;
using WebsitePanel.EnterpriseServer; using WebsitePanel.EnterpriseServer;
@ -42,28 +44,15 @@ namespace WebsitePanel.Portal.RDS
protected void Page_Load(object sender, EventArgs e) protected void Page_Load(object sender, EventArgs e)
{ {
users.Module = Module; users.Module = Module;
users.OnRefreshClicked -= OnRefreshClicked;
users.OnRefreshClicked += OnRefreshClicked;
if (!IsPostBack) if (!IsPostBack)
{ {
BindQuota();
var collectionUsers = ES.Services.RDS.GetRdsCollectionUsers(PanelRequest.CollectionID);
var collection = ES.Services.RDS.GetRdsCollection(PanelRequest.CollectionID); var collection = ES.Services.RDS.GetRdsCollection(PanelRequest.CollectionID);
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
foreach (var user in collectionUsers)
{
if (localAdmins.Select(l => l.AccountName).Contains(user.AccountName))
{
user.IsVIP = true;
}
else
{
user.IsVIP = false;
}
}
litCollectionName.Text = collection.DisplayName; litCollectionName.Text = collection.DisplayName;
users.SetUsers(collectionUsers); BindQuota();
users.BindUsers();
} }
} }
@ -87,6 +76,17 @@ namespace WebsitePanel.Portal.RDS
} }
} }
private void OnRefreshClicked(object sender, EventArgs e)
{
((ModalPopupExtender)asyncTasks.FindControl("ModalPopupProperties")).Hide();
var users = (List<string>)sender;
if (users.Any())
{
messageBox.ShowErrorMessage("RDS_USERS_NOT_DELETED", new Exception(string.Join(", ", users)));
}
}
private bool SaveRdsUsers() private bool SaveRdsUsers()
{ {
try try

View file

@ -48,6 +48,15 @@ namespace WebsitePanel.Portal.RDS {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.Literal litCollectionName; protected global::System.Web.UI.WebControls.Literal litCollectionName;
/// <summary>
/// messageUpdatePanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.UpdatePanel messageUpdatePanel;
/// <summary> /// <summary>
/// messageBox control. /// messageBox control.
/// </summary> /// </summary>

View file

@ -126,6 +126,9 @@
<data name="btnCancel.Text" xml:space="preserve"> <data name="btnCancel.Text" xml:space="preserve">
<value>Cancel</value> <value>Cancel</value>
</data> </data>
<data name="btnCancelDeleteWarning.Text" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="btnDelete.Text" xml:space="preserve"> <data name="btnDelete.Text" xml:space="preserve">
<value>Delete</value> <value>Delete</value>
</data> </data>
@ -153,4 +156,10 @@
<data name="headerAddAccounts.Text" xml:space="preserve"> <data name="headerAddAccounts.Text" xml:space="preserve">
<value>Enabled Users</value> <value>Enabled Users</value>
</data> </data>
<data name="headerDeleteWarning.Text" xml:space="preserve">
<value>Warning</value>
</data>
<data name="locDeleteWarning.Text" xml:space="preserve">
<value>Unable to remove the following user(s) since they are local admins&lt;br/&gt;or they were granted access to remote applications</value>
</data>
</root> </root>

View file

@ -5,7 +5,7 @@
<ContentTemplate> <ContentTemplate>
<div class="FormButtonsBarClean"> <div class="FormButtonsBarClean">
<asp:Button ID="btnAdd" runat="server" Text="Add..." CssClass="Button1" OnClick="btnAdd_Click" meta:resourcekey="btnAdd" /> <asp:Button ID="btnAdd" runat="server" Text="Add..." CssClass="Button1" OnClick="btnAdd_Click" meta:resourcekey="btnAdd" />
<asp:Button ID="btnDelete" runat="server" Text="Delete" CssClass="Button1" OnClick="btnDelete_Click" meta:resourcekey="btnDelete"/> <asp:Button ID="btnDelete" runat="server" Text="Delete" CssClass="Button1" OnClick="btnDelete_Click" OnClientClick="ShowProgressDialog('Checking users ...');return true;" meta:resourcekey="btnDelete"/>
</div> </div>
<asp:GridView ID="gvUsers" runat="server" meta:resourcekey="gvUsers" AutoGenerateColumns="False" <asp:GridView ID="gvUsers" runat="server" meta:resourcekey="gvUsers" AutoGenerateColumns="False"
Width="600px" CssSelectorClass="NormalGridView" OnRowCommand="gvUsers_RowCommand" Width="600px" CssSelectorClass="NormalGridView" OnRowCommand="gvUsers_RowCommand"
@ -113,6 +113,41 @@
</div> </div>
</asp:Panel> </asp:Panel>
<asp:Panel ID="DeleteWarningPanel" runat="server" CssClass="Popup" style="display:none">
<table class="Popup-Header" cellpadding="0" cellspacing="0">
<tr>
<td class="Popup-HeaderLeft"/>
<td class="Popup-HeaderTitle">
<asp:Localize ID="lcDeleteWarningHeader" runat="server" meta:resourcekey="headerDeleteWarning"></asp:Localize>
</td>
<td class="Popup-HeaderRight"/>
</tr>
</table>
<div class="Popup-Content">
<div class="Popup-Body">
<br />
<asp:UpdatePanel ID="deleteWarningUpdatePanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="Popup-Scroll" style="height:auto;">
<asp:Panel runat="server" ID="panelDeleteWarning">
<asp:Localize runat="server" ID="locDeleteWarning" Text="Unable to remove the following user(s) since they are local admins or<br/>they were granted access to remote applications" />
<br/>
<asp:Literal runat="server" ID="ltUsers" Text="" />
</asp:Panel>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<br />
</div>
<div class="FormFooter">
<asp:Button ID="btnCancelDeleteWarning" runat="server" CssClass="Button1" meta:resourcekey="btnCancelDeleteWarning" Text="Cancel" CausesValidation="false" />
</div>
</div>
</asp:Panel>
<asp:Button ID="btnDeleteWarningFake" runat="server" style="display:none;" />
<ajaxToolkit:ModalPopupExtender ID="DeleteWarningModal" runat="server" TargetControlID="btnDeleteWarningFake" PopupControlID="DeleteWarningPanel"
BackgroundCssClass="modalBackground" DropShadow="false" CancelControlID="btnCancelDeleteWarning"/>
<asp:Button ID="btnAddAccountsFake" runat="server" style="display:none;" /> <asp:Button ID="btnAddAccountsFake" runat="server" style="display:none;" />
<ajaxToolkit:ModalPopupExtender ID="AddAccountsModal" runat="server" <ajaxToolkit:ModalPopupExtender ID="AddAccountsModal" runat="server"
TargetControlID="btnAddAccountsFake" PopupControlID="AddAccountsPanel" TargetControlID="btnAddAccountsFake" PopupControlID="AddAccountsPanel"

View file

@ -41,6 +41,7 @@ namespace WebsitePanel.Portal.RDS.UserControls
public partial class RDSCollectionUsers : WebsitePanelControlBase public partial class RDSCollectionUsers : WebsitePanelControlBase
{ {
public const string DirectionString = "DirectionString"; public const string DirectionString = "DirectionString";
public event EventHandler OnRefreshClicked;
public bool ButtonAddEnabled public bool ButtonAddEnabled
{ {
@ -100,11 +101,28 @@ namespace WebsitePanel.Portal.RDS.UserControls
protected void btnDelete_Click(object sender, EventArgs e) protected void btnDelete_Click(object sender, EventArgs e)
{ {
List<OrganizationUser> selectedAccounts = GetGridViewUsers(SelectedState.Unselected); if (PanelRequest.Ctl == "rds_collection_edit_users")
{
var lockedUsers = CheckDeletedUsers();
if (!lockedUsers.Any())
{
List<OrganizationUser> selectedAccounts = GetGridViewUsers(SelectedState.Unselected);
BindAccounts(selectedAccounts.ToArray(), false); BindAccounts(selectedAccounts.ToArray(), false);
} }
if (OnRefreshClicked != null)
{
OnRefreshClicked(lockedUsers, new EventArgs());
}
}
else
{
List<OrganizationUser> selectedAccounts = GetGridViewUsers(SelectedState.Unselected);
BindAccounts(selectedAccounts.ToArray(), false);
}
}
protected void btnAddSelected_Click(object sender, EventArgs e) protected void btnAddSelected_Click(object sender, EventArgs e)
{ {
List<OrganizationUser> selectedAccounts = GetGridViewAccounts(); List<OrganizationUser> selectedAccounts = GetGridViewAccounts();
@ -134,9 +152,58 @@ namespace WebsitePanel.Portal.RDS.UserControls
return GetThemedImage("Exchange/" + imgName); return GetThemedImage("Exchange/" + imgName);
} }
public List<string> CheckDeletedUsers()
{
var rdsUsers = GetGridViewUsers(SelectedState.Selected);
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
var organizationUsers = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, null, null, null, 0, Int32.MaxValue).PageUsers;
var applicationUsers = ES.Services.RDS.GetApplicationUsers(PanelRequest.ItemID, PanelRequest.CollectionID, null);
var remoteAppUsers = organizationUsers.Where(x => applicationUsers.Select(a => a.Split('\\').Last().ToLower()).Contains(x.SamAccountName.Split('\\').Last().ToLower()));
var deletedUsers = new List<OrganizationUser>();
deletedUsers.AddRange(rdsUsers.Where(r => localAdmins.Select(l => l.AccountName.ToLower()).Contains(r.AccountName.ToLower())));
remoteAppUsers = remoteAppUsers.Where(r => !localAdmins.Select(l => l.AccountName.ToLower()).Contains(r.AccountName.ToLower()));
deletedUsers.AddRange(rdsUsers.Where(r => remoteAppUsers.Select(l => l.AccountName.ToLower()).Contains(r.AccountName.ToLower())));
deletedUsers = deletedUsers.Distinct().ToList();
return deletedUsers.Select(d => d.DisplayName).ToList();
}
public void BindUsers()
{
var collectionUsers = ES.Services.RDS.GetRdsCollectionUsers(PanelRequest.CollectionID);
var collection = ES.Services.RDS.GetRdsCollection(PanelRequest.CollectionID);
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
foreach (var user in collectionUsers)
{
if (localAdmins.Select(l => l.AccountName).Contains(user.AccountName))
{
user.IsVIP = true;
}
else
{
user.IsVIP = false;
}
}
SetUsers(collectionUsers);
}
protected void BindPopupAccounts() protected void BindPopupAccounts()
{ {
OrganizationUser[] accounts = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, null, null, null, 0, Int32.MaxValue).PageUsers; OrganizationUser[] accounts;
if (PanelRequest.Ctl == "rds_collection_edit_users")
{
accounts = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, null, null, null, 0, Int32.MaxValue).PageUsers;
}
else
{
accounts = ES.Services.RDS.GetRdsCollectionUsers(PanelRequest.CollectionID);
}
var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID); var localAdmins = ES.Services.RDS.GetRdsCollectionLocalAdmins(PanelRequest.CollectionID);
foreach (var user in accounts) foreach (var user in accounts)

View file

@ -138,6 +138,87 @@ namespace WebsitePanel.Portal.RDS.UserControls {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.Button btnCancelAdd; protected global::System.Web.UI.WebControls.Button btnCancelAdd;
/// <summary>
/// DeleteWarningPanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel DeleteWarningPanel;
/// <summary>
/// lcDeleteWarningHeader control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize lcDeleteWarningHeader;
/// <summary>
/// deleteWarningUpdatePanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.UpdatePanel deleteWarningUpdatePanel;
/// <summary>
/// panelDeleteWarning control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel panelDeleteWarning;
/// <summary>
/// locDeleteWarning control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locDeleteWarning;
/// <summary>
/// ltUsers control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal ltUsers;
/// <summary>
/// btnCancelDeleteWarning control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnCancelDeleteWarning;
/// <summary>
/// btnDeleteWarningFake control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnDeleteWarningFake;
/// <summary>
/// DeleteWarningModal control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::AjaxControlToolkit.ModalPopupExtender DeleteWarningModal;
/// <summary> /// <summary>
/// btnAddAccountsFake control. /// btnAddAccountsFake control.
/// </summary> /// </summary>

View file

@ -104,6 +104,22 @@
</table> </table>
</asp:Panel> </asp:Panel>
<wsp:CollapsiblePanel ID="OwaSettings" runat="server" TargetControlID="PanelOwaSettings" meta:resourcekey="OwaSettings" Text="Office Web Apps" />
<asp:Panel ID="PanelOwaSettings" runat="server" Height="0" style="overflow:hidden;">
<table>
<tr>
<td class="SubHead"><asp:Localize ID="locEnableOwa" runat="server" meta:resourcekey="locEnableOwa" /></td>
<td class="Normal">
<asp:CheckBox ID="chkEnableOwa" runat="server" Text="Yes" meta:resourcekey="chkEnableOwa" />
</td>
</tr>
<tr>
<td class="SubHead" style="width:200px;"><asp:Localize ID="locOwaUrl" runat="server" meta:resourcekey="locOwaUrl" />
<td><asp:TextBox runat="server" ID="txtOwaUrl" Width="450px" /></td>
</tr>
</table>
</asp:Panel>
<wsp:CollapsiblePanel ID="TwilioSettings" runat="server" TargetControlID="PanelTwilioSettings" meta:resourcekey="TwilioSettings" Text="Webdav Portal" /> <wsp:CollapsiblePanel ID="TwilioSettings" runat="server" TargetControlID="PanelTwilioSettings" meta:resourcekey="TwilioSettings" Text="Webdav Portal" />
<asp:Panel ID="PanelTwilioSettings" runat="server" Height="0" style="overflow:hidden;"> <asp:Panel ID="PanelTwilioSettings" runat="server" Height="0" style="overflow:hidden;">
<table> <table>

View file

@ -167,6 +167,9 @@ namespace WebsitePanel.Portal
chkEnablePasswordReset.Checked = Utils.ParseBool(settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_ENABLED_KEY], false); chkEnablePasswordReset.Checked = Utils.ParseBool(settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_ENABLED_KEY], false);
txtWebdavPortalUrl.Text = settings[WEBDAV_PORTAL_URL]; txtWebdavPortalUrl.Text = settings[WEBDAV_PORTAL_URL];
txtPasswordResetLinkLifeSpan.Text = settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN]; txtPasswordResetLinkLifeSpan.Text = settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN];
chkEnableOwa.Checked = Utils.ParseBool(settings[WSP.SystemSettings.WEBDAV_OWA_ENABLED_KEY], false);
txtOwaUrl.Text = settings[WSP.SystemSettings.WEBDAV_OWA_URL];
} }
// Twilio portal // Twilio portal
@ -264,6 +267,10 @@ namespace WebsitePanel.Portal
settings[WEBDAV_PORTAL_URL] = txtWebdavPortalUrl.Text; settings[WEBDAV_PORTAL_URL] = txtWebdavPortalUrl.Text;
settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_ENABLED_KEY] = chkEnablePasswordReset.Checked.ToString(); settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_ENABLED_KEY] = chkEnablePasswordReset.Checked.ToString();
settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN] = txtPasswordResetLinkLifeSpan.Text; settings[WSP.SystemSettings.WEBDAV_PASSWORD_RESET_LINK_LIFE_SPAN] = txtPasswordResetLinkLifeSpan.Text;
settings[WSP.SystemSettings.WEBDAV_OWA_ENABLED_KEY] = chkEnableOwa.Checked.ToString();
settings[WSP.SystemSettings.WEBDAV_OWA_URL] = txtOwaUrl.Text;
result = ES.Services.System.SetSystemSettings(WSP.SystemSettings.WEBDAV_PORTAL_SETTINGS, settings); result = ES.Services.System.SetSystemSettings(WSP.SystemSettings.WEBDAV_PORTAL_SETTINGS, settings);
if (result < 0) if (result < 0)

View file

@ -300,6 +300,60 @@ namespace WebsitePanel.Portal {
/// </remarks> /// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtWebdavPortalUrl; protected global::System.Web.UI.WebControls.TextBox txtWebdavPortalUrl;
/// <summary>
/// OwaSettings control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::WebsitePanel.Portal.CollapsiblePanel OwaSettings;
/// <summary>
/// PanelOwaSettings control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel PanelOwaSettings;
/// <summary>
/// locEnableOwa control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locEnableOwa;
/// <summary>
/// chkEnableOwa control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.CheckBox chkEnableOwa;
/// <summary>
/// locOwaUrl control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Localize locOwaUrl;
/// <summary>
/// txtOwaUrl control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.TextBox txtOwaUrl;
/// <summary> /// <summary>
/// TwilioSettings control. /// TwilioSettings control.
/// </summary> /// </summary>

View file

@ -0,0 +1 @@
<%@ WebHandler Language="C#" CodeBehind="ThumbnailPhoto.ashx.cs" Class="WebsitePanel.Portal.ThumbnailPhoto" %>

View file

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebsitePanel.EnterpriseServer;
using WebsitePanel.EnterpriseServer.Base.HostedSolution;
using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Providers.Common;
using WebsitePanel.Providers.ResultObjects;
namespace WebsitePanel.Portal
{
/// <summary>
/// Summary description for ThumbnailPhoto
/// </summary>
public class ThumbnailPhoto : IHttpHandler
{
public HttpContext Context = null;
public int Param(string key)
{
string val = Context.Request.QueryString[key];
if (val == null)
{
val = Context.Request.Form[key];
if (val == null) return 0;
}
int res = 0;
int.TryParse(val, out res);
return res;
}
public void ProcessRequest(HttpContext context)
{
Context = context;
int ItemID = Param("ItemID");
int AccountID = Param("AccountID");
BytesResult res = ES.Services.ExchangeServer.GetPicture(ItemID, AccountID);
if (res.IsSuccess)
{
context.Response.ContentType = "image/jpeg";
context.Response.BinaryWrite(res.Value);
}
else
{
context.Response.Redirect(PortalUtils.GetThemedImage("empty.gif"), true);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}

View file

@ -346,6 +346,9 @@
<Compile Include="SettingsUserPasswordRequestLetter.ascx.designer.cs"> <Compile Include="SettingsUserPasswordRequestLetter.ascx.designer.cs">
<DependentUpon>SettingsUserPasswordRequestLetter.ascx</DependentUpon> <DependentUpon>SettingsUserPasswordRequestLetter.ascx</DependentUpon>
</Compile> </Compile>
<Compile Include="ThumbnailPhoto.ashx.cs">
<DependentUpon>ThumbnailPhoto.ashx</DependentUpon>
</Compile>
<Compile Include="UserControls\SendToControl.ascx.cs"> <Compile Include="UserControls\SendToControl.ascx.cs">
<DependentUpon>SendToControl.ascx</DependentUpon> <DependentUpon>SendToControl.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType> <SubType>ASPXCodeBehind</SubType>
@ -7509,6 +7512,7 @@
<Content Include="VPSForPC\VirtualMachineSnapshotImage.ashx" /> <Content Include="VPSForPC\VirtualMachineSnapshotImage.ashx" />
<Content Include="VPS2012\VirtualMachineImage.ashx" /> <Content Include="VPS2012\VirtualMachineImage.ashx" />
<Content Include="VPS2012\VirtualMachineSnapshotImage.ashx" /> <Content Include="VPS2012\VirtualMachineSnapshotImage.ashx" />
<Content Include="ThumbnailPhoto.ashx" />
<None Include="Web.config"> <None Include="Web.config">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>