DocSpace-buildtools/products/ASC.Calendar/Server/Controllers/CalendarController.cs

4789 lines
220 KiB
C#
Raw Normal View History

2020-02-12 07:58:31 +00:00

using System.Collections.Generic;
using ASC.Api.Core;
using ASC.Common.Logging;
using ASC.Common.Utils;
using ASC.Core;
using ASC.Core.Common.Settings;
using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.Data.Reassigns;
using ASC.FederatedLogin;
using ASC.MessagingSystem;
using ASC.Calendar.Models;
using ASC.Security.Cryptography;
using ASC.Web.Api.Routing;
using ASC.Web.Core;
using ASC.Web.Core.Users;
using ASC.Web.Studio.Core;
using ASC.Web.Studio.Core.Notify;
using ASC.Web.Studio.UserControls.Statistics;
using ASC.Web.Studio.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SecurityContext = ASC.Core.SecurityContext;
using ASC.Calendar.Core;
using ASC.Calendar.Core.Dao;
2020-02-21 12:33:51 +00:00
using ASC.Calendar.BusinessObjects;
2020-02-26 11:44:32 +00:00
using ASC.Web.Core.Calendars;
using ASC.Calendar.ExternalCalendars;
using System.Linq;
2020-02-27 08:50:06 +00:00
using System;
using Microsoft.AspNetCore.Http;
using HttpContext = Microsoft.AspNetCore.Http.HttpContext;
using System.Web;
using ASC.Calendar.Notification;
2020-02-27 14:15:25 +00:00
using ASC.Common;
2020-03-03 12:29:07 +00:00
using System.Net;
using System.IO;
using ASC.Calendar.iCalParser;
using ASC.Common.Security;
using System.Globalization;
2020-03-10 11:49:09 +00:00
using Ical.Net.DataTypes;
2020-03-11 13:18:32 +00:00
using System.Threading;
using System.Text;
2020-03-19 12:09:03 +00:00
using ASC.Common.Web;
using System.Net.Mime;
using ASC.Common.Caching;
using System.Text.RegularExpressions;
using System.Diagnostics;
2020-03-26 09:57:30 +00:00
using System.Threading.Tasks;
2020-03-26 10:58:30 +00:00
using System.Security;
2020-03-26 16:00:58 +00:00
using Ical.Net.CalendarComponents;
2020-02-12 07:58:31 +00:00
namespace ASC.Calendar.Controllers
{
2020-03-19 12:09:03 +00:00
public interface IApiContentResponce
{
Stream ContentStream { get; }
ContentType ContentType { get; }
Encoding ContentEncoding { get; }
ContentDisposition ContentDisposition { get; }
}
public class iCalApiContentResponse : IApiContentResponce
{
private Stream _stream;
private string _fileName;
public iCalApiContentResponse(Stream stream, string fileName)
{
_stream = stream;
_fileName = fileName;
}
#region IApiContentResponce Members
public Encoding ContentEncoding
{
get { return Encoding.UTF8; }
}
public Stream ContentStream
{
get { return _stream; }
}
public System.Net.Mime.ContentType ContentType
{
get { return new System.Net.Mime.ContentType("text/calendar; charset=UTF-8"); }
}
public System.Net.Mime.ContentDisposition ContentDisposition
{
get { return new System.Net.Mime.ContentDisposition { Inline = true, FileName = _fileName }; }
}
#endregion
}
2020-02-12 07:58:31 +00:00
[DefaultRoute]
[ApiController]
public class CalendarController : ControllerBase
{
2020-03-06 06:56:05 +00:00
private const int _monthCount = 3;
2020-03-26 16:00:58 +00:00
private static List<String> updatedEvents = new List<string>();
2020-02-12 07:58:31 +00:00
public Tenant Tenant { get { return ApiContext.Tenant; } }
public ApiContext ApiContext { get; }
2020-02-26 11:44:32 +00:00
public AuthContext AuthContext { get; }
2020-02-13 09:18:13 +00:00
public UserManager UserManager { get; }
2020-02-21 12:33:51 +00:00
public DataProvider DataProvider { get; }
2020-02-12 07:58:31 +00:00
public ILog Log { get; }
2020-02-26 11:44:32 +00:00
private TenantManager TenantManager { get; }
2020-02-21 12:33:51 +00:00
public TimeZoneConverter TimeZoneConverter { get; }
public CalendarWrapperHelper CalendarWrapperHelper { get; }
2020-02-26 11:44:32 +00:00
public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
2020-02-27 08:50:06 +00:00
private AuthorizationManager AuthorizationManager { get; }
private AuthManager Authentication { get; }
2020-03-03 12:29:07 +00:00
private CalendarNotifyClient CalendarNotifyClient { get; }
public DDayICalParser DDayICalParser { get; }
2020-02-27 08:50:06 +00:00
public HttpContext HttpContext { get; set; }
2020-03-03 12:29:07 +00:00
public PermissionContext PermissionContext { get; }
public EventHistoryWrapperHelper EventHistoryWrapperHelper { get; }
2020-03-06 06:56:05 +00:00
public EventWrapperHelper EventWrapperHelper { get; }
2020-03-10 08:05:31 +00:00
public EventHistoryHelper EventHistoryHelper { get; }
public PublicItemCollectionHelper PublicItemCollectionHelper { get; }
2020-03-16 08:41:25 +00:00
public TodoWrapperHelper TodoWrapperHelper { get; }
2020-03-19 12:09:03 +00:00
public Signature Signature { get; }
public SecurityContext SecurityContext { get; }
public ExportDataCache ExportDataCache { get; }
2020-03-23 12:23:46 +00:00
public SubscriptionWrapperHelper SubscriptionWrapperHelper { get; }
2020-03-26 10:58:30 +00:00
public EmailValidationKeyProvider EmailValidationKeyProvider { get; }
2020-03-10 08:05:31 +00:00
2020-02-12 07:58:31 +00:00
public CalendarController(
2020-03-06 06:56:05 +00:00
2020-02-12 07:58:31 +00:00
ApiContext apiContext,
2020-02-26 11:44:32 +00:00
AuthContext authContext,
2020-02-27 08:50:06 +00:00
AuthorizationManager authorizationManager,
2020-02-13 09:18:13 +00:00
UserManager userManager,
2020-02-26 11:44:32 +00:00
TenantManager tenantManager,
2020-02-21 12:33:51 +00:00
TimeZoneConverter timeZoneConverter,
2020-02-26 11:44:32 +00:00
DisplayUserSettingsHelper displayUserSettingsHelper,
IOptionsMonitor<ILog> option,
2020-03-03 12:29:07 +00:00
DDayICalParser dDayICalParser,
2020-02-21 12:33:51 +00:00
DataProvider dataProvider,
2020-02-27 08:50:06 +00:00
IHttpContextAccessor httpContextAccessor,
CalendarWrapperHelper calendarWrapperHelper,
2020-03-03 12:29:07 +00:00
AuthManager authentication,
CalendarNotifyClient calendarNotifyClient,
PermissionContext permissionContext,
2020-03-06 06:56:05 +00:00
EventHistoryWrapperHelper eventHistoryWrapperHelper,
2020-03-10 08:05:31 +00:00
EventWrapperHelper eventWrapperHelper,
EventHistoryHelper eventHistoryHelper,
2020-03-16 08:41:25 +00:00
PublicItemCollectionHelper publicItemCollectionHelper,
2020-03-19 12:09:03 +00:00
TodoWrapperHelper todoWrapperHelper,
Signature signature,
SecurityContext securityContext,
2020-03-23 12:23:46 +00:00
ExportDataCache exportDataCache,
2020-03-26 10:58:30 +00:00
SubscriptionWrapperHelper subscriptionWrapperHelper,
EmailValidationKeyProvider emailValidationKeyProvider)
2020-02-12 07:58:31 +00:00
{
2020-02-26 11:44:32 +00:00
AuthContext = authContext;
2020-02-27 08:50:06 +00:00
Authentication = authentication;
AuthorizationManager = authorizationManager;
2020-02-26 11:44:32 +00:00
TenantManager = tenantManager;
2020-02-12 07:58:31 +00:00
Log = option.Get("ASC.Api");
2020-02-21 12:33:51 +00:00
TimeZoneConverter = timeZoneConverter;
2020-02-12 07:58:31 +00:00
ApiContext = apiContext;
2020-02-13 09:18:13 +00:00
UserManager = userManager;
2020-02-21 12:33:51 +00:00
DataProvider = dataProvider;
2020-02-25 13:36:20 +00:00
CalendarWrapperHelper = calendarWrapperHelper;
2020-02-26 11:44:32 +00:00
DisplayUserSettingsHelper = displayUserSettingsHelper;
2020-03-03 12:29:07 +00:00
CalendarNotifyClient = calendarNotifyClient;
DDayICalParser = dDayICalParser;
PermissionContext = permissionContext;
EventHistoryWrapperHelper = eventHistoryWrapperHelper;
2020-03-06 06:56:05 +00:00
EventWrapperHelper = eventWrapperHelper;
2020-03-10 08:05:31 +00:00
EventHistoryHelper = eventHistoryHelper;
PublicItemCollectionHelper = publicItemCollectionHelper;
2020-03-16 08:41:25 +00:00
TodoWrapperHelper = todoWrapperHelper;
2020-03-19 12:09:03 +00:00
Signature = signature;
SecurityContext = securityContext;
ExportDataCache = exportDataCache;
2020-03-23 12:23:46 +00:00
SubscriptionWrapperHelper = subscriptionWrapperHelper;
2020-03-26 10:58:30 +00:00
EmailValidationKeyProvider = emailValidationKeyProvider;
2020-02-26 11:44:32 +00:00
2020-03-20 13:07:07 +00:00
CalendarManager.Instance.RegistryCalendar(new SharedEventsCalendar(AuthContext, TimeZoneConverter, TenantManager, DataProvider));
2020-02-26 11:44:32 +00:00
var birthdayReminderCalendar = new BirthdayReminderCalendar(AuthContext, TimeZoneConverter, UserManager, DisplayUserSettingsHelper);
if (UserManager.IsUserInGroup(AuthContext.CurrentAccount.ID, Constants.GroupVisitor.ID))
{
CalendarManager.Instance.UnRegistryCalendar(birthdayReminderCalendar.Id);
}
else
{
CalendarManager.Instance.RegistryCalendar(birthdayReminderCalendar);
}
2020-02-27 08:50:06 +00:00
HttpContext = httpContextAccessor?.HttpContext;
}
public class SharingParam : SharingOptions.PublicItem
{
public string actionId { get; set; }
public Guid itemId
{
get { return Id; }
set { Id = value; }
}
public bool isGroup
{
get { return IsGroup; }
set { IsGroup = value; }
}
2020-02-12 07:58:31 +00:00
}
2020-03-10 12:52:20 +00:00
public enum EventRemoveType
{
Single = 0,
AllFollowing = 1,
AllSeries = 2
}
2020-02-12 07:58:31 +00:00
[Read("info")]
public Module GetModule()
{
var product = new CalendarProduct();
product.Init();
return new Module(product, true);
}
/// <summary>
/// Returns the list of all subscriptions available to the user
/// </summary>
/// <short>
/// Subscription list
/// </short>
/// <returns>List of subscriptions</returns>
2020-03-23 12:23:46 +00:00
[Read("subscriptions")]
public List<SubscriptionWrapper> LoadSubscriptions()
{
var result = new List<SubscriptionWrapper>();
var calendars = DataProvider.LoadSubscriptionsForUser(SecurityContext.CurrentAccount.ID);
result.AddRange(calendars.FindAll(c => !c.OwnerId.Equals(SecurityContext.CurrentAccount.ID)).ConvertAll(c => SubscriptionWrapperHelper.Get(c)));
var iCalStreams = DataProvider.LoadiCalStreamsForUser(SecurityContext.CurrentAccount.ID);
result.AddRange(iCalStreams.ConvertAll(c => SubscriptionWrapperHelper.Get(c)));
var extCalendars = CalendarManager.Instance.GetCalendarsForUser(SecurityContext.CurrentAccount.ID, UserManager);
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, extCalendars.ConvertAll(c => c.Id));
result.AddRange(extCalendars.ConvertAll(c =>
SubscriptionWrapperHelper.Get(c, viewSettings.Find(o => o.CalendarId.Equals(c.Id, StringComparison.InvariantCultureIgnoreCase)))));
//TODO For personal
/*else
{
var iCalStreams = DataProvider.LoadiCalStreamsForUser(SecurityContext.CurrentAccount.ID);
result.AddRange(iCalStreams.ConvertAll(c => new SubscriptionWrapper(c)));
}*/
return result;
}
2020-03-25 06:17:44 +00:00
public class SubscriptionState
{
public string id { get; set; }
public bool isAccepted { get; set; }
}
public class SubscriptionModel
{
public IEnumerable<SubscriptionState> States { get; set; }
}
/// <summary>
/// Updates the subscription state either subscribing or unsubscribing the user to/from it
/// </summary>
/// <short>
/// Update subscription
/// </short>
/// <param name="states">Updated subscription states</param>
/// <visible>false</visible>
2020-03-25 06:17:44 +00:00
[Update("subscriptions/manage")]
public void ManageSubscriptions(SubscriptionModel subscriptionModel)
2020-03-25 06:17:44 +00:00
{
var states = subscriptionModel.States;
2020-03-25 06:17:44 +00:00
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, states.Select(s => s.id).ToList());
var settingsCollection = new List<UserViewSettings>();
foreach (var s in states)
{
var settings = viewSettings.Find(vs => vs.CalendarId.Equals(s.id, StringComparison.InvariantCultureIgnoreCase));
if (settings == null)
{
settings = new UserViewSettings
{
CalendarId = s.id,
UserId = SecurityContext.CurrentAccount.ID
};
}
settings.IsAccepted = s.isAccepted;
settingsCollection.Add(settings);
}
DataProvider.UpdateCalendarUserView(settingsCollection);
}
/// <summary>
/// Returns the list of all dates which contain the events from the displayed calendars
/// </summary>
/// <short>
/// Calendar events
/// </short>
/// <param name="startDate">Period start date</param>
/// <param name="endDate">Period end date</param>
/// <returns>Date list</returns>
/// <visible>false</visible>
2020-03-20 13:07:07 +00:00
[Read("eventdays/{startDate}/{endDate}")]
public List<ApiDateTime> GetEventDays(ApiDateTime startDate, ApiDateTime endDate)
{
var result = new List<CalendarWrapper>();
int newCalendarsCount;
//internal
var calendars = DataProvider.LoadCalendarsForUser(SecurityContext.CurrentAccount.ID, out newCalendarsCount);
result.AddRange(calendars.ConvertAll(c => CalendarWrapperHelper.Get(c)));
//external
var extCalendars = CalendarManager.Instance.GetCalendarsForUser(SecurityContext.CurrentAccount.ID, UserManager);
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, extCalendars.ConvertAll(c => c.Id));
var extCalendarsWrappers = extCalendars.ConvertAll(c =>
CalendarWrapperHelper.Get(c, viewSettings.Find(o => o.CalendarId.Equals(c.Id, StringComparison.InvariantCultureIgnoreCase)))
)
.FindAll(c => c.IsAcceptedSubscription);
extCalendarsWrappers.ForEach(c => c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper));
var sharedEvents = extCalendarsWrappers.Find(c => String.Equals(c.Id, SharedEventsCalendar.CalendarId, StringComparison.InvariantCultureIgnoreCase));
if (sharedEvents != null)
result.ForEach(c =>
{
c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper);
c.Events.RemoveAll(e => sharedEvents.Events.Exists(sEv => string.Equals(sEv.Id, e.Id, StringComparison.InvariantCultureIgnoreCase)));
});
else
result.ForEach(c => c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper));
result.AddRange(extCalendarsWrappers);
//TODO for personal
/*
//remove all subscription except ical streams
result.RemoveAll(c => c.IsSubscription && !c.IsiCalStream);
result.ForEach(c => c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate));
*/
var days = new List<ApiDateTime>();
foreach (var cal in result)
{
if (cal.IsHidden)
continue;
foreach (var e in cal.Events)
{
var d = (e.Start.UtcTime + e.Start.TimeZoneOffset).Date;
var dend = (e.End.UtcTime + e.End.TimeZoneOffset).Date;
while (d <= dend)
{
if (!days.Exists(day => day == d))
days.Add(new ApiDateTime(d, TimeZoneInfo.Utc.GetOffset()));
d = d.AddDays(1);
}
}
}
return days;
}
/// <summary>
/// Returns the list of calendars and subscriptions with the events for the current user for the selected period
/// </summary>
/// <short>
/// Calendars and subscriptions
/// </short>
/// <param name="startDate">Period start date</param>
/// <param name="endDate">Period end date</param>
/// <returns>List of calendars and subscriptions with events</returns>
2020-03-19 12:36:12 +00:00
[Read("calendars/{startDate}/{endDate}")]
public List<CalendarWrapper> LoadCalendars(ApiDateTime startDate, ApiDateTime endDate)
{
var result = LoadInternalCalendars();
//external
var extCalendars = CalendarManager.Instance.GetCalendarsForUser(SecurityContext.CurrentAccount.ID, UserManager);
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, extCalendars.ConvertAll(c => c.Id));
var extCalendarsWrappers = extCalendars.ConvertAll(c =>
CalendarWrapperHelper.Get(c, viewSettings.Find(o => o.CalendarId.Equals(c.Id, StringComparison.InvariantCultureIgnoreCase)))
)
.FindAll(c => c.IsAcceptedSubscription);
2020-02-12 07:58:31 +00:00
2020-03-20 13:07:07 +00:00
extCalendarsWrappers.ForEach(c => c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper));
2020-03-19 12:36:12 +00:00
var sharedEvents = extCalendarsWrappers.Find(c => String.Equals(c.Id, SharedEventsCalendar.CalendarId, StringComparison.InvariantCultureIgnoreCase));
if (sharedEvents != null)
result.ForEach(c =>
{
2020-03-20 13:07:07 +00:00
c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper);
2020-03-19 12:36:12 +00:00
c.Todos = c.UserCalendar.GetTodoWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate);
c.Events.RemoveAll(e => sharedEvents.Events.Exists(sEv => string.Equals(sEv.Id, e.Id, StringComparison.InvariantCultureIgnoreCase)));
});
else
result.ForEach(c =>
{
2020-03-20 13:07:07 +00:00
c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate, EventWrapperHelper);
2020-03-19 12:36:12 +00:00
c.Todos = c.UserCalendar.GetTodoWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate);
});
result.AddRange(extCalendarsWrappers);
//TODO For personal
/*
//remove all subscription except ical streams
result.RemoveAll(c => c.IsSubscription && !c.IsiCalStream);
result.ForEach(c => c.Events = c.UserCalendar.GetEventWrappers(SecurityContext.CurrentAccount.ID, startDate, endDate));
*/
return result;
}
/// <summary>
/// Returns the detailed information about the calendar with the ID specified in the request
/// </summary>
/// <short>
/// Calendar by ID
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <returns>Calendar</returns>
[Read("{calendarId}")]
2020-02-26 11:44:32 +00:00
public CalendarWrapper GetCalendarById(string calendarId)
{
2020-02-26 11:44:32 +00:00
int calId;
if (int.TryParse(calendarId, out calId))
{
var calendars = DataProvider.GetCalendarById(calId);
return (calendars != null ? CalendarWrapperHelper.Get(calendars) : null);
}
2020-02-26 11:44:32 +00:00
var extCalendar = CalendarManager.Instance.GetCalendarForUser(AuthContext.CurrentAccount.ID, calendarId, UserManager);
if (extCalendar != null)
{
var viewSettings = DataProvider.GetUserViewSettings(AuthContext.CurrentAccount.ID, new List<string> { calendarId });
return CalendarWrapperHelper.Get(extCalendar, viewSettings.FirstOrDefault());
}
return null;
}
/// <summary>
/// Returns the link for the iCal associated with the calendar with the ID specified in the request
/// </summary>
/// <short>
/// Get iCal link
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <returns>iCal link</returns>
2020-03-19 12:09:03 +00:00
[Read("{calendarId}/icalurl")]
public object GetCalendariCalUrl(string calendarId)
{
var sig = Signature.Create(AuthContext.CurrentAccount.ID);
// var path = UrlPath.ResolveUrl(() => new CalendarApi().GetCalendariCalStream(calendarId, sig));
var path = "api/2.0/calendar/" + calendarId + "/ical/" + sig;
var result = new Uri(HttpContext.Request.GetUrlRewriter(), VirtualPathUtility.ToAbsolute("~/" + path)).ToString();
return new{result};
}
2020-03-26 09:57:30 +00:00
/// <summary>
/// Returns the link for the CalDav associated with the calendar with the ID specified in the request
/// </summary>
/// <short>
/// Get CalDav link
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <returns>CalDav link</returns>
[Read("{calendarId}/caldavurl")]
public string GetCalendarCalDavUrl(string calendarId)
{
var myUri = HttpContext.Request.GetUrlRewriter();
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
var caldavHost = myUri.Host;
var userId = SecurityContext.CurrentAccount.ID;
var userName = UserManager.GetUsers(userId).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, userId);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ":" + currentAccountPaswd));
var curCaldavUserName = userName + "@" + caldavHost;
if (calendarId == "todo_calendar")
{
var todoCalendars = DataProvider.LoadTodoCalendarsForUser(SecurityContext.CurrentAccount.ID);
var userTimeZone = TenantManager.GetCurrentTenant().TimeZone;
var icalendar = new iCalendar(AuthContext, TimeZoneConverter, TenantManager);
var newCalendar = new BusinessObjects.Calendar(AuthContext, TimeZoneConverter, icalendar, DataProvider);
var todoCal = CalendarWrapperHelper.Get(newCalendar);
if (todoCalendars.Count == 0)
{
var todoCalModel = new CalendarModel
{
Name = "Todo_calendar",
Description = "",
TextColor = BusinessObjects.Calendar.DefaultTextColor,
BackgroundColor = BusinessObjects.Calendar.DefaultTodoBackgroundColor,
TimeZone = userTimeZone.ToString(),
AlertType = EventAlertType.FifteenMinutes,
SharingOptions = null,
ICalUrl = null,
IsTodo = 1
};
todoCal = CreateCalendar(todoCalModel);
if (todoCal != null)
{
try
{
var dataCaldavGuid = DataProvider.GetCalDavGuid(todoCal.Id);
var caldavGuid = dataCaldavGuid != null
? Guid.Parse(dataCaldavGuid)
: Guid.Empty;
var sharedCalUrl = new Uri(new Uri(calDavServerUrl), "/caldav/" + curCaldavUserName + "/" + caldavGuid).ToString();
var calendar = GetUserCaldavCalendar(sharedCalUrl, encoded);
if (calendar != "")
{
if (calendar == "NotFound")
{
return CreateCalDavCalendar(
"Todo_calendar",
"",
BusinessObjects.Calendar.DefaultTodoBackgroundColor,
caldavGuid.ToString(),
myUri,
curCaldavUserName,
userName,
currentAccountPaswd
);
}
return sharedCalUrl;
}
else
{
return "";
}
}
catch (Exception exception)
{
Log.Error("ERROR: " + exception.Message);
return "";
}
}
else
{
return "";
}
}
else
{
var sharedCalUrl = new Uri(new Uri(calDavServerUrl), "/caldav/" + curCaldavUserName + "/" + todoCalendars[0].calDavGuid).ToString();
var calendar = GetUserCaldavCalendar(sharedCalUrl, encoded);
if (calendar != "")
{
if (calendar == "NotFound")
{
return CreateCalDavCalendar(
"Todo_calendar",
"",
BusinessObjects.Calendar.DefaultTodoBackgroundColor,
todoCalendars[0].calDavGuid.ToString(),
myUri,
curCaldavUserName,
userName,
currentAccountPaswd
);
}
return sharedCalUrl;
}
else
{
return "";
}
}
}
if (calendarId == BirthdayReminderCalendar.CalendarId ||
calendarId == SharedEventsCalendar.CalendarId ||
calendarId == "crm_calendar" ||
calendarId.Contains("Project_"))
{
if (SecurityContext.IsAuthenticated)
{
var sharedCalendar = GetCalendarById(calendarId);
var currentUserId = SecurityContext.CurrentAccount.ID;
var currentUserEmail = UserManager.GetUsers(currentUserId).Email;
var currentUserPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, currentUserId);
var currentCaldavUserName = currentUserEmail + "@" + caldavHost;
var sharedEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(currentUserEmail + ":" + currentUserPaswd));
var sharedCalUrl = new Uri(new Uri(calDavServerUrl), "/caldav/" + currentCaldavUserName + "/" + calendarId + "-shared").ToString();
var calendar = GetUserCaldavCalendar(sharedCalUrl, sharedEncoded);
if (calendar != "")
{
if (calendar == "NotFound")
{
sharedCalUrl = CreateCalDavCalendar(
sharedCalendar.UserCalendar.Name,
sharedCalendar.UserCalendar.Description,
sharedCalendar.TextColor,
calendarId,
myUri,
currentCaldavUserName,
currentUserEmail,
Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, currentUserId),
true
);
}
if (sharedCalUrl != "")
{
var calendarIcs = GetCalendariCalString(calendarId, true);
//TODO Caldav
2020-03-26 16:00:58 +00:00
//var tenant = TenantManager.GetCurrentTenant();
//var caldavTask = new Task(() => CreateCaldavSharedEvents(calendarId, calendarIcs, myUri, currentUserEmail, currentUserPaswd, sharedCalendar.UserCalendar, SecurityContext.CurrentAccount, tenant.TenantId));
//caldavTask.Start();
2020-03-26 09:57:30 +00:00
return sharedCalUrl;
}
}
}
return "";
}
var cal = DataProvider.GetCalendarById(Convert.ToInt32(calendarId));
var ownerId = cal.OwnerId;
TenantManager.SetCurrentTenant(cal.TenantId);
var isShared = ownerId != SecurityContext.CurrentAccount.ID;
var calDavGuid = cal.calDavGuid;
if (calDavGuid == "" || calDavGuid == Guid.Empty.ToString())
{
calDavGuid = Guid.NewGuid().ToString();
DataProvider.UpdateCalendarGuid(Convert.ToInt32(cal.Id), Guid.Parse(calDavGuid));
}
var calUrl = new Uri(new Uri(calDavServerUrl), "/caldav/" + curCaldavUserName + "/" + calDavGuid + (isShared ? "-shared" : "")).ToString();
Log.Info("RADICALE REWRITE URL: " + myUri);
var caldavCalendar = GetUserCaldavCalendar(calUrl, encoded);
if (caldavCalendar != "")
{
if (caldavCalendar == "NotFound")
{
return SyncCaldavCalendar(calendarId, cal.Name, cal.Description, cal.Context.HtmlBackgroundColor, Guid.Parse(calDavGuid), myUri, curCaldavUserName, userName, currentAccountPaswd, isShared, cal.SharingOptions);
}
return calUrl;
}
return "";
}
2020-03-26 10:58:30 +00:00
/// <summary>
/// Run caldav event update function
/// </summary>
/// <short>
/// Update CalDav Event
/// </short>
/// <param name="change">changes of event</param>
/// <param name="key"></param>
/// <visible>false</visible>
[Read("change_to_storage", false)] //NOTE: this method doesn't requires auth!!!
public void ChangeOfCalendarStorage(string change, string key)
{
var authInterval = TimeSpan.FromHours(1);
var checkKeyResult = EmailValidationKeyProvider.ValidateEmailKey(change + ConfirmType.Auth, key, authInterval);
if (checkKeyResult != EmailValidationKeyProvider.ValidationResult.Ok) throw new SecurityException("Access Denied.");
var urlRewriter = HttpContext.Request.GetUrlRewriter();
var caldavUser = change.Split('/')[0];
var portalName = caldavUser.Split('@')[2];
if (change != null && portalName != null)
{
//TODO Caldav
2020-03-26 16:00:58 +00:00
//var calDavUrl = new Uri(urlRewriter.Scheme + "://" + portalName);
//var caldavTask = new Task(() => UpdateCalDavEvent(change, calDavUrl));
//caldavTask.Start();
2020-03-26 10:58:30 +00:00
}
}
2020-03-30 15:04:14 +00:00
/// <summary>
/// Deletes the project calendar with the ID specified in the request
/// </summary>
/// <short>
/// Delete project calendar
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <param name="team">Project team</param>
[Delete("caldavprojcal")]
public void DeleteCaldavCalendar(string calendarId, List<string> team = null)
{
try
{
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID));
var myUri = HttpContext.Request.GetUrlRewriter();
var caldavHost = myUri.Host;
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var deleteCaldavCalendar = new Thread(() =>
{
TenantManager.SetCurrentTenant(currentTenantId);
foreach (var teamMember in team)
{
var currentUserName = UserManager.GetUsers(Guid.Parse(teamMember)).Email + "@" + caldavHost;
DataProvider.RemoveCaldavCalendar(
currentUserName,
UserManager.GetUsers(Guid.Parse(teamMember)).Email,
Authentication.GetUserPasswordHash(currentTenantId, Guid.Parse(teamMember)),
encoded,
calendarId,
myUri,
true);
}
});
deleteCaldavCalendar.Start();
}
catch (Exception ex)
{
Log.Error(String.Format("Delete project caldav calendar: {0}", ex.Message));
}
}
/// <summary>
/// Deletes the whole caldav event from the calendar
/// </summary>
/// <short>
/// Delete event
/// </short>
/// <param name="calendarId">ID of the calendar where the event belongs</param>
/// <param name="uid">Event uid</param>
/// <param name="responsibles">Task responsibles</param>
[Delete("caldavevent")]
public void DeleteCaldavEvent(string calendarId, string uid, List<string> responsibles = null)
{
try
{
var currentUserId = SecurityContext.CurrentAccount.ID;
var myUri = HttpContext.Request.GetUrlRewriter();
if (responsibles == null || responsibles.Count == 0)
{
var currentUserEmail = UserManager.GetUsers(currentUserId).Email;
var currentUserPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, currentUserId);
deleteEvent(uid, calendarId, currentUserEmail, currentUserPaswd, myUri, true);
}
else if (responsibles.Count > 0)
{
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var deleteCaldavEvent = new Thread(() =>
{
TenantManager.SetCurrentTenant(currentTenantId);
foreach (var responsibleSid in responsibles)
{
deleteEvent(
uid,
calendarId,
UserManager.GetUsers(Guid.Parse(responsibleSid)).Email,
Authentication.GetUserPasswordHash(currentTenantId, Guid.Parse(responsibleSid)),
myUri,
true
);
}
});
deleteCaldavEvent.Start();
}
}
catch (Exception ex)
{
Log.Error(String.Format("Delete CRM caldav event: {0}", ex.Message));
}
}
/// <summary>
/// Create/update the existing caldav event in the selected calendar
/// </summary>
/// <short>
/// Update caldav event
/// </short>
/// <param name="calendarId">ID of the calendar where the event belongs</param>
/// <param name="uid">Event uid</param>
/// <param name="alert">Event notification type</param>
/// <param name="responsibles">Task responsibles</param>
[Update("caldavevent")]
public void UpdateCaldavEvent(string calendarId, string uid, int alert = 0, List<string> responsibles = null)
{
try
{
if (responsibles.Count > 0)
{
var myUri = HttpContext.Request.GetUrlRewriter();
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var sharedCalendar = GetCalendarById(calendarId);
SecurityContext.AuthenticateMe(
UserManager.GetUsers(Guid.Parse(responsibles[0])).Email,
Authentication.GetUserPasswordHash(currentTenantId, Guid.Parse(responsibles[0]))
);
var calendarIcs = GetCalendariCalString(calendarId, true);
var parseCalendar = DDayICalParser.DeserializeCalendar(calendarIcs);
var calendar = parseCalendar.FirstOrDefault();
if (calendar != null)
{
var events = calendar.Events;
var ddayCalendar = new Ical.Net.Calendar();
foreach (var evt in events)
{
var eventUid = evt.Uid;
string[] split = eventUid.Split(new Char[] { '@' });
if (uid == split[0])
{
ddayCalendar = getEventIcs(alert, sharedCalendar, evt, calendarId);
}
}
var serializeIcs = DDayICalParser.SerializeCalendar(ddayCalendar);
var updateEvent = new Thread(() =>
{
TenantManager.SetCurrentTenant(currentTenantId);
foreach (var responsibleSid in responsibles)
{
updateCaldavEvent(
serializeIcs,
uid,
true,
calendarId,
myUri,
UserManager.GetUsers(Guid.Parse(responsibleSid)).Email,
Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, Guid.Parse(responsibleSid)),
DateTime.Now,
ddayCalendar.TimeZones[0],
sharedCalendar.UserCalendar.TimeZone, false, true
);
}
});
updateEvent.Start();
}
}
}
catch (Exception ex)
{
Log.Error(String.Format("Create/update CRM caldav event: {0}", ex.Message));
}
}
private Ical.Net.Calendar getEventIcs(int alert, CalendarWrapper calendar, CalendarEvent evt, string calendarId)
{
var ddayCalendar = DDayICalParser.ConvertCalendar(calendar.UserCalendar);
ddayCalendar.Events.Clear();
evt.Created = null;
if (calendarId.Contains("Project_"))
{
evt.End = new CalDateTime(evt.End.AddDays(1));
}
evt.Status = EventStatus.Confirmed.ToString();
if (alert > 0)
{
evt.Alarms.Add(
new Alarm()
{
Action = "DISPLAY",
Description = "Reminder",
Trigger = new Trigger(TimeSpan.FromMinutes((-1) * alert))
}
);
}
ddayCalendar.Events.Add(evt);
return ddayCalendar;
}
2020-03-26 10:58:30 +00:00
/// <summary>
/// Run caldav event delete function
/// </summary>
/// <short>
/// Delete CalDav Event
/// </short>
/// <param name="eventInfo">event info</param>
/// <param name="key"></param>
/// <visible>false</visible>
[Read("caldav_delete_event", false)] //NOTE: this method doesn't requires auth!!!
public void CaldavDeleteEvent(string eventInfo, string key)
{
var authInterval = TimeSpan.FromHours(1);
var checkKeyResult = EmailValidationKeyProvider.ValidateEmailKey(eventInfo + ConfirmType.Auth, key, authInterval);
if (checkKeyResult != EmailValidationKeyProvider.ValidationResult.Ok) throw new SecurityException("Access Denied.");
if (eventInfo != null)
{
var myUri = HttpContext.Request.GetUrlRewriter();
var calEvent = eventInfo.Split('/')[2].Replace("_write", "");
var eventGuid = calEvent.Split('.')[0];
//TODO Caldav
2020-03-26 16:00:58 +00:00
//var updateEventGuid = updatedEvents.Find((x) => x == eventGuid);
//if (updateEventGuid == null)
//{
// Task.Run(() => DeleteCalDavEvent(eventInfo, myUri));
//}
//else
//{
// updatedEvents.Remove(updateEventGuid);
//}
2020-03-26 10:58:30 +00:00
}
}
2020-03-26 09:57:30 +00:00
private string SyncCaldavCalendar(string calendarId,
string name,
string description,
string backgroundColor,
Guid calDavGuid,
Uri myUri,
string curCaldavUserName,
string email,
string currentAccountPaswd,
bool isShared = false,
SharingOptions sharingOptions = null)
{
var calendarUrl = CreateCalDavCalendar(name, description, backgroundColor, calDavGuid.ToString(), myUri, curCaldavUserName, email, currentAccountPaswd, isShared);
BaseCalendar icalendar;
int calId;
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, new List<string> { calendarId });
if (int.TryParse(calendarId, out calId))
{
icalendar = DataProvider.GetCalendarById(calId);
if (icalendar != null)
{
icalendar = icalendar.GetUserCalendar(viewSettings.FirstOrDefault());
}
}
else
{
//external
icalendar = CalendarManager.Instance.GetCalendarForUser(SecurityContext.CurrentAccount.ID, calendarId, UserManager);
if (icalendar != null)
{
icalendar = icalendar.GetUserCalendar(viewSettings.FirstOrDefault());
}
}
if (icalendar == null) return "";
var calendarIcs = GetCalendariCalString(icalendar.Id, true);
//TODO Caldav
2020-03-26 16:00:58 +00:00
//var tenant = TenantManager.GetCurrentTenant();
//var caldavTask = isShared ? new Task(() => CreateCaldavSharedEvents(calDavGuid.ToString(), calendarIcs, myUri, email, currentAccountPaswd, icalendar, SecurityContext.CurrentAccount, tenant.TenantId)): new Task(() => CreateCaldavEvents(calDavGuid.ToString(), myUri, email, currentAccountPaswd, icalendar, calendarIcs));
//caldavTask.Start();
2020-03-26 09:57:30 +00:00
return calendarUrl;
}
private string HexFromRGB(int r, int g, int b)
{
return String.Format("#{0:X2}{1:X2}{2:X2}", r, g, b);
}
private string GetUserCaldavCalendar(string calUrl, string encoded)
{
var webRequest = (HttpWebRequest)WebRequest.Create(calUrl);
webRequest.Method = "GET";
webRequest.ContentType = "text/calendar; charset=utf-8";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
try
{
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
string ics = reader.ReadToEnd();
if (!string.IsNullOrEmpty(ics))
{
return ics;
}
return "";
}
}
catch (WebException exception)
{
if (exception.Status == WebExceptionStatus.ProtocolError && exception.Response != null)
{
var resp = (HttpWebResponse)exception.Response;
if (resp.StatusCode == HttpStatusCode.NotFound)
{
return "NotFound";
}
}
Log.Info("ERROR. Get calendar CalDav url: " + exception.Message);
return "";
}
}
private string CreateCalDavCalendar(string name, string description, string backgroundColor, string calDavGuid, Uri myUri, string currentUserName, string email, string currentAccountPaswd, bool isSharedCalendar = false)
{
name = (name ?? "").Trim();
if (String.IsNullOrEmpty(name))
throw new Exception(Resources.CalendarApiResource.ErrorEmptyName);
description = (description ?? "").Trim();
backgroundColor = (backgroundColor ?? "").Trim();
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
Log.Info("RADICALE REWRITE URL: " + myUri);
string[] numbers = Regex.Split(backgroundColor, @"\D+");
var color = numbers.Length > 4 ? HexFromRGB(int.Parse(numbers[1]), int.Parse(numbers[2]), int.Parse(numbers[3])) : "#000000";
var data = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
"<mkcol xmlns=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:CR=\"urn:ietf:params:xml:ns:carddav\" xmlns:I=\"http://apple.com/ns/ical/\" xmlns:INF=\"http://inf-it.com/ns/ab/\">" +
"<set><prop>" +
"<resourcetype><collection /><C:calendar /></resourcetype>" +
"<C:supported-calendar-component-set><C:comp name=\"VEVENT\" /><C:comp name=\"VJOURNAL\" /><C:comp name=\"VTODO\" />" +
"</C:supported-calendar-component-set><displayname>" + name + "</displayname>" +
"<I:calendar-color>" + color + "</I:calendar-color>" +
"<C:calendar-description>" + description + "</C:calendar-description></prop></set></mkcol>";
var calDavUrl = calDavServerUrl.Insert(calDavServerUrl.IndexOf("://") + 3, HttpUtility.UrlEncode(currentUserName) + ":" + HttpUtility.UrlEncode(currentAccountPaswd) + "@");
var requestUrl = calDavUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" + calDavGuid + (isSharedCalendar ? "-shared" : "");
try
{
var encoded = isSharedCalendar ? Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID)) : Convert.ToBase64String(Encoding.UTF8.GetBytes(email.ToLower() + ":" + currentAccountPaswd));
var webRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
webRequest.Method = "MKCOL";
webRequest.ContentType = "text/plain;charset=UTF-8";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
var encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(data);
webRequest.ContentLength = bytes.Length;
using (Stream writeStream = webRequest.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
reader.ReadToEnd();
return calDavServerUrl + "/" + currentUserName + "/" + calDavGuid + (isSharedCalendar ? "-shared" : "");
}
}
catch (Exception ex)
{
Log.Error(ex);
return "";
}
}
/// <summary>
/// Returns the feed for the iCal associated with the calendar by its ID and signagure specified in the request
/// </summary>
/// <short>Get iCal feed</short>
/// <param name="calendarId">Calendar ID</param>
/// <param name="signature">Signature</param>
/// <remarks>To get the feed you need to use the method returning the iCal feed link (it will generate the necessary signature)</remarks>
/// <returns>Calendar iCal feed</returns>
2020-03-19 12:09:03 +00:00
[Read("{calendarId}/ical/{signature}", false)] //NOTE: this method doesn't requires auth!!!
public iCalApiContentResponse GetCalendariCalStream(string calendarId, string signature)
{
try
{
//do not use compression
var acceptEncoding = HttpContext.Request.Headers["Accept-Encoding"];
if (acceptEncoding.Count > 0)
{
/*var encodings = acceptEncoding.Split(',');
if (encodings.Contains("gzip"))
{
encodings = (from x in encodings where x != "gzip" select x).ToArray();
Type t = HttpContext.Request.Headers.GetType();
PropertyInfo propertyInfo = t.GetProperty("IsReadOnly", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
propertyInfo.SetValue(HttpContext.Request.Headers, false, null);
HttpContext.Request.Headers.Set("Accept-Encoding", string.Join(",", encodings));
}*/
}
}
catch (Exception ex)
{
Log.Error(ex);
}
iCalApiContentResponse resp = null;
var userId = Signature.Read<Guid>(signature);
if (UserManager.GetUsers(userId).ID != Constants.LostUser.ID)
{
var currentUserId = Guid.Empty;
if (AuthContext.IsAuthenticated)
{
currentUserId = AuthContext.CurrentAccount.ID;
AuthContext.Logout();
}
try
{
SecurityContext.AuthenticateMe(userId);
var icalFormat = GetCalendariCalString(calendarId);
if (icalFormat != null)
resp = new iCalApiContentResponse(new MemoryStream(Encoding.UTF8.GetBytes(icalFormat)), calendarId + ".ics");
}
finally
{
AuthContext.Logout();
if (currentUserId != Guid.Empty)
{
SecurityContext.AuthenticateMe(currentUserId);
}
}
}
return resp;
}
2020-02-27 08:50:06 +00:00
/// <summary>
/// Creates the new calendar with the parameters (name, description, color, etc.) specified in the request
/// </summary>
/// <short>
/// Create calendar
/// </short>
/// <param name="name">Calendar name</param>
/// <param name="description">Calendar description</param>
/// <param name="textColor">Event text color</param>
/// <param name="backgroundColor">Event background color</param>
/// <param name="timeZone">Calendar time zone</param>
/// <param name="alertType">Event alert type, in case alert type is set by default</param>
/// <param name="sharingOptions">Calendar sharing options with other users</param>
/// <param name="iCalUrl">iCal url</param>
/// <param name="isTodo">Calendar for todo list</param>
/// <returns>Created calendar</returns>
2020-02-27 08:50:06 +00:00
[Create]
public CalendarWrapper CreateCalendar(CalendarModel calendar)
{
2020-03-11 13:18:32 +00:00
var sharingOptionsList = calendar.SharingOptions ?? new List<SharingParam>();
2020-02-27 08:50:06 +00:00
var timeZoneInfo = TimeZoneConverter.GetTimeZone(calendar.TimeZone);
2020-03-06 06:56:05 +00:00
2020-02-27 08:50:06 +00:00
calendar.Name = (calendar.Name ?? "").Trim();
if (String.IsNullOrEmpty(calendar.Name))
throw new Exception(Resources.CalendarApiResource.ErrorEmptyName);
calendar.Description = (calendar.Description ?? "").Trim();
calendar.TextColor = (calendar.TextColor ?? "").Trim();
calendar.BackgroundColor = (calendar.BackgroundColor ?? "").Trim();
Guid calDavGuid = Guid.NewGuid();
var myUri = HttpContext.Request.GetUrlRewriter();
var _email = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email;
var currentUserName = _email.ToLower() + "@" + myUri.Host;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(_email).ID);
//TODO caldav
2020-03-26 16:00:58 +00:00
//var caldavTask = new Task(() => CreateCalDavCalendar(calendar.Name, calendar.Description, calendar.BackgroundColor, calDavGuid.ToString(), myUri, currentUserName, _email, currentAccountPaswd));
//caldavTask.Start();
2020-02-27 08:50:06 +00:00
var cal = DataProvider.CreateCalendar(
AuthContext.CurrentAccount.ID,
calendar.Name,
calendar.Description,
calendar.TextColor,
2020-03-06 06:56:05 +00:00
calendar.BackgroundColor,
2020-02-27 08:50:06 +00:00
timeZoneInfo,
calendar.AlertType,
null,
sharingOptionsList.Select(o => o as SharingOptions.PublicItem).ToList(),
2020-03-06 06:56:05 +00:00
new List<UserViewSettings>(),
2020-02-27 08:50:06 +00:00
calDavGuid,
calendar.IsTodo);
if (cal == null) throw new Exception("calendar is null");
2020-03-06 06:56:05 +00:00
foreach (var opt in sharingOptionsList)
2020-02-27 08:50:06 +00:00
if (String.Equals(opt.actionId, AccessOption.FullAccessOption.Id, StringComparison.InvariantCultureIgnoreCase))
AuthorizationManager.AddAce(new AzRecord(opt.Id, CalendarAccessRights.FullAccessAction.ID, Common.Security.Authorizing.AceType.Allow, cal));
//notify
2020-03-03 12:29:07 +00:00
CalendarNotifyClient.NotifyAboutSharingCalendar(cal);
2020-02-27 08:50:06 +00:00
2020-03-03 12:29:07 +00:00
//iCalUrl
2020-03-16 08:41:25 +00:00
if (!string.IsNullOrEmpty(calendar.ICalUrl))
2020-02-27 08:50:06 +00:00
{
try
{
2020-03-16 08:41:25 +00:00
var req = (HttpWebRequest)WebRequest.Create(calendar.ICalUrl);
2020-02-27 08:50:06 +00:00
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
{
var ms = new MemoryStream();
stream.StreamCopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
using (var tempReader = new StreamReader(ms))
{
var cals = DDayICalParser.DeserializeCalendar(tempReader);
ImportEvents(Convert.ToInt32(cal.Id), cals);
}
}
}
catch (Exception ex)
{
2020-03-03 12:29:07 +00:00
Log.Info(String.Format("Error import events to new calendar by ical url: {0}", ex.Message));
2020-02-27 08:50:06 +00:00
}
2020-03-03 12:29:07 +00:00
}
2020-02-27 08:50:06 +00:00
return CalendarWrapperHelper.Get(cal);
}
2020-03-03 12:29:07 +00:00
/// <summary>
/// Updates the selected calendar with the parameters (name, description, color, etc.) specified in the request for the current user and access rights for other users
/// </summary>
/// <short>
/// Update calendar
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <param name="name">Calendar new name</param>
/// <param name="description">Calendar new description</param>
/// <param name="textColor">Event text color</param>
/// <param name="backgroundColor">Event background color</param>
/// <param name="timeZone">Calendar time zone</param>
/// <param name="alertType">Event alert type, in case alert type is set by default</param>
/// <param name="hideEvents">Display type: show or hide events in calendar</param>
/// <param name="sharingOptions">Calendar sharing options with other users</param>
/// <param name="iCalUrl">iCal url</param>
/// <returns>Updated calendar</returns>
2020-03-11 13:18:32 +00:00
[Update("{calendarId}")]
public CalendarWrapper UpdateCalendar(string calendarId, CalendarModel calendar)
{
var name = calendar.Name;
var description = calendar.Description;
var textColor = calendar.TextColor;
var backgroundColor = calendar.BackgroundColor;
var timeZone = calendar.TimeZone;
var alertType = calendar.AlertType;
var hideEvents = calendar.HideEvents;
var sharingOptions = calendar.SharingOptions;
2020-03-16 08:41:25 +00:00
var iCalUrl = calendar.ICalUrl ?? "";
2020-03-11 13:18:32 +00:00
TimeZoneInfo timeZoneInfo = TimeZoneConverter.GetTimeZone(timeZone);
int calId;
if (!string.IsNullOrEmpty(iCalUrl))
{
try
{
var req = (HttpWebRequest)WebRequest.Create(iCalUrl);
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
{
var ms = new MemoryStream();
stream.StreamCopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
using (var tempReader = new StreamReader(ms))
{
var cals = DDayICalParser.DeserializeCalendar(tempReader);
ImportEvents(Convert.ToInt32(calendarId), cals);
}
}
}
catch (Exception ex)
{
Log.Info(String.Format("Error import events to calendar by ical url: {0}", ex.Message));
}
}
if (int.TryParse(calendarId, out calId))
{
var oldCal = DataProvider.GetCalendarById(calId);
2020-03-25 07:55:43 +00:00
2020-03-11 13:18:32 +00:00
if (CheckPermissions(oldCal, CalendarAccessRights.FullAccessAction, true))
{
//update calendar and share options
var sharingOptionsList = sharingOptions ?? new List<SharingParam>();
name = (name ?? "").Trim();
if (String.IsNullOrEmpty(name))
throw new Exception(Resources.CalendarApiResource.ErrorEmptyName);
description = (description ?? "").Trim();
textColor = (textColor ?? "").Trim();
backgroundColor = (backgroundColor ?? "").Trim();
//view
var userOptions = oldCal.ViewSettings;
var usrOpt = userOptions.Find(o => o.UserId.Equals(AuthContext.CurrentAccount.ID));
if (usrOpt == null)
{
userOptions.Add(new UserViewSettings
{
Name = name,
TextColor = textColor,
BackgroundColor = backgroundColor,
EventAlertType = alertType,
IsAccepted = true,
UserId = AuthContext.CurrentAccount.ID,
TimeZone = timeZoneInfo
});
}
else
{
usrOpt.Name = name;
usrOpt.TextColor = textColor;
usrOpt.BackgroundColor = backgroundColor;
usrOpt.EventAlertType = alertType;
usrOpt.TimeZone = timeZoneInfo;
}
userOptions.RemoveAll(o => !o.UserId.Equals(oldCal.OwnerId) && !sharingOptionsList.Exists(opt => (!opt.IsGroup && o.UserId.Equals(opt.Id))
|| opt.IsGroup && UserManager.IsUserInGroup(o.UserId, opt.Id)));
//check owner
if (!oldCal.OwnerId.Equals(AuthContext.CurrentAccount.ID))
{
name = oldCal.Name;
description = oldCal.Description;
}
var myUri = HttpContext.Request.GetUrlRewriter();
var _email = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(_email).ID);
var cal = DataProvider.UpdateCalendar(calId, name, description,
sharingOptionsList.Select(o => o as SharingOptions.PublicItem).ToList(),
userOptions);
var oldSharingList = new List<SharingParam>();
var owner = UserManager.GetUsers(cal.OwnerId);
var ownerAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, cal.OwnerId);
//TODO Caldav
2020-03-26 16:00:58 +00:00
//if (AuthContext.CurrentAccount.ID != cal.OwnerId)
//{
// UpdateCalDavCalendar(name, description, backgroundColor, oldCal.calDavGuid, myUri, owner.Email, ownerAccountPaswd);
//}
//else
//{
// UpdateCalDavCalendar(name, description, backgroundColor, oldCal.calDavGuid, myUri, _email, currentAccountPaswd);
//}
2020-03-11 13:18:32 +00:00
var pic = PublicItemCollectionHelper.GetForCalendar(oldCal);
if (pic.Items.Count > 1)
{
oldSharingList.AddRange(from publicItem in pic.Items
where publicItem.ItemId != owner.ID.ToString()
select new SharingParam
{
Id = Guid.Parse(publicItem.ItemId),
isGroup = publicItem.IsGroup,
actionId = publicItem.SharingOption.Id
});
}
if (sharingOptionsList.Count > 0)
{
var tenant = TenantManager.GetCurrentTenant();
var events = cal.LoadEvents(AuthContext.CurrentAccount.ID, DateTime.MinValue, DateTime.MaxValue);
var calendarObjViewSettings = cal != null && cal.ViewSettings != null ? cal.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(cal != null ? cal.GetUserCalendar(calendarObjViewSettings) : null);
//TODO Caldav
2020-03-27 12:49:05 +00:00
//var caldavTask = new Task(() => UpdateSharedCalDavCalendar(name, description, backgroundColor, oldCal.calDavGuid, myUri, sharingOptionsList, events, calendarId, cal.calDavGuid, tenant.TenantId, DateTime.Now, targetCalendar.TimeZones[0], cal.TimeZone));
//caldavTask.Start();
2020-03-11 13:18:32 +00:00
}
oldSharingList.RemoveAll(c => sharingOptionsList.Contains(sharingOptionsList.Find((x) => x.Id == c.Id)));
if (oldSharingList.Count > 0)
{
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var caldavHost = myUri.Host;
//TODO Caldav
/*var replaceSharingEventThread = new Thread(() =>
{
TenantManager.SetCurrentTenant(currentTenantId);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID));
foreach (var sharingOption in oldSharingList)
{
if (!sharingOption.IsGroup)
{
var user = UserManager.GetUsers(sharingOption.itemId);
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
var userEmail = user.Email;
string userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(userEmail).ID);
DataProvider.RemoveCaldavCalendar(currentUserName, userEmail, userPaswd, encoded, cal.calDavGuid, myUri, user.ID != cal.OwnerId);
}
else
{
2020-03-27 12:49:05 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-11 13:18:32 +00:00
foreach (var user in users)
{
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
var userEmail = user.Email;
string userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(userEmail).ID);
DataProvider.RemoveCaldavCalendar(currentUserName, userEmail, userPaswd, encoded, cal.calDavGuid, myUri, user.ID != cal.OwnerId);
}
}
}
});
replaceSharingEventThread.Start();*/
}
if (cal != null)
{
//clear old rights
AuthorizationManager.RemoveAllAces(cal);
foreach (var opt in sharingOptionsList)
if (String.Equals(opt.actionId, AccessOption.FullAccessOption.Id, StringComparison.InvariantCultureIgnoreCase))
AuthorizationManager.AddAce(new AzRecord(opt.Id, CalendarAccessRights.FullAccessAction.ID, Common.Security.Authorizing.AceType.Allow, cal));
//notify
CalendarNotifyClient.NotifyAboutSharingCalendar(cal, oldCal);
return CalendarWrapperHelper.Get(cal);
}
return null;
}
}
//update view
2020-03-12 11:45:21 +00:00
return UpdateCalendarView(calendarId, new CalendarModel
{
Name = name,
TextColor = textColor,
BackgroundColor = backgroundColor,
TimeZone = timeZone,
AlertType = alertType,
HideEvents = hideEvents
});
2020-03-11 13:18:32 +00:00
}
/// <summary>
/// Change the calendar display parameters specified in the request for the current user
/// </summary>
/// <short>
/// Update calendar user view
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <param name="name">Calendar name</param>
/// <param name="textColor">Event text color</param>
/// <param name="backgroundColor">Event background color</param>
/// <param name="timeZone">Calendar time zone</param>
/// <param name="alertType">Event alert type, in case alert type is set by default</param>
/// <param name="hideEvents">Display type: show or hide events in calendar</param>
/// <returns>Updated calendar</returns>
2020-03-11 13:18:32 +00:00
[Update("{calendarId}/view")]
2020-03-12 11:45:21 +00:00
public CalendarWrapper UpdateCalendarView(string calendarId, CalendarModel calendar)
2020-03-11 13:18:32 +00:00
{
2020-03-12 11:45:21 +00:00
var name = calendar.Name;
var textColor = calendar.TextColor;
var backgroundColor = calendar.BackgroundColor;
var timeZone = calendar.TimeZone;
var alertType = calendar.AlertType;
var hideEvents = calendar.HideEvents;
2020-03-11 13:18:32 +00:00
TimeZoneInfo timeZoneInfo = TimeZoneConverter.GetTimeZone(timeZone);
name = (name ?? "").Trim();
if (String.IsNullOrEmpty(name))
throw new Exception(Resources.CalendarApiResource.ErrorEmptyName);
var settings = new UserViewSettings
{
BackgroundColor = backgroundColor,
CalendarId = calendarId,
IsHideEvents = hideEvents,
TextColor = textColor,
EventAlertType = alertType,
IsAccepted = true,
UserId = AuthContext.CurrentAccount.ID,
Name = name,
TimeZone = timeZoneInfo
};
DataProvider.UpdateCalendarUserView(settings);
return GetCalendarById(calendarId);
}
/// <summary>
/// Deletes the calendar with the ID specified in the request
/// </summary>
/// <short>
/// Delete calendar
/// </short>
/// <param name="calendarId">Calendar ID</param>
2020-03-12 11:45:21 +00:00
[Delete("{calendarId}")]
public void RemoveCalendar(int calendarId)
{
var cal = DataProvider.GetCalendarById(calendarId);
var events = cal.LoadEvents(AuthContext.CurrentAccount.ID, DateTime.MinValue, DateTime.MaxValue);
var pic = PublicItemCollectionHelper.GetForCalendar(cal);
//check permissions
CheckPermissions(cal, CalendarAccessRights.FullAccessAction);
//clear old rights
AuthorizationManager.RemoveAllAces(cal);
DataProvider.RemoveCalendar(calendarId, HttpContext.Request.GetUrlRewriter());
var sharingList = new List<SharingParam>();
if (pic.Items.Count > 1)
{
sharingList.AddRange(from publicItem in pic.Items
where publicItem.ItemId != AuthContext.CurrentAccount.ID.ToString()
select new SharingParam
{
Id = Guid.Parse(publicItem.ItemId),
isGroup = publicItem.IsGroup,
actionId = publicItem.SharingOption.Id
});
}
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var myUri = HttpContext.Request.GetUrlRewriter();
var caldavHost = myUri.Host;
//TODO Caldav
2020-03-27 12:49:05 +00:00
/*var replaceSharingEventThread = new Thread(() =>
2020-03-12 11:45:21 +00:00
{
TenantManager.SetCurrentTenant(currentTenantId);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID));
foreach (var sharingOption in sharingList)
{
if (!sharingOption.IsGroup)
{
var user = UserManager.GetUsers(sharingOption.itemId);
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
var _email = user.Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(_email).ID);
DataProvider.RemoveCaldavCalendar(currentUserName, _email, currentAccountPaswd, encoded, cal.calDavGuid, myUri, user.ID != cal.OwnerId);
}
else
{
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
foreach (var user in users)
{
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
var _email = user.Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(_email).ID);
DataProvider.RemoveCaldavCalendar(currentUserName, _email, currentAccountPaswd, encoded, cal.calDavGuid, myUri, user.ID != cal.OwnerId);
}
}
}
foreach (var evt in events)
{
if (evt.SharingOptions.PublicItems.Count > 0)
{
var permissions = PublicItemCollectionHelper.GetForEvent(evt);
var so = permissions.Items
.Where(x => x.SharingOption.Id != AccessOption.OwnerOption.Id)
.Select(x => new SharingParam
{
Id = x.Id,
actionId = x.SharingOption.Id,
isGroup = x.IsGroup
}).ToList();
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
foreach (var sharingOption in so)
{
var fullAccess = sharingOption.actionId == AccessOption.FullAccessOption.Id;
if (!sharingOption.IsGroup)
{
var user = UserManager.GetUsers(sharingOption.itemId);
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
deleteEvent(fullAccess ? split[0] + "_write" : split[0], SharedEventsCalendar.CalendarId, user.Email, currentAccountPaswd, myUri, user.ID != evt.OwnerId);
}
else
{
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
foreach (var user in users)
{
var eventUid = user.ID == evt.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
2020-03-27 12:49:05 +00:00
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-12 11:45:21 +00:00
deleteEvent(eventUid, SharedEventsCalendar.CalendarId, user.Email, currentAccountPaswd, myUri, true);
}
}
}
}
}
});
replaceSharingEventThread.Start();*/
}
/// <summary>
/// Unsubscribes the current user from the event with the ID specified in the request
/// </summary>
/// <short>
/// Unsubscribe from event
/// </short>
/// <param name="eventId">Event ID</param>
2020-03-23 13:03:44 +00:00
[Delete("events/{eventId}/unsubscribe")]
public void UnsubscribeEvent(int eventId)
{
var evt = DataProvider.GetEventById(eventId);
if (evt != null)
{
string[] split = evt.Uid.Split(new Char[] { '@' });
var myUri = HttpContext.Request.GetUrlRewriter();
var email = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).Email;
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID);
var fullAccess = CheckPermissions(evt, CalendarAccessRights.FullAccessAction, true);
deleteEvent(fullAccess ? split[0] + "_write" : split[0], SharedEventsCalendar.CalendarId, email, currentAccountPaswd, myUri, SecurityContext.CurrentAccount.ID != evt.OwnerId);
DataProvider.UnsubscribeFromEvent(eventId, SecurityContext.CurrentAccount.ID);
}
}
2020-03-23 13:03:44 +00:00
//TODO Caldav
private void deleteEvent(string uid, string calendarId, string email, string currentAccountPaswd, Uri myUri, bool isShared = false)
{
try
{
2020-03-27 12:49:05 +00:00
var сaldavGuid = "";
2020-03-23 13:03:44 +00:00
if (calendarId != BirthdayReminderCalendar.CalendarId &&
calendarId != SharedEventsCalendar.CalendarId &&
calendarId != "crm_calendar" &&
!calendarId.Contains("Project_"))
{
2020-03-27 12:49:05 +00:00
сaldavGuid = DataProvider.GetCalDavGuid(calendarId);
2020-03-23 13:03:44 +00:00
}
else
{
сaldavGuid = calendarId;
}
if (сaldavGuid != "")
{
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
2020-03-27 12:49:05 +00:00
Log.Info("RADICALE REWRITE URL: " + myUri);
2020-03-23 13:03:44 +00:00
var currentUserName = email + "@" + myUri.Host;
var encoded = isShared ? Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID)) : Convert.ToBase64String(Encoding.UTF8.GetBytes(email.ToLower() + ":" + currentAccountPaswd));
var requestUrl = calDavServerUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" + (isShared ? сaldavGuid + "-shared" : сaldavGuid) + "/" + uid + ".ics";
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
webRequest.Method = "DELETE";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream())) { }
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound || resp.StatusCode == HttpStatusCode.Conflict)
2020-03-27 12:49:05 +00:00
Log.Debug("ERROR: " + ex.Message);
2020-03-23 13:03:44 +00:00
else
2020-03-27 12:49:05 +00:00
Log.Error("ERROR: " + ex.Message);
2020-03-23 13:03:44 +00:00
}
else
{
2020-03-27 12:49:05 +00:00
Log.Error("ERROR: " + ex.Message);
2020-03-23 13:03:44 +00:00
}
}
catch (Exception ex)
{
2020-03-27 12:49:05 +00:00
Log.Error("ERROR: " + ex.Message);
2020-03-23 13:03:44 +00:00
}
2020-03-27 12:49:05 +00:00
}
2020-03-23 13:03:44 +00:00
}
catch (Exception ex)
{
Log.Error("ERROR: " + ex.Message);
}
}
/// <summary>
/// Returns the event in ics format from history
/// </summary>
/// <short>
/// Returns the event in ics format from history
/// </short>
/// <param name="eventUid">Event UID</param>
/// <returns>Event History</returns>
2020-03-03 12:29:07 +00:00
[Read("events/{eventUid}/historybyuid")]
public EventHistoryWrapper GetEventHistoryByUid(string eventUid)
{
if (string.IsNullOrEmpty(eventUid))
{
throw new ArgumentException("eventUid");
}
var evt = DataProvider.GetEventByUid(eventUid);
return GetEventHistoryWrapper(evt);
}
/// <summary>
/// Returns the event in ics format from history
/// </summary>
/// <short>
/// Returns the event in ics format from history
/// </short>
/// <param name="eventId">Event ID</param>
/// <returns>Event History</returns>
2020-03-23 12:39:01 +00:00
[Read("events/{eventId}/historybyid")]
public EventHistoryWrapper GetEventHistoryById(int eventId)
{
if (eventId <= 0)
{
throw new ArgumentException("eventId");
}
2020-03-06 06:56:05 +00:00
2020-03-23 12:39:01 +00:00
var evt = DataProvider.GetEventById(eventId);
return GetEventHistoryWrapper(evt);
}
/// <summary>
/// Creates the new event in the default calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Create new event
/// </short>
/// <param name="name">Event name</param>
/// <param name="description">Event description</param>
/// <param name="startDate">Event start date</param>
/// <param name="endDate">Event end date</param>
/// <param name="repeatType">Event recurrence type (RRULE string in iCal format)</param>
/// <param name="alertType">Event notification type</param>
/// <param name="isAllDayLong">Event duration type: all day long or not</param>
/// <param name="sharingOptions">Event sharing access parameters</param>
/// <returns>Event list</returns>
2020-03-10 12:52:20 +00:00
[Create("event")]
public List<EventWrapper> CreateEvent(EventModel eventModel)
{
var calendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
int calendarId;
if (int.TryParse(calendar.Id, out calendarId))
{
return AddEvent(calendarId, eventModel);
}
throw new Exception(string.Format("Can't parse {0} to int", calendar.Id));
}
/// <summary>
/// Creates the new event in the selected calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Create new event
/// </short>
/// <param name="calendarId">ID of the calendar where the event is created</param>
/// <param name="name">Event name</param>
/// <param name="description">Event description</param>
/// <param name="startDate">Event start date</param>
/// <param name="endDate">Event end date</param>
/// <param name="repeatType">Event recurrence type (RRULE string in iCal format)</param>
/// <param name="alertType">Event notification type</param>
/// <param name="isAllDayLong">Event duration type: all day long or not</param>
/// <param name="sharingOptions">Event sharing access parameters</param>
/// <returns>Event list</returns>
2020-03-10 12:52:20 +00:00
[Create("{calendarId}/event")]
public List<EventWrapper> AddEvent(int calendarId, EventModel eventModel)
{
eventModel.CalendarId = calendarId.ToString();
return AddEvent(eventModel);
}
/// <summary>
/// Updates the existing event in the selected calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Update event
/// </short>
/// <param name="calendarId">ID of the calendar where the event belongs</param>
/// <param name="eventId">Event ID</param>
/// <param name="name">Event new name</param>
/// <param name="description">Event new description</param>
/// <param name="startDate">Event start date</param>
/// <param name="endDate">Event end date</param>
/// <param name="repeatType">Event recurrence type (RRULE string in iCal format)</param>
/// <param name="alertType">Event notification type</param>
/// <param name="isAllDayLong">Event duration type: all day long or not</param>
/// <param name="sharingOptions">Event sharing access parameters</param>
/// <param name="status">Event status</param>
/// <returns>Updated event list</returns>
2020-03-10 12:52:20 +00:00
[Update("{calendarId}/{eventId}")]
public List<EventWrapper> Update(string calendarId, int eventId, EventModel eventModel)
{
eventModel.CalendarId = calendarId;
eventModel.EventId = eventId;
return UpdateEvent(eventModel);
}
/// <summary>
/// Creates the new event in the selected calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Create new event
/// </short>
/// <param name="calendarId">ID of the calendar where the event is created</param>
/// <param name="ics">Event in iCal format</param>
/// <param name="alertType">Event notification type</param>
/// <param name="sharingOptions">Event sharing access parameters</param>
/// <param name="eventUid">Event uid</param>
/// <returns>Event</returns>
2020-03-06 06:56:05 +00:00
[Create("icsevent")]
public List<EventWrapper> AddEvent(EventModel eventData)
{
var calendarId = eventData.CalendarId;
2020-03-10 08:05:31 +00:00
var eventUid = eventData.EventUid;
2020-03-06 06:56:05 +00:00
var ics = eventData.Ics;
var old_ics = eventData.Ics;
2020-03-10 08:05:31 +00:00
int calId;
if (!int.TryParse(calendarId, out calId))
{
calId = int.Parse(eventData.CalendarId);
}
if (calId <= 0)
2020-03-06 06:56:05 +00:00
{
var defaultCalendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
2020-03-10 08:05:31 +00:00
if (!int.TryParse(defaultCalendar.Id, out calId))
2020-03-06 06:56:05 +00:00
throw new Exception(string.Format("Can't parse {0} to int", defaultCalendar.Id));
}
var calendars = DDayICalParser.DeserializeCalendar(ics);
if (calendars == null) return null;
var calendar = calendars.FirstOrDefault();
if (calendar == null || calendar.Events == null) return null;
var eventObj = calendar.Events.FirstOrDefault();
if (eventObj == null) return null;
2020-03-10 08:05:31 +00:00
var calendarObj = DataProvider.GetCalendarById(calId);
2020-03-06 06:56:05 +00:00
var calendarObjViewSettings = calendarObj != null && calendarObj.ViewSettings != null ? calendarObj.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(calendarObj?.GetUserCalendar(calendarObjViewSettings));
if (targetCalendar == null) return null;
var rrule = GetRRuleString(eventObj);
var utcStartDate = eventObj.IsAllDay ? eventObj.Start.Value : DDayICalParser.ToUtc(eventObj.Start);
var utcEndDate = eventObj.IsAllDay ? eventObj.End.Value : DDayICalParser.ToUtc(eventObj.End);
if (eventObj.IsAllDay && utcStartDate.Date < utcEndDate.Date)
utcEndDate = utcEndDate.AddDays(-1);
eventUid = eventUid == null ? null : string.Format("{0}@onlyoffice.com", eventUid);
2020-03-10 08:05:31 +00:00
var result = CreateEvent(calId,
2020-03-06 06:56:05 +00:00
eventObj.Summary,
eventObj.Description,
utcStartDate,
utcEndDate,
RecurrenceRule.Parse(rrule),
eventData.AlertType,
eventObj.IsAllDay,
eventData.SharingOptions,
DataProvider.GetEventUid(eventUid),
EventStatus.Confirmed,
eventObj.Created != null ? eventObj.Created.Value : DateTime.Now);
if (result == null || !result.Any()) return null;
var evt = result.First();
eventObj.Uid = evt.Uid;
eventObj.Sequence = 0;
eventObj.Status = Ical.Net.EventStatus.Confirmed;
targetCalendar.Method = Ical.Net.CalendarMethods.Request;
targetCalendar.Events.Clear();
targetCalendar.Events.Add(eventObj);
ics = DDayICalParser.SerializeCalendar(targetCalendar);
//TODO caldav
2020-03-27 12:49:05 +00:00
try
2020-03-06 06:56:05 +00:00
{
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
var calDavGuid = calendarObj != null ? calendarObj.calDavGuid : "";
2020-03-27 12:49:05 +00:00
var myUri = HttpContext.Request.GetUrlRewriter();
2020-03-06 06:56:05 +00:00
var userId = SecurityContext.CurrentAccount.ID;
2020-03-27 12:49:05 +00:00
var currentUserEmail = UserManager.GetUsers(userId).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, userId);
2020-03-06 06:56:05 +00:00
var currentEventUid = split[0];
2020-03-27 12:49:05 +00:00
var pic = PublicItemCollectionHelper.GetForCalendar(calendarObj);
2020-03-06 06:56:05 +00:00
var sharingList = new List<SharingParam>();
if (pic.Items.Count > 1)
{
sharingList.AddRange(from publicItem in pic.Items
where publicItem.ItemId != SecurityContext.CurrentAccount.ID.ToString()
select new SharingParam
{
Id = Guid.Parse(publicItem.ItemId),
isGroup = publicItem.IsGroup,
actionId = publicItem.SharingOption.Id
});
}
2020-03-27 12:49:05 +00:00
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
2020-03-06 06:56:05 +00:00
if (!calendarObj.OwnerId.Equals(SecurityContext.CurrentAccount.ID) && CheckPermissions(calendarObj, CalendarAccessRights.FullAccessAction, true))
{
currentEventUid = currentEventUid + "_write";
}
2020-03-27 12:49:05 +00:00
var updateCaldavThread = new Thread(() =>
2020-03-06 06:56:05 +00:00
{
updateCaldavEvent(old_ics, currentEventUid, true, calDavGuid, myUri,
currentUserEmail, currentAccountPaswd, DateTime.Now,
targetCalendar.TimeZones[0], calendarObj.TimeZone, false, userId != calendarObj.OwnerId);
2020-03-27 12:49:05 +00:00
TenantManager.SetCurrentTenant(currentTenantId);
2020-03-06 06:56:05 +00:00
//calendar sharing list
foreach (var sharingOption in sharingList)
{
var fullAccess = sharingOption.actionId == AccessOption.FullAccessOption.Id;
if (!sharingOption.IsGroup)
{
2020-03-27 12:49:05 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
var userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-06 06:56:05 +00:00
var sharedEventUid = user.ID == calendarObj.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
updateCaldavEvent(old_ics, sharedEventUid, true, calDavGuid, myUri,
user.Email, userPaswd, DateTime.Now, targetCalendar.TimeZones[0],
calendarObj.TimeZone, false, user.ID != calendarObj.OwnerId);
}
else
{
2020-03-27 12:49:05 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-06 06:56:05 +00:00
foreach (var user in users)
{
var sharedEventUid = user.ID == calendarObj.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
2020-03-27 12:49:05 +00:00
var userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-06 06:56:05 +00:00
updateCaldavEvent(old_ics, sharedEventUid, true, calDavGuid, myUri,
user.Email, userPaswd, DateTime.Now, targetCalendar.TimeZones[0],
calendarObj.TimeZone, false, user.ID != calendarObj.OwnerId);
}
}
}
//event sharing list
2020-03-27 12:49:05 +00:00
foreach (var sharingOption in eventData.SharingOptions)
2020-03-06 06:56:05 +00:00
{
var fullAccess = sharingOption.actionId == AccessOption.FullAccessOption.Id;
if (!sharingOption.IsGroup)
{
2020-03-27 12:49:05 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
var userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-06 06:56:05 +00:00
var sharedEventUid = user.ID == calendarObj.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
updateCaldavEvent(old_ics, sharedEventUid, true, SharedEventsCalendar.CalendarId, myUri,
user.Email, userPaswd, DateTime.Now, targetCalendar.TimeZones[0],
calendarObj.TimeZone, false, user.ID != calendarObj.OwnerId);
}
else
{
2020-03-27 12:49:05 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-06 06:56:05 +00:00
foreach (var user in users)
{
var sharedEventUid = user.ID == calendarObj.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
2020-03-27 12:49:05 +00:00
var userPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-06 06:56:05 +00:00
updateCaldavEvent(old_ics, sharedEventUid, true, SharedEventsCalendar.CalendarId, myUri,
user.Email, userPaswd, DateTime.Now, targetCalendar.TimeZones[0],
calendarObj.TimeZone, false, user.ID != calendarObj.OwnerId);
}
}
}
});
updateCaldavThread.Start();
}
catch (Exception e)
{
2020-03-27 12:49:05 +00:00
Log.Error(e.Message);
}
2020-03-06 06:56:05 +00:00
2020-03-10 08:05:31 +00:00
DataProvider.AddEventHistory(calId, evt.Uid, int.Parse(evt.Id), ics);
2020-03-06 06:56:05 +00:00
return result;
}
/// <summary>
/// Updates the existing event in the selected calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Update event
/// </short>
/// <param name="eventId">Event ID</param>
/// <param name="calendarId">ID of the calendar where the event belongs</param>
/// <param name="ics">Event in iCal format</param>
/// <param name="alertType">Event notification type</param>
/// <param name="sharingOptions">Event sharing access parameters</param>
/// <param name="fromCalDavServer">bool flag says that request from caldav server</param>
/// <param name="ownerId">Event owner id</param>
/// <returns>Updated event</returns>
2020-03-12 11:45:21 +00:00
[Update("icsevent.json")]
2020-03-10 08:05:31 +00:00
public List<EventWrapper> UpdateEvent(EventModel eventData)
{
var fromCalDavServer = eventData.FromCalDavServer;
var ownerId = eventData.OwnerId ?? "";
var ics = eventData.Ics;
var old_ics = eventData.Ics;
var calendarId = eventData.CalendarId;
var evt = DataProvider.GetEventById(eventData.EventId);
if (evt == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
var cal = DataProvider.GetCalendarById(Int32.Parse(evt.CalendarId));
if (!fromCalDavServer)
{
if (!evt.OwnerId.Equals(AuthContext.CurrentAccount.ID) &&
!CheckPermissions(evt, CalendarAccessRights.FullAccessAction, true) &&
!CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true))
throw new System.Security.SecurityException(Resources.CalendarApiResource.ErrorAccessDenied);
}
int calId;
if (!int.TryParse(calendarId, out calId))
{
calId = int.Parse(evt.CalendarId);
}
EventHistory evtHistory = null;
if (string.IsNullOrEmpty(evt.Uid))
{
evt.Uid = DataProvider.GetEventUid(evt.Uid);
DataProvider.SetEventUid(eventData.EventId, evt.Uid);
}
else
{
evtHistory = DataProvider.GetEventHistory(eventData.EventId);
}
var sequence = 0;
if (evtHistory != null)
{
var maxSequence = evtHistory.History.Select(x => x.Events.First()).Max(x => x.Sequence);
if (!fromCalDavServer)
{
if (evt.OwnerId == AuthContext.CurrentAccount.ID && !CheckIsOrganizer(evtHistory))
sequence = maxSequence;
else
sequence = maxSequence + 1;
}
}
var calendars = DDayICalParser.DeserializeCalendar(ics);
if (calendars == null) return null;
var calendar = calendars.FirstOrDefault();
if (calendar == null || calendar.Events == null) return null;
var eventObj = calendar.Events.FirstOrDefault();
if (eventObj == null) return null;
var calendarObj = DataProvider.GetCalendarById(calId);
var calendarObjViewSettings = calendarObj != null && calendarObj.ViewSettings != null ? calendarObj.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(calendarObj != null ? calendarObj.GetUserCalendar(calendarObjViewSettings) : null);
if (targetCalendar == null) return null;
eventObj.Uid = evt.Uid;
eventObj.Sequence = sequence;
//eventObj.ExceptionDates.Clear();
targetCalendar.Method = Ical.Net.CalendarMethods.Request;
targetCalendar.Events.Clear();
targetCalendar.Events.Add(eventObj);
ics = (evtHistory != null ? (evtHistory.Ics + Environment.NewLine) : string.Empty) + DDayICalParser.SerializeCalendar(targetCalendar);
DataProvider.RemoveEventHistory(eventData.EventId);
evtHistory = DataProvider.AddEventHistory(calId, evt.Uid, eventData.EventId, ics);
var mergedCalendar = EventHistoryHelper.GetMerged(evtHistory);
if (mergedCalendar == null || mergedCalendar.Events == null || !mergedCalendar.Events.Any()) return null;
var mergedEvent = mergedCalendar.Events.First();
var rrule = GetRRuleString(mergedEvent);
var utcStartDate = eventObj.IsAllDay ? eventObj.Start.Value : DDayICalParser.ToUtc(eventObj.Start);
var utcEndDate = eventObj.IsAllDay ? eventObj.End.Value : DDayICalParser.ToUtc(eventObj.End);
var createDate = mergedEvent.Created != null ? mergedEvent.Created.Value : DateTime.Now;
if (eventObj.IsAllDay && utcStartDate.Date < utcEndDate.Date)
utcEndDate = utcEndDate.AddDays(-1);
if (!fromCalDavServer)
{
try
{
var uid = evt.Uid;
string[] uidData = uid.Split(new Char[] { '@' });
var calDavGuid = calendarObj != null ? calendarObj.calDavGuid : "";
var myUri = HttpContext.Request.GetUrlRewriter();
var currentUserEmail = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
var isFullAccess = PermissionContext.PermissionResolver.Check(AuthContext.CurrentAccount, (ISecurityObject)evt, null,
CalendarAccessRights.FullAccessAction);
var isShared = false;
if (calendarId == BirthdayReminderCalendar.CalendarId ||
calendarId == SharedEventsCalendar.CalendarId ||
calendarId == "crm_calendar")
{
calDavGuid = calendarId;
isShared = true;
}
else
{
isShared = calendarObj != null && calendarObj.OwnerId != AuthContext.CurrentAccount.ID;
}
var eventUid = isShared && isFullAccess ? uidData[0] + "_write" : uidData[0];
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var pic = PublicItemCollectionHelper.GetForCalendar(cal);
var calendarCharingList = new List<SharingParam>();
if (pic.Items.Count > 1)
{
calendarCharingList.AddRange(from publicItem in pic.Items
where publicItem.ItemId != calendarObj.OwnerId.ToString()
select new SharingParam
{
Id = Guid.Parse(publicItem.ItemId),
isGroup = publicItem.IsGroup,
actionId = publicItem.SharingOption.Id
});
}
//TODO caldav
2020-03-27 13:14:23 +00:00
2020-03-10 08:05:31 +00:00
var sharingEventThread = new Thread(() =>
{
2020-03-27 13:14:23 +00:00
TenantManager.SetCurrentTenant(currentTenantId);
2020-03-10 08:05:31 +00:00
//event sharing ptions
2020-03-27 13:14:23 +00:00
foreach (var sharingOption in eventData.SharingOptions)
2020-03-10 08:05:31 +00:00
{
if (!sharingOption.IsGroup)
{
2020-03-27 13:14:23 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
2020-03-10 08:05:31 +00:00
ReplaceSharingEvent(user, sharingOption.actionId, uidData[0], myUri, old_ics,
calendarId, createDate, targetCalendar.TimeZones[0],
calendarObj.TimeZone);
}
else
{
2020-03-27 13:14:23 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-10 08:05:31 +00:00
foreach (var user in users)
{
ReplaceSharingEvent(user, sharingOption.actionId, uidData[0], myUri, old_ics,
calendarId, createDate, targetCalendar.TimeZones[0],
calendarObj.TimeZone);
}
}
}
//calendar sharing ptions
foreach (var sharingOption in calendarCharingList)
{
if (!sharingOption.IsGroup)
{
2020-03-27 13:14:23 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
2020-03-10 08:05:31 +00:00
ReplaceSharingEvent(user, sharingOption.actionId, uidData[0], myUri, old_ics,
calendarId, createDate, targetCalendar.TimeZones[0],
calendarObj.TimeZone, cal.calDavGuid);
}
else
{
2020-03-27 13:14:23 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-10 08:05:31 +00:00
foreach (var user in users)
{
ReplaceSharingEvent(user, sharingOption.actionId, uidData[0], myUri, old_ics,
calendarId, createDate, targetCalendar.TimeZones[0],
calendarObj.TimeZone, cal.calDavGuid);
}
}
}
if (!isShared)
{
updateCaldavEvent(old_ics, eventUid, true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd, createDate, targetCalendar.TimeZones[0], calendarObj.TimeZone, false, isShared);
}
else
{
2020-03-27 13:14:23 +00:00
var owner = UserManager.GetUsers(evt.OwnerId);
var ownerPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, evt.OwnerId);
2020-03-10 08:05:31 +00:00
updateCaldavEvent(old_ics, uidData[0], true, calendarObj.calDavGuid, myUri, owner.Email, ownerPaswd, createDate, targetCalendar.TimeZones[0], calendarObj.TimeZone, false, false);
}
});
sharingEventThread.Start();
}
catch (Exception e)
{
Log.Error(e.Message);
}
}
return UpdateEvent(calendarId,
eventData.EventId,
eventObj.Summary,
eventObj.Description,
new ApiDateTime(utcStartDate, TimeZoneInfo.Utc.GetOffset()),
new ApiDateTime(utcEndDate, TimeZoneInfo.Utc.GetOffset()),
rrule,
eventData.AlertType,
eventObj.IsAllDay,
eventData.SharingOptions,
DDayICalParser.ConvertEventStatus(mergedEvent.Status), createDate,
fromCalDavServer, ownerId);
}
2020-03-10 11:49:09 +00:00
/// <summary>
/// Deletes the whole event from the calendar (all events in the series)
/// </summary>
/// <short>
/// Delete event series
/// </short>
/// <param name="eventId">Event ID</param>
2020-03-10 11:49:09 +00:00
[Delete("events/{eventId}")]
public void RemoveEvent(int eventId)
{
RemoveEvent(eventId, new EventDeleteModel { EventId = eventId, Date = null, Type = EventRemoveType.AllSeries });
}
/// <summary>
/// Deletes one event from the series of recurrent events
/// </summary>
/// <short>
/// Delete event
/// </short>
/// <param name="eventId">Event ID</param>
/// <param name="date">Date to be deleted from the recurrent event</param>
/// <param name="type">Recurrent event deletion type</param>
/// <param name="fromCaldavServer">Bool flag says that request from caldav server</param>
/// <param name="uri">Current uri</param>
/// <returns>Updated event series collection</returns>
2020-03-10 11:49:09 +00:00
[Delete("events/{eventId}/custom")]
public List<EventWrapper> RemoveEvent(int eventId, EventDeleteModel eventDeleteModel)
{
var events = new List<EventWrapper>();
var evt = DataProvider.GetEventById(eventId);
2020-03-10 08:05:31 +00:00
2020-03-10 11:49:09 +00:00
if (evt == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
var cal = DataProvider.GetCalendarById(Convert.ToInt32(evt.CalendarId));
var pic = PublicItemCollectionHelper.GetForCalendar(cal);
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
var sharingList = new List<SharingParam>();
if (pic.Items.Count > 1)
{
sharingList.AddRange(from publicItem in pic.Items
where publicItem.ItemId != cal.OwnerId.ToString()
select new SharingParam
{
Id = Guid.Parse(publicItem.ItemId),
isGroup = publicItem.IsGroup,
actionId = publicItem.SharingOption.Id
});
}
var permissions = PublicItemCollectionHelper.GetForEvent(evt);
var so = permissions.Items
.Where(x => x.SharingOption.Id != AccessOption.OwnerOption.Id)
.Select(x => new SharingParam
{
Id = x.Id,
actionId = x.SharingOption.Id,
isGroup = x.IsGroup
}).ToList();
var currentTenantId = TenantManager.GetCurrentTenant().TenantId;
var calendarId = evt.CalendarId;
var myUri = HttpContext.Request != null ? HttpContext.Request.GetUrlRewriter() : eventDeleteModel.Uri ?? new Uri("http://localhost");
var currentUserId = AuthContext.CurrentAccount.ID;
//TODO Caldav
2020-03-27 13:14:23 +00:00
var removeEventThread = new Thread(() =>
2020-03-10 11:49:09 +00:00
{
2020-03-27 13:14:23 +00:00
TenantManager.SetCurrentTenant(currentTenantId);
2020-03-10 11:49:09 +00:00
//calendar sharing list
foreach (var sharingOption in sharingList)
{
var fullAccess = sharingOption.actionId == AccessOption.FullAccessOption.Id;
if (!sharingOption.IsGroup)
{
2020-03-27 13:14:23 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-10 11:49:09 +00:00
deleteEvent(fullAccess ? split[0] + "_write" : split[0], calendarId, user.Email, currentAccountPaswd, myUri, user.ID != cal.OwnerId);
}
else
{
2020-03-27 13:14:23 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-10 11:49:09 +00:00
foreach (var user in users)
{
var eventUid = user.ID == evt.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
2020-03-27 13:14:23 +00:00
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-10 11:49:09 +00:00
deleteEvent(eventUid, calendarId, user.Email, currentAccountPaswd, myUri, true);
}
}
}
//event sharing list
foreach (var sharingOption in so)
{
var fullAccess = sharingOption.actionId == AccessOption.FullAccessOption.Id;
if (!sharingOption.IsGroup)
{
2020-03-27 13:14:23 +00:00
var user = UserManager.GetUsers(sharingOption.itemId);
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-10 11:49:09 +00:00
deleteEvent(fullAccess ? split[0] + "_write" : split[0], SharedEventsCalendar.CalendarId, user.Email, currentAccountPaswd, myUri, user.ID != evt.OwnerId);
}
else
{
2020-03-27 13:14:23 +00:00
var users = UserManager.GetUsersByGroup(sharingOption.itemId);
2020-03-10 11:49:09 +00:00
foreach (var user in users)
{
var eventUid = user.ID == evt.OwnerId
? split[0]
: fullAccess ? split[0] + "_write" : split[0];
2020-03-27 13:14:23 +00:00
var currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID);
2020-03-10 11:49:09 +00:00
deleteEvent(eventUid, SharedEventsCalendar.CalendarId, user.Email, currentAccountPaswd, myUri, true);
}
}
}
if (currentUserId == evt.OwnerId)
{
2020-03-27 13:14:23 +00:00
var owner = UserManager.GetUsers(evt.OwnerId);
var ownerPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, evt.OwnerId);
2020-03-10 11:49:09 +00:00
deleteEvent(split[0], evt.CalendarId, owner.Email, ownerPaswd, myUri, false);
}
if (calendarId != BirthdayReminderCalendar.CalendarId &&
calendarId != SharedEventsCalendar.CalendarId &&
calendarId != "crm_calendar" &&
!calendarId.Contains("Project_"))
{
if (currentUserId == cal.OwnerId)
{
2020-03-27 13:14:23 +00:00
var owner = UserManager.GetUsers(currentUserId);
var ownerPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, currentUserId);
2020-03-10 11:49:09 +00:00
deleteEvent(split[0], evt.CalendarId, owner.Email, ownerPaswd, myUri, false);
}
}
2020-03-27 13:14:23 +00:00
});
2020-03-10 11:49:09 +00:00
if (evt.OwnerId.Equals(AuthContext.CurrentAccount.ID) || CheckPermissions(evt, CalendarAccessRights.FullAccessAction, true) || CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true))
{
if (eventDeleteModel.Type == EventRemoveType.AllSeries || evt.RecurrenceRule.Freq == Frequency.Never)
{
DataProvider.RemoveEvent(eventId);
//TODO Caldav
2020-03-27 13:14:23 +00:00
if (!eventDeleteModel.FromCaldavServer)
2020-03-10 11:49:09 +00:00
{
var ownerId = SecurityContext.CurrentAccount.ID != cal.OwnerId ? cal.OwnerId : SecurityContext.CurrentAccount.ID;
2020-03-27 13:14:23 +00:00
var email = UserManager.GetUsers(ownerId).Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, ownerId);
2020-03-10 11:49:09 +00:00
deleteEvent(split[0], evt.CalendarId, email, currentAccountPaswd, myUri);
removeEventThread.Start();
2020-03-27 13:14:23 +00:00
}
2020-03-10 11:49:09 +00:00
return events;
}
var utcDate = evt.AllDayLong
? eventDeleteModel.Date.UtcTime.Date
: TimeZoneInfo.ConvertTime(new DateTime(eventDeleteModel.Date.UtcTime.Ticks),
cal.ViewSettings.Any() && cal.ViewSettings.First().TimeZone != null
? cal.ViewSettings.First().TimeZone
: cal.TimeZone,
TimeZoneInfo.Utc);
if (eventDeleteModel.Type == EventRemoveType.Single)
{
evt.RecurrenceRule.ExDates.Add(new RecurrenceRule.ExDate
{
Date = evt.AllDayLong ? utcDate.Date : utcDate,
isDateTime = !evt.AllDayLong
});
}
else if (eventDeleteModel.Type == EventRemoveType.AllFollowing)
{
var lastEventDate = evt.AllDayLong ? utcDate.Date : utcDate;
var dates = evt.RecurrenceRule
.GetDates(evt.UtcStartDate, evt.UtcStartDate, evt.UtcStartDate.AddMonths(_monthCount), int.MaxValue, false)
.Where(x => x < lastEventDate)
.ToList();
var untilDate = dates.Any() ? dates.Last() : evt.UtcStartDate.AddDays(-1);
evt.RecurrenceRule.Until = evt.AllDayLong ? untilDate.Date : untilDate;
}
evt = DataProvider.UpdateEvent(int.Parse(evt.Id), evt.Uid, int.Parse(evt.CalendarId), evt.OwnerId, evt.Name, evt.Description,
evt.UtcStartDate, evt.UtcEndDate, evt.RecurrenceRule, evt.AlertType, evt.AllDayLong,
evt.SharingOptions.PublicItems, evt.Status, DateTime.Now);
if (!eventDeleteModel.FromCaldavServer)
{
try
{
var calDavGuid = cal != null ? cal.calDavGuid : "";
var currentUserEmail = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
var calendarObj = DataProvider.GetCalendarById(Convert.ToInt32(cal.Id));
var calendarObjViewSettings = calendarObj != null && calendarObj.ViewSettings != null ? calendarObj.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(calendarObj != null ? calendarObj.GetUserCalendar(calendarObjViewSettings) : null);
targetCalendar.Events.Clear();
var convertedEvent = DDayICalParser.ConvertEvent(evt as BaseEvent);
convertedEvent.ExceptionDates.Clear();
foreach (var exDate in evt.RecurrenceRule.ExDates)
{
var periodList = new PeriodList { new CalDateTime(exDate.Date) };
if (exDate.isDateTime)
{
periodList.Parameters.Add("TZID", targetCalendar.TimeZones[0].TzId);
}
else
{
periodList.Parameters.Add("VALUE", "DATE");
}
convertedEvent.ExceptionDates.Add(periodList);
}
targetCalendar.Events.Add(convertedEvent);
var ics = DDayICalParser.SerializeCalendar(targetCalendar);
//TODo Caldav
2020-03-27 13:14:23 +00:00
var updateCaldavThread = new Thread(() => updateCaldavEvent(ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd, DateTime.Now, targetCalendar.TimeZones[0], cal.TimeZone, true));
updateCaldavThread.Start();
2020-03-10 11:49:09 +00:00
}
catch (Exception e)
{
Log.Error(e.Message);
}
}
if (eventDeleteModel.Type != EventRemoveType.AllSeries)
{
var history = DataProvider.GetEventHistory(eventId);
if (history != null)
{
var mergedCalendar = EventHistoryHelper.GetMerged(history);
if (mergedCalendar != null && mergedCalendar.Events != null && mergedCalendar.Events.Any())
{
if (evt.OwnerId != AuthContext.CurrentAccount.ID || CheckIsOrganizer(history))
{
mergedCalendar.Events[0].Sequence++;
}
mergedCalendar.Events[0].RecurrenceRules.Clear();
mergedCalendar.Events[0].RecurrenceRules.Add(DDayICalParser.DeserializeRecurrencePattern(evt.RecurrenceRule.ToString(true)));
mergedCalendar.Events[0].ExceptionDates.Clear();
foreach (var exDate in evt.RecurrenceRule.ExDates)
{
mergedCalendar.Events[0].ExceptionDates.Add(new Ical.Net.DataTypes.PeriodList
{
exDate.isDateTime ?
new Ical.Net.DataTypes.CalDateTime(exDate.Date.Year, exDate.Date.Month, exDate.Date.Day, exDate.Date.Hour, exDate.Date.Minute, exDate.Date.Second) :
new Ical.Net.DataTypes.CalDateTime(exDate.Date.Year, exDate.Date.Month, exDate.Date.Day)
});
}
DataProvider.AddEventHistory(int.Parse(evt.CalendarId), evt.Uid, int.Parse(evt.Id), DDayICalParser.SerializeCalendar(mergedCalendar));
}
}
}
//define timeZone
TimeZoneInfo timeZone;
if (!CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true))
{
timeZone = DataProvider.GetTimeZoneForSharedEventsCalendar(AuthContext.CurrentAccount.ID);
evt.CalendarId = SharedEventsCalendar.CalendarId;
}
else
timeZone = DataProvider.GetTimeZoneForCalendar(AuthContext.CurrentAccount.ID, int.Parse(evt.CalendarId));
var eventWrapper = EventWrapperHelper.Get(evt, AuthContext.CurrentAccount.ID, timeZone);
events = EventWrapperHelper.GetList(evt.UtcStartDate, evt.UtcStartDate.AddMonths(_monthCount), eventWrapper.UserId, evt);
}
else
DataProvider.UnsubscribeFromEvent(eventId, AuthContext.CurrentAccount.ID);
return events;
}
2020-03-16 08:41:25 +00:00
public class CreateTodoModel
{
public string ics { get; set; }
public string todoUid { get; set; }
2020-03-16 11:05:56 +00:00
public string todoId { get; set; }
public string calendarId { get; set; }
public bool fromCalDavServer { get; set; }
2020-03-16 08:41:25 +00:00
}
/// <summary>
/// Creates the new task in the selected calendar with the parameters specified in the request
/// </summary>
/// <short>
/// Create new task
/// </short>
/// <param name="ics">Task in iCal format</param>
/// <param name="todoUid">Task uid</param>
/// <returns>Todo</returns>
2020-03-16 08:41:25 +00:00
[Create("icstodo")]
public List<TodoWrapper> AddTodo(CreateTodoModel createTodoModel)
{
var ics = createTodoModel.ics;
var todoUid = createTodoModel.todoUid;
var old_ics = ics;
var todoCalendars = DataProvider.LoadTodoCalendarsForUser(AuthContext.CurrentAccount.ID);
var userTimeZone = TenantManager.GetCurrentTenant().TimeZone;
2020-03-19 12:09:03 +00:00
var icalendar = new iCalendar(AuthContext, TimeZoneConverter, TenantManager);
var newCalendar = new BusinessObjects.Calendar(AuthContext, TimeZoneConverter, icalendar, DataProvider);
2020-03-16 08:41:25 +00:00
var todoCal = CalendarWrapperHelper.Get(newCalendar);
if (todoCalendars.Count == 0)
{
todoCal = CreateCalendar(new CalendarModel
{
Name = "Todo_calendar",
Description = "",
TextColor = BusinessObjects.Calendar.DefaultTextColor,
BackgroundColor = BusinessObjects.Calendar.DefaultTodoBackgroundColor,
TimeZone = userTimeZone.ToString(),
AlertType = EventAlertType.FifteenMinutes,
SharingOptions = null,
ICalUrl = null,
IsTodo = 1,
});
}
var calendarId = Convert.ToInt32(todoCalendars.Count == 0 ? todoCal.Id : todoCalendars.FirstOrDefault().Id);
if (calendarId <= 0)
{
var defaultCalendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
if (!int.TryParse(defaultCalendar.Id, out calendarId))
throw new Exception(string.Format("Can't parse {0} to int", defaultCalendar.Id));
}
var calendars = DDayICalParser.DeserializeCalendar(ics);
if (calendars == null) return null;
var calendar = calendars.FirstOrDefault();
if (calendar == null || calendar.Todos == null) return null;
var todoObj = calendar.Todos.FirstOrDefault();
if (todoObj == null) return null;
var calendarObj = todoCalendars.Count == 0 ? DataProvider.GetCalendarById(Convert.ToInt32(todoCal.Id)) : todoCalendars.FirstOrDefault();
var calendarObjViewSettings = calendarObj != null && calendarObj.ViewSettings != null ? calendarObj.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(calendarObj?.GetUserCalendar(calendarObjViewSettings));
if (targetCalendar == null) return null;
var utcStartDate = todoObj.Start != null ? DDayICalParser.ToUtc(todoObj.Start) : DateTime.MinValue;
todoUid = todoUid == null ? null : string.Format("{0}@onlyoffice.com", todoUid);
var result = CreateTodo(calendarId,
todoObj.Summary,
todoObj.Description,
utcStartDate,
DataProvider.GetEventUid(todoUid),
DateTime.MinValue);
if (result == null || !result.Any()) return null;
var todo = result.First();
todoObj.Uid = todo.Uid;
targetCalendar.Method = Ical.Net.CalendarMethods.Request;
targetCalendar.Todos.Clear();
targetCalendar.Todos.Add(todoObj);
try
{
var uid = todo.Uid;
string[] split = uid.Split(new Char[] { '@' });
var calDavGuid = calendarObj != null ? calendarObj.calDavGuid : "";
var myUri = HttpContext.Request.GetUrlRewriter();
var currentUserEmail = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
//TODO Caldav
2020-03-27 13:14:23 +00:00
var updateCaldavThread = new Thread(() => updateCaldavEvent(old_ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd));
updateCaldavThread.Start();
2020-03-16 08:41:25 +00:00
}
catch (Exception e)
{
Log.Error(e.Message);
}
return result;
}
2020-03-16 11:05:56 +00:00
/// <summary>
/// Updates the existing task with the parameters specified in the request
/// </summary>
/// <short>
/// Update task
/// </short>
/// <param name="todoId">Task ID</param>
/// <param name="calendarId">ID of the calendar where the task belongs</param>
/// <param name="ics">Task in iCal format</param>
/// <param name="fromCalDavServer">bool flag says that request from caldav server</param>
/// <returns>Updated task</returns>
2020-03-16 11:05:56 +00:00
[Update("icstodo")]
public List<TodoWrapper> UpdateTodo(CreateTodoModel createTodoModel)
{
var ics = createTodoModel.ics;
var todoId = createTodoModel.todoId;
var calendarId = createTodoModel.calendarId;
var fromCalDavServer = createTodoModel.fromCalDavServer;
var todo = DataProvider.GetTodoById(Convert.ToInt32(todoId));
if (todo == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
var old_ics = ics;
var cal = DataProvider.GetCalendarById(Int32.Parse(todo.CalendarId));
if (!fromCalDavServer)
{
if (!todo.OwnerId.Equals(AuthContext.CurrentAccount.ID) &&
!CheckPermissions(todo, CalendarAccessRights.FullAccessAction, true) &&
!CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true))
throw new System.Security.SecurityException(Resources.CalendarApiResource.ErrorAccessDenied);
}
int calId;
if (!int.TryParse(calendarId, out calId))
{
calId = int.Parse(todo.CalendarId);
}
var calendars = DDayICalParser.DeserializeCalendar(ics);
if (calendars == null) return null;
var calendar = calendars.FirstOrDefault();
if (calendar == null || calendar.Events == null) return null;
var todoObj = calendar.Todos.FirstOrDefault();
if (todoObj == null) return null;
var calendarObj = DataProvider.GetCalendarById(calId);
var calendarObjViewSettings = calendarObj != null && calendarObj.ViewSettings != null ? calendarObj.ViewSettings.FirstOrDefault() : null;
var targetCalendar = DDayICalParser.ConvertCalendar(calendarObj?.GetUserCalendar(calendarObjViewSettings));
if (targetCalendar == null) return null;
todoObj.Uid = todo.Uid;
if (!fromCalDavServer)
{
try
{
var uid = todo.Uid;
string[] split = uid.Split(new Char[] { '@' });
var calDavGuid = calendarObj != null ? calendarObj.calDavGuid : "";
var myUri = HttpContext.Request.GetUrlRewriter();
var currentUserEmail = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
//TODO Caldav
2020-03-27 13:14:23 +00:00
var updateCaldavThread = new Thread(() => updateCaldavEvent(old_ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd));
updateCaldavThread.Start();
2020-03-16 11:05:56 +00:00
}
catch (Exception e)
{
Log.Error(e.Message);
}
}
var completed = todoObj.Completed == null ? DateTime.MinValue : DDayICalParser.ToUtc(todoObj.Completed);
var utcStartDate = todoObj.DtStart != null ? DDayICalParser.ToUtc(todoObj.DtStart) : DateTime.MinValue;
var result = UpdateTodo(
int.Parse(calendarId),
todoObj.Summary,
todoObj.Description,
utcStartDate,
todoObj.Uid,
completed);
return result;
2020-03-16 12:25:08 +00:00
}
/// <summary>
/// Deletes task
/// </summary>
/// <short>
/// Delete task
/// </short>
/// <param name="todoId">Task ID</param>
/// <param name="fromCaldavServer">Bool flag says that request from caldav server</param>
2020-03-16 12:25:08 +00:00
[Delete("todos/{todoId}")]
public void RemoveTodo(int todoId, CreateTodoModel createTodoModel)
{
var fromCaldavServer = createTodoModel.fromCalDavServer;
var todo = DataProvider.GetTodoById(todoId);
var uid = todo.Uid;
string[] split = uid.Split(new Char[] { '@' });
if (!fromCaldavServer)
{
var email = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
var myUri = HttpContext.Request.GetUrlRewriter();
//TODO Caldav
2020-03-27 13:14:23 +00:00
deleteEvent(split[0], todo.CalendarId, email, currentAccountPaswd, myUri);
2020-03-16 12:25:08 +00:00
}
DataProvider.RemoveTodo(todoId);
2020-03-16 11:05:56 +00:00
}
2020-03-16 08:41:25 +00:00
private List<TodoWrapper> CreateTodo(int calendarId, string name, string description, DateTime utcStartDate, string uid, DateTime completed)
{
name = (name ?? "").Trim();
description = (description ?? "").Trim();
if (!string.IsNullOrEmpty(uid))
{
var existTodo = DataProvider.GetTodoByUid(uid);
if (existTodo != null)
{
return null;
}
}
CheckPermissions(DataProvider.GetCalendarById(calendarId), CalendarAccessRights.FullAccessAction);
var todo = DataProvider.CreateTodo(calendarId,
AuthContext.CurrentAccount.ID,
name,
description,
utcStartDate,
uid,
completed);
if (todo != null)
{
var todoResult = TodoWrapperHelper.Get(todo, AuthContext.CurrentAccount.ID,
DataProvider.GetTimeZoneForCalendar(AuthContext.CurrentAccount.ID, calendarId))
.GetList();
return todoResult;
}
return null;
}
2020-03-16 11:05:56 +00:00
private List<TodoWrapper> UpdateTodo(int calendarId, string name, string description, DateTime utcStartDate, string uid, DateTime completed)
{
name = (name ?? "").Trim();
description = (description ?? "").Trim();
if (!string.IsNullOrEmpty(uid))
{
var existTodo = DataProvider.GetTodoByUid(uid);
CheckPermissions(DataProvider.GetCalendarById(calendarId), CalendarAccessRights.FullAccessAction);
var todo = DataProvider.UpdateTodo(existTodo.Id, calendarId, AuthContext.CurrentAccount.ID, name, description, utcStartDate, uid, completed);
if (todo != null)
{
var todoResult = TodoWrapperHelper.Get(todo, AuthContext.CurrentAccount.ID,
DataProvider.GetTimeZoneForCalendar(AuthContext.CurrentAccount.ID, calendarId))
.GetList();
return todoResult;
}
}
return null;
}
2020-03-25 07:55:43 +00:00
2020-03-25 07:55:43 +00:00
[Create("outsideevent")]
public void AddEventOutside(string calendarGuid, string eventGuid, string ics)
{
if (calendarGuid.IndexOf("-shared") > 0)
{
var caldavGuid = calendarGuid.Replace("-shared", "");
var calendarTmp = DataProvider.GetCalendarIdByCaldavGuid(caldavGuid);
var calendarId = Convert.ToInt32(calendarTmp[0][0]);
var eventData = DataProvider.GetEventIdByUid(eventGuid.Split('.')[0], calendarId);
if (eventData == null)
{
var eventModel = new EventModel
{
Ics = ics,
AlertType = EventAlertType.Never,
SharingOptions = new List<SharingParam>()
};
AddEvent(calendarId, eventModel);
}
else
{
if (eventData.OwnerId == SecurityContext.CurrentAccount.ID)
{
var cal = DataProvider.GetCalendarById(calendarId);
var sharingOptions = eventData.SharingOptions;
var eventCharingList = new List<SharingParam>();
if (sharingOptions.PublicItems.Count > 1)
{
eventCharingList.AddRange(from publicItem in sharingOptions.PublicItems
where publicItem.Id.ToString() != AccessOption.OwnerOption.Id
select new SharingParam
{
Id = publicItem.Id,
isGroup = publicItem.IsGroup
});
}
var eventModel = new EventModel
{
EventId = Convert.ToInt32(eventData.Id),
CalendarId = calendarId.ToString(),
Ics = ics,
AlertType = EventAlertType.Never,
SharingOptions = eventCharingList
};
UpdateEvent(eventModel);
}
}
}
}
/// <summary>
/// Returns the sharing access parameters to the calendar with the ID specified in the request
/// </summary>
/// <short>
/// Get access parameters
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <returns>Sharing access parameters</returns>
2020-03-10 12:52:20 +00:00
[Read("{calendarId}/sharing")]
public PublicItemCollection GetCalendarSharingOptions(int calendarId)
{
var cal = DataProvider.GetCalendarById(calendarId);
if (cal == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
return PublicItemCollectionHelper.GetForCalendar(cal);
}
/// <summary>
/// Returns the default values for the sharing access parameters
/// </summary>
/// <short>
/// Get default access
/// </short>
/// <returns>Default sharing access parameters</returns>
2020-03-10 12:52:20 +00:00
[Read("sharing")]
public PublicItemCollection GetDefaultSharingOptions()
{
return PublicItemCollectionHelper.GetDefault();
}
public class UploadModel
{
public IEnumerable<IFormFile> Files { get; set; }
}
/// <summary>
/// Imports the events from the iCal files
/// </summary>
/// <short>
/// Import iCal
/// </short>
/// <param name="files">iCal formatted files with the events to be imported</param>
/// <returns>Returns the number of imported events</returns>
[Create("import")]
public int ImportEvents(UploadModel uploadModel)
{
var calendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
int calendarId;
if (int.TryParse(calendar.Id, out calendarId))
return ImportEvents(calendarId, uploadModel);
throw new Exception(string.Format("Can't parse {0} to int", calendar.Id));
}
/// <summary>
/// Imports the events from the iCal files to the existing calendar
/// </summary>
/// <short>
/// Import iCal
/// </short>
/// <param name="calendarId">ID for the calendar which serves as the future storage base for the imported events</param>
/// <param name="files">iCal formatted files with the events to be imported</param>
/// <returns>Returns the number of imported events</returns>
[Create("{calendarId}/import")]
public int ImportEvents(int calendarId, UploadModel uploadModel)
{
var counter = 0;
var files = uploadModel.Files;
if (files != null)
{
foreach (var file in files)
{
using (var reader = new StreamReader(file.OpenReadStream()))
{
var cals = DDayICalParser.DeserializeCalendar(reader);
2020-03-10 12:52:20 +00:00
counter = ImportEvents(calendarId, cals);
}
}
}
return counter;
}
public class ImportModel
{
public int CalendarId { get; set; }
public string ICalString { get; set; }
}
/// <summary>
/// Imports the events from the iCal files
/// </summary>
/// <short>
/// Import iCal
/// </short>
/// <param name="calendarId">Calendar ID</param>
/// <param name="iCalString">iCal formatted string</param>
/// <returns>Returns the number of imported events</returns>
[Create("importIcs")]
public int ImportEvents(ImportModel importModel)
{
var calendarId = importModel.CalendarId;
var iCalString = importModel.ICalString;
if (calendarId > 0)
{
var cals = DDayICalParser.DeserializeCalendar(iCalString);
return ImportEvents(calendarId, cals);
}
var calendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
if (int.TryParse(calendar.Id, out calendarId))
{
importModel.CalendarId = calendarId;
return ImportEvents(importModel);
}
throw new Exception(string.Format("Can't parse {0} to int", calendar.Id));
}
/// <summary>
/// Creates a calendar by the link to the external iCal feed
/// </summary>
/// <short>
/// Create calendar
/// </short>
/// <param name="iCalUrl">Link to the external iCal feed</param>
/// <param name="name">Calendar name</param>
/// <param name="textColor">Event text name</param>
/// <param name="backgroundColor">Event background name</param>
/// <returns>Created calendar</returns>
2020-03-13 08:53:32 +00:00
[Create("calendarUrl")]
public CalendarWrapper CreateCalendarStream(СalendarUrlModel сalendarUrl)
{
var iCalUrl = сalendarUrl.ICalUrl;
var name = сalendarUrl.Name;
var textColor = сalendarUrl.TextColor;
var backgroundColor = сalendarUrl.BackgroundColor;
var icalendar = new iCalendar(AuthContext, TimeZoneConverter, TenantManager);
var cal = icalendar.GetFromUrl(iCalUrl);
if (cal.isEmptyName)
cal.Name = iCalUrl;
if (String.IsNullOrEmpty(name))
name = cal.Name;
textColor = (textColor ?? "").Trim();
backgroundColor = (backgroundColor ?? "").Trim();
var calendar = DataProvider.CreateCalendar(
AuthContext.CurrentAccount.ID, name, cal.Description ?? "", textColor, backgroundColor,
cal.TimeZone, cal.EventAlertType, iCalUrl, null, new List<UserViewSettings>(), Guid.Empty);
if (calendar != null)
{
var calendarWrapperr = UpdateCalendarView(calendar.Id, new CalendarModel
{
Name = calendar.Name,
TextColor = textColor,
BackgroundColor = backgroundColor,
TimeZone = calendar.TimeZone.Id,
AlertType = cal.EventAlertType,
HideEvents = false
});
return calendarWrapperr;
}
return null;
}
2020-03-06 06:56:05 +00:00
private List<CalendarWrapper> LoadInternalCalendars()
{
var result = new List<CalendarWrapper>();
int newCalendarsCount;
//internal
var calendars = DataProvider.LoadCalendarsForUser(AuthContext.CurrentAccount.ID, out newCalendarsCount);
var userTimeZone = TimeZoneConverter.GetTimeZone(TenantManager.GetCurrentTenant().TimeZone);
result.AddRange(calendars.ConvertAll(c => CalendarWrapperHelper.Get(c)));
foreach (var calendarWrapper in result.ToList())
{
if (calendarWrapper.Owner.Id != SecurityContext.CurrentAccount.ID)
{
var ownerViewSettings = DataProvider.GetUserViewSettings(calendarWrapper.Owner.Id, new List<string>() { calendarWrapper.Id });
var userViewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, new List<string>() { calendarWrapper.Id });
userViewSettings.FirstOrDefault().TimeZone = ownerViewSettings.FirstOrDefault().TimeZone;
var newCal = CalendarWrapperHelper.Get(calendarWrapper.UserCalendar, userViewSettings.FirstOrDefault());
result.Remove(calendarWrapper);
result.Add(newCal);
}
}
2020-03-06 06:56:05 +00:00
if (!result.Exists(c => !c.IsSubscription))
{
//create first calendar
var firstCal = DataProvider.CreateCalendar(AuthContext.CurrentAccount.ID,
Resources.CalendarApiResource.DefaultCalendarName, "", BusinessObjects.Calendar.DefaultTextColor, BusinessObjects.Calendar.DefaultBackgroundColor, userTimeZone, EventAlertType.FifteenMinutes, null, new List<SharingOptions.PublicItem>(), new List<UserViewSettings>(), Guid.Empty);
result.Add(CalendarWrapperHelper.Get(firstCal));
}
return result;
}
2020-03-03 12:29:07 +00:00
private EventHistoryWrapper GetEventHistoryWrapper(Event evt, bool fullHistory = false)
{
if (evt == null) return null;
int calId;
BusinessObjects.Calendar cal = null;
if (int.TryParse(evt.CalendarId, out calId))
cal = DataProvider.GetCalendarById(calId);
if (cal == null) return null;
int evtId;
EventHistory history = null;
if (int.TryParse(evt.Id, out evtId))
history = DataProvider.GetEventHistory(evtId);
if (history == null) return null;
return ToEventHistoryWrapper(evt, cal, history, fullHistory);
}
private EventHistoryWrapper ToEventHistoryWrapper(Event evt, BusinessObjects.Calendar cal, EventHistory history, bool fullHistory = false)
{
var canNotify = false;
bool canEdit;
var calIsShared = cal.SharingOptions.SharedForAll || cal.SharingOptions.PublicItems.Count > 0;
if (calIsShared)
{
canEdit = canNotify = CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true);
return EventHistoryWrapperHelper.Get(history, canEdit, canNotify, cal, fullHistory);
}
var evtIsShared = evt.SharingOptions.SharedForAll || evt.SharingOptions.PublicItems.Count > 0;
if (evtIsShared)
{
canEdit = canNotify = CheckPermissions(evt, CalendarAccessRights.FullAccessAction, true);
return EventHistoryWrapperHelper.Get(history, canEdit, canNotify, cal, fullHistory);
}
canEdit = CheckPermissions(evt, CalendarAccessRights.FullAccessAction, true);
if (canEdit)
{
//TODO
//canNotify = CheckIsOrganizer(history);
}
return EventHistoryWrapperHelper.Get(history, canEdit, canNotify, cal, fullHistory);
}
private bool CheckIsOrganizer(EventHistory history)
{
//TODO
/* var canNotify = false;
var apiServer = new ApiServer();
var apiResponse = apiServer.GetApiResponse(String.Format("{0}mail/accounts.json", SetupInfo.WebApiBaseUrl), "GET");
var obj = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiResponse)));
if (obj["response"] != null)
{
var accounts = (from account in JArray.Parse(obj["response"].ToString())
let email = account.Value<String>("email")
let enabled = account.Value<Boolean>("enabled")
let isGroup = account.Value<Boolean>("isGroup")
where enabled && !isGroup
select email).ToList();
if (accounts.Any())
{
var mergedHistory = history.GetMerged();
if (mergedHistory != null && mergedHistory.Events != null)
{
var eventObj = mergedHistory.Events.FirstOrDefault();
if (eventObj != null && eventObj.Organizer != null)
{
var organizerEmail = eventObj.Organizer.Value.ToString()
.ToLowerInvariant()
.Replace("mailto:", "");
canNotify = accounts.Contains(organizerEmail);
}
}
}
}
return canNotify;*/
return false;
}
private int ImportEvents(int calendarId, IEnumerable<Ical.Net.Calendar> cals)
{
var counter = 0;
CheckPermissions(DataProvider.GetCalendarById(calendarId), CalendarAccessRights.FullAccessAction);
if (cals == null) return counter;
var calendars = cals.Where(x => string.IsNullOrEmpty(x.Method) ||
x.Method == Ical.Net.CalendarMethods.Publish ||
x.Method == Ical.Net.CalendarMethods.Request ||
x.Method == Ical.Net.CalendarMethods.Reply ||
x.Method == Ical.Net.CalendarMethods.Cancel).ToList();
foreach (var calendar in calendars)
{
if (calendar.Events == null) continue;
if (string.IsNullOrEmpty(calendar.Method))
calendar.Method = Ical.Net.CalendarMethods.Publish;
2020-03-06 06:56:05 +00:00
foreach (var eventObj in calendar.Events)
{
2020-03-03 12:29:07 +00:00
if (eventObj == null) continue;
var tmpCalendar = calendar.Copy<Ical.Net.Calendar>();
tmpCalendar.Events.Clear();
tmpCalendar.Events.Add(eventObj);
string rrule;
var ics = DDayICalParser.SerializeCalendar(tmpCalendar);
var eventHistory = DataProvider.GetEventHistory(eventObj.Uid);
if (eventHistory == null)
{
rrule = GetRRuleString(eventObj);
var utcStartDate = eventObj.IsAllDay ? eventObj.Start.Value : DDayICalParser.ToUtc(eventObj.Start);
var utcEndDate = eventObj.IsAllDay ? eventObj.End.Value : DDayICalParser.ToUtc(eventObj.End);
var existCalendar = DataProvider.GetCalendarById(calendarId);
if (!eventObj.IsAllDay && eventObj.Created != null && !eventObj.Start.IsUtc)
{
var offset = existCalendar.TimeZone.GetUtcOffset(eventObj.Created.Value);
var _utcStartDate = eventObj.Start.Subtract(offset).Value;
var _utcEndDate = eventObj.End.Subtract(offset).Value;
utcStartDate = _utcStartDate;
utcEndDate = _utcEndDate;
}
else if (!eventObj.IsAllDay && eventObj.Created != null)
{
var createOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.Created.Value);
var startOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.Start.Value);
var endOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.End.Value);
if (createOffset != startOffset)
{
var _utcStartDate = eventObj.Start.Subtract(createOffset).Add(startOffset).Value;
utcStartDate = _utcStartDate;
}
if (createOffset != endOffset)
{
var _utcEndDate = eventObj.End.Subtract(createOffset).Add(endOffset).Value;
utcEndDate = _utcEndDate;
}
}
if (eventObj.IsAllDay && utcStartDate.Date < utcEndDate.Date)
utcEndDate = utcEndDate.AddDays(-1);
try
{
var uid = eventObj.Uid;
string[] split = uid.Split(new Char[] { '@' });
var calDavGuid = existCalendar != null ? existCalendar.calDavGuid : "";
var myUri = HttpContext.Request.GetUrlRewriter();
var currentUserEmail = UserManager.GetUsers(AuthContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount.ID);
2020-03-06 06:56:05 +00:00
2020-03-03 12:29:07 +00:00
//TODO caldav
2020-03-27 13:14:23 +00:00
var updateCaldavThread = new Thread(() => updateCaldavEvent(ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd, DateTime.Now, tmpCalendar.TimeZones[0], existCalendar.TimeZone));
updateCaldavThread.Start();
2020-03-03 12:29:07 +00:00
}
catch (Exception e)
{
Log.Error(e.Message);
}
/*var result = CreateEvent(calendarId,
eventObj.Summary,
eventObj.Description,
utcStartDate,
utcEndDate,
RecurrenceRule.Parse(rrule),
EventAlertType.Default,
eventObj.IsAllDay,
null,
eventObj.Uid,
calendar.Method == Ical.Net.CalendarMethods.Cancel ? EventStatus.Cancelled : DDayICalParser.ConvertEventStatus(eventObj.Status), eventObj.Created != null ? eventObj.Created.Value : DateTime.Now);*/
2020-03-06 06:56:05 +00:00
// var eventId = result != null && result.Any() ? Int32.Parse(result.First().Id) : 0;
2020-03-03 12:29:07 +00:00
//if (eventId > 0)
2020-03-06 06:56:05 +00:00
// {
//DataProvider.AddEventHistory(calendarId, eventObj.Uid, eventId, ics);
// counter++;
// }
2020-03-03 12:29:07 +00:00
}
else
{
2020-03-27 13:14:23 +00:00
if (EventHistoryHelper.Contains(tmpCalendar, eventHistory)) continue;
2020-03-03 12:29:07 +00:00
2020-03-27 13:14:23 +00:00
eventHistory = DataProvider.AddEventHistory(eventHistory.CalendarId, eventHistory.EventUid,
2020-03-06 06:56:05 +00:00
eventHistory.EventId, ics);
2020-03-03 12:29:07 +00:00
2020-03-27 13:14:23 +00:00
var mergedCalendar = EventHistoryHelper.GetMerged(eventHistory);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
if (mergedCalendar == null || mergedCalendar.Events == null || !mergedCalendar.Events.Any()) continue;
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var mergedEvent = mergedCalendar.Events.First();
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
rrule = GetRRuleString(mergedEvent);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var utcStartDate = mergedEvent.IsAllDay ? mergedEvent.Start.Value : DDayICalParser.ToUtc(mergedEvent.Start);
var utcEndDate = mergedEvent.IsAllDay ? mergedEvent.End.Value : DDayICalParser.ToUtc(mergedEvent.End);
2020-03-03 12:29:07 +00:00
2020-03-27 13:14:23 +00:00
var existCalendar = DataProvider.GetCalendarById(calendarId);
2020-03-06 06:56:05 +00:00
if (!eventObj.IsAllDay && eventObj.Created != null && !eventObj.Start.IsUtc)
{
var offset = existCalendar.TimeZone.GetUtcOffset(eventObj.Created.Value);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var _utcStartDate = eventObj.Start.Subtract(offset).Value;
var _utcEndDate = eventObj.End.Subtract(offset).Value;
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
utcStartDate = _utcStartDate;
utcEndDate = _utcEndDate;
}
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
if (mergedEvent.IsAllDay && utcStartDate.Date < utcEndDate.Date)
utcEndDate = utcEndDate.AddDays(-1);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var targetEvent = DataProvider.GetEventById(eventHistory.EventId);
2020-03-27 13:14:23 +00:00
var permissions = PublicItemCollectionHelper.GetForEvent(targetEvent);
2020-03-06 06:56:05 +00:00
var sharingOptions = permissions.Items
.Where(x => x.SharingOption.Id != AccessOption.OwnerOption.Id)
.Select(x => new SharingParam
{
Id = x.Id,
actionId = x.SharingOption.Id,
isGroup = x.IsGroup
}).ToList();
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
try
{
var uid = eventObj.Uid;
string[] split = uid.Split(new Char[] { '@' });
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var calDavGuid = existCalendar != null ? existCalendar.calDavGuid : "";
2020-03-27 13:14:23 +00:00
var myUri = HttpContext.Request.GetUrlRewriter(); ;
var currentUserEmail = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).Email.ToLower();
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
//TODO caldav
2020-03-27 13:14:23 +00:00
var updateCaldavThread = new Thread(() => updateCaldavEvent(ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd, DateTime.Now, tmpCalendar.TimeZones[0], existCalendar.TimeZone));
updateCaldavThread.Start();
2020-03-06 06:56:05 +00:00
}
catch (Exception e)
{
Log.Error(e.Message);
}
//updateEvent(ics, split[0], calendarId.ToString(), true, DateTime.Now, tmpCalendar.TimeZones[0], existCalendar.TimeZone);
CreateEvent(eventHistory.CalendarId,
mergedEvent.Summary,
mergedEvent.Description,
utcStartDate,
utcEndDate,
RecurrenceRule.Parse(rrule),
EventAlertType.Default,
mergedEvent.IsAllDay,
sharingOptions,
mergedEvent.Uid,
DDayICalParser.ConvertEventStatus(mergedEvent.Status), eventObj.Created != null ? eventObj.Created.Value : DateTime.Now);
2020-03-27 13:14:23 +00:00
counter++;
2020-03-03 12:29:07 +00:00
}
}
}
return counter;
2020-03-06 06:56:05 +00:00
2020-03-03 12:29:07 +00:00
}
private void CheckPermissions(ISecurityObject securityObj, Common.Security.Authorizing.Action action)
{
CheckPermissions(securityObj, action, false);
}
private bool CheckPermissions(ISecurityObject securityObj, Common.Security.Authorizing.Action action, bool silent)
{
if (securityObj == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
if (silent)
return PermissionContext.CheckPermissions(securityObj, action);
PermissionContext.DemandPermissions(securityObj, action);
return true;
}
private string GetRRuleString(Ical.Net.CalendarComponents.CalendarEvent evt)
{
var rrule = string.Empty;
if (evt.RecurrenceRules != null && evt.RecurrenceRules.Any())
{
var recurrenceRules = evt.RecurrenceRules.ToList();
rrule = DDayICalParser.SerializeRecurrencePattern(recurrenceRules.First());
if (evt.ExceptionDates != null && evt.ExceptionDates.Any())
{
rrule += ";exdates=";
var exceptionDates = evt.ExceptionDates.ToList();
foreach (var periodList in exceptionDates)
{
var date = periodList.ToString();
//has time
if (date.ToLowerInvariant().IndexOf('t') >= 0)
{
//is utc time
if (date.ToLowerInvariant().IndexOf('z') >= 0)
{
rrule += date;
}
else
{
//convert to utc time
DateTime dt;
if (DateTime.TryParseExact(date.ToUpper(), "yyyyMMdd'T'HHmmssK", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out dt))
{
var tzid = periodList.TzId ?? evt.Start.TzId;
if (!String.IsNullOrEmpty(tzid))
{
dt = TimeZoneInfo.ConvertTime(dt, TimeZoneConverter.GetTimeZone(tzid), TimeZoneInfo.Utc);
}
rrule += dt.ToString("yyyyMMdd'T'HHmmssK");
}
else
{
rrule += date;
}
}
}
//for yyyyMMdd/P1D date. Bug in the ical.net
else if (date.ToLowerInvariant().IndexOf("/p") >= 0)
{
try
{
rrule += date.Split('/')[0];
}
catch (Exception ex)
{
Log.Error(String.Format("Error: {0}, Date string: {1}", ex, date));
rrule += date;
}
}
else
{
rrule += date;
}
rrule += ",";
}
rrule = rrule.TrimEnd(',');
}
}
return rrule;
}
private List<EventWrapper> CreateEvent(int calendarId, string name, string description, DateTime utcStartDate, DateTime utcEndDate, RecurrenceRule rrule, EventAlertType alertType, bool isAllDayLong, List<SharingParam> sharingOptions, string uid, EventStatus status, DateTime createDate)
{
var sharingOptionsList = sharingOptions ?? new List<SharingParam>();
name = (name ?? "").Trim();
description = (description ?? "").Trim();
if (!string.IsNullOrEmpty(uid))
{
var existEvent = DataProvider.GetEventByUid(uid);
2020-03-06 10:44:26 +00:00
if (existEvent != null)
2020-03-03 12:29:07 +00:00
{
return UpdateEvent(existEvent.CalendarId,
int.Parse(existEvent.Id),
name,
description,
2020-03-06 10:44:26 +00:00
new ApiDateTime(utcStartDate, TimeZoneInfo.Utc.GetOffset()),
new ApiDateTime(utcEndDate, TimeZoneInfo.Utc.GetOffset()),
2020-03-03 12:29:07 +00:00
rrule.ToString(),
alertType,
isAllDayLong,
sharingOptions,
status,
createDate);
2020-03-06 10:44:26 +00:00
}
2020-03-03 12:29:07 +00:00
}
2020-03-06 06:56:05 +00:00
CheckPermissions(DataProvider.GetCalendarById(calendarId), CalendarAccessRights.FullAccessAction);
2020-03-03 12:29:07 +00:00
2020-03-06 06:56:05 +00:00
var evt = DataProvider.CreateEvent(calendarId,
AuthContext.CurrentAccount.ID,
2020-03-03 12:29:07 +00:00
name,
description,
utcStartDate,
utcEndDate,
rrule,
alertType,
isAllDayLong,
sharingOptionsList.Select(o => o as SharingOptions.PublicItem).ToList(),
uid,
status,
createDate);
if (evt != null)
{
foreach (var opt in sharingOptionsList)
if (String.Equals(opt.actionId, AccessOption.FullAccessOption.Id, StringComparison.InvariantCultureIgnoreCase))
2020-03-06 06:56:05 +00:00
AuthorizationManager.AddAce(new AzRecord(opt.Id, CalendarAccessRights.FullAccessAction.ID, Common.Security.Authorizing.AceType.Allow, evt));
2020-03-03 12:29:07 +00:00
//notify
CalendarNotifyClient.NotifyAboutSharingEvent(evt);
2020-03-06 06:56:05 +00:00
var eventWrapper = EventWrapperHelper.Get(evt, AuthContext.CurrentAccount.ID,
DataProvider.GetTimeZoneForCalendar(AuthContext.CurrentAccount.ID, calendarId));
2020-03-10 07:08:37 +00:00
return EventWrapperHelper.GetList(utcStartDate, utcStartDate.AddMonths(_monthCount), eventWrapper.UserId, evt);
2020-03-06 06:56:05 +00:00
}
2020-03-03 12:29:07 +00:00
return null;
}
2020-03-06 10:44:26 +00:00
private List<EventWrapper> UpdateEvent(string calendarId, int eventId, string name, string description, ApiDateTime startDate, ApiDateTime endDate, string repeatType, EventAlertType alertType, bool isAllDayLong, List<SharingParam> sharingOptions, EventStatus status, DateTime createDate, bool fromCalDavServer = false, string ownerId = "")
{
var sharingOptionsList = sharingOptions ?? new List<SharingParam>();
var oldEvent = DataProvider.GetEventById(eventId);
var ownerGuid = fromCalDavServer ? Guid.Parse(ownerId) : Guid.Empty; //get userGuid in the case of a request from the server
if (oldEvent == null)
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
var cal = DataProvider.GetCalendarById(Int32.Parse(oldEvent.CalendarId));
if (!fromCalDavServer)
{
if (!oldEvent.OwnerId.Equals(AuthContext.CurrentAccount.ID) &&
!CheckPermissions(oldEvent, CalendarAccessRights.FullAccessAction, true) &&
!CheckPermissions(cal, CalendarAccessRights.FullAccessAction, true))
throw new System.Security.SecurityException(Resources.CalendarApiResource.ErrorAccessDenied);
}
name = (name ?? "").Trim();
description = (description ?? "").Trim();
TimeZoneInfo timeZone;
var calId = int.Parse(oldEvent.CalendarId);
if (!int.TryParse(calendarId, out calId))
{
calId = int.Parse(oldEvent.CalendarId);
timeZone = fromCalDavServer ? DataProvider.GetTimeZoneForSharedEventsCalendar(ownerGuid) : DataProvider.GetTimeZoneForSharedEventsCalendar(AuthContext.CurrentAccount.ID);
}
else
timeZone = fromCalDavServer ? DataProvider.GetTimeZoneForCalendar(ownerGuid, calId) : DataProvider.GetTimeZoneForCalendar(AuthContext.CurrentAccount.ID, calId);
var rrule = RecurrenceRule.Parse(repeatType);
2020-03-10 07:08:37 +00:00
var evt = DataProvider.UpdateEvent(eventId, oldEvent.Uid, calId,
2020-03-06 10:44:26 +00:00
oldEvent.OwnerId, name, description, startDate.UtcTime, endDate.UtcTime, rrule, alertType, isAllDayLong,
sharingOptionsList.Select(o => o as SharingOptions.PublicItem).ToList(), status, createDate);
if (evt != null)
{
//clear old rights
AuthorizationManager.RemoveAllAces(evt);
foreach (var opt in sharingOptionsList)
if (String.Equals(opt.actionId, AccessOption.FullAccessOption.Id, StringComparison.InvariantCultureIgnoreCase))
AuthorizationManager.AddAce(new AzRecord(opt.Id, CalendarAccessRights.FullAccessAction.ID, Common.Security.Authorizing.AceType.Allow, evt));
//notify
CalendarNotifyClient.NotifyAboutSharingEvent(evt, oldEvent);
evt.CalendarId = calendarId;
2020-03-10 07:08:37 +00:00
2020-03-10 08:05:31 +00:00
var eventWrapper = fromCalDavServer ?
EventWrapperHelper.Get(evt, ownerGuid, timeZone) :
2020-03-10 07:08:37 +00:00
EventWrapperHelper.Get(evt, AuthContext.CurrentAccount.ID, timeZone);
2020-03-10 08:05:31 +00:00
return EventWrapperHelper.GetList(startDate.UtcTime, startDate.UtcTime.AddMonths(_monthCount), eventWrapper.UserId, evt);
2020-03-10 07:08:37 +00:00
2020-03-06 10:44:26 +00:00
}
return null;
}
2020-03-19 12:09:03 +00:00
private string GetCalendariCalString(string calendarId, bool ignoreCache = false)
{
Log.Debug("GetCalendariCalString calendarId = " + calendarId);
try
{
var result = ExportDataCache.Get(calendarId);
if (!string.IsNullOrEmpty(result) && !ignoreCache)
return result;
var stopWatch = new Stopwatch();
stopWatch.Start();
BaseCalendar icalendar;
int calId;
var viewSettings = DataProvider.GetUserViewSettings(SecurityContext.CurrentAccount.ID, new List<string> { calendarId });
if (int.TryParse(calendarId, out calId))
{
icalendar = DataProvider.GetCalendarById(calId);
if (icalendar != null)
{
icalendar = icalendar.GetUserCalendar(viewSettings.FirstOrDefault());
}
}
else
{
//external
icalendar = CalendarManager.Instance.GetCalendarForUser(AuthContext.CurrentAccount.ID, calendarId, UserManager);
if (icalendar != null)
{
icalendar = icalendar.GetUserCalendar(viewSettings.FirstOrDefault());
}
}
if (icalendar == null) return null;
var ddayCalendar = DDayICalParser.ConvertCalendar(icalendar);
ddayCalendar.Events.Clear();
var events = icalendar.LoadEvents(SecurityContext.CurrentAccount.ID, DateTime.MinValue, DateTime.MaxValue);
var eventIds = new List<int>();
foreach (var e in events)
{
int evtId;
if (int.TryParse(e.Id, out evtId))
eventIds.Add(evtId);
}
var eventsHystory = DataProvider.GetEventsHistory(eventIds.ToArray());
foreach (var e in events)
{
int evtId;
EventHistory evtHistory = null;
if (int.TryParse(e.Id, out evtId))
evtHistory = eventsHystory.FirstOrDefault(x => x.EventId == evtId);
var offset = icalendar.TimeZone.GetUtcOffset(e.UtcUpdateDate);
if (evtHistory != null)
{
var mergedCalendar = EventHistoryHelper.GetMerged(evtHistory);
if (mergedCalendar == null || mergedCalendar.Events == null || !mergedCalendar.Events.Any())
continue;
var mergedEvent = mergedCalendar.Events.First();
mergedEvent.ExceptionDates.Clear();
foreach (var exDate in e.RecurrenceRule.ExDates)
{
var periodList = new PeriodList { new CalDateTime(exDate.Date) };
if (exDate.isDateTime)
{
periodList.Parameters.Add("TZID", ddayCalendar.TimeZones[0].TzId);
}
else
{
periodList.Parameters.Add("VALUE", "DATE");
}
mergedEvent.ExceptionDates.Add(periodList);
}
if (!mergedEvent.IsAllDay && mergedEvent.DtStart.IsUtc)
{
var _DtStart = mergedEvent.DtStart.Add(offset).Value;
var _DtEnd = mergedEvent.DtEnd.Add(offset).Value;
mergedEvent.DtStart = new CalDateTime(_DtStart.Year, _DtStart.Month, _DtStart.Day, _DtStart.Hour, _DtStart.Minute, _DtStart.Second, ddayCalendar.TimeZones[0].TzId);
mergedEvent.DtEnd = new CalDateTime(_DtEnd.Year, _DtEnd.Month, _DtEnd.Day, _DtEnd.Hour, _DtEnd.Minute, _DtEnd.Second, ddayCalendar.TimeZones[0].TzId);
}
var alarm = mergedEvent.Alarms.FirstOrDefault();
if (alarm != null)
{
if (alarm.Trigger == null)
{
mergedEvent.Alarms.Clear();
}
}
else
{
mergedEvent.Alarms.Clear();
}
ddayCalendar.Events.Add(mergedEvent);
}
else
{
var convertedEvent = DDayICalParser.ConvertEvent(e as BaseEvent);
if (string.IsNullOrEmpty(convertedEvent.Uid))
convertedEvent.Uid = DataProvider.GetEventUid(e.Uid, e.Id);
if (!convertedEvent.IsAllDay)
{
var _DtStart = convertedEvent.DtStart.Add(offset).Value;
var _DtEnd = convertedEvent.DtEnd.Add(offset).Value;
convertedEvent.DtStart = new CalDateTime(_DtStart.Year, _DtStart.Month, _DtStart.Day, _DtStart.Hour, _DtStart.Minute, _DtStart.Second, ddayCalendar.TimeZones[0].TzId);
convertedEvent.DtEnd = new CalDateTime(_DtEnd.Year, _DtEnd.Month, _DtEnd.Day, _DtEnd.Hour, _DtEnd.Minute, _DtEnd.Second, ddayCalendar.TimeZones[0].TzId);
}
var alarm = convertedEvent.Alarms.FirstOrDefault();
if (alarm != null)
{
if (alarm.Trigger == null)
{
convertedEvent.Alarms.Clear();
}
}
else
{
convertedEvent.Alarms.Clear();
}
ddayCalendar.Events.Add(convertedEvent);
}
}
ddayCalendar.TimeZones[0].Children.Clear();
result = DDayICalParser.SerializeCalendar(ddayCalendar);
//for yyyyMMdd/P1D date. Bug in the ical.net
result = Regex.Replace(result, @"(\w*EXDATE;VALUE=DATE:\d{8})(/\w*)", "$1");
ExportDataCache.Insert(calendarId, result);
stopWatch.Stop();
var timeSpan = stopWatch.Elapsed;
var elapsedTime = String.Format("GetCalendariCalString elapsedTime = {0:00}:{1:00}:{2:00}.{3:00}",
timeSpan.Hours,
timeSpan.Minutes,
timeSpan.Seconds,
timeSpan.Milliseconds / 10);
Log.Debug(elapsedTime);
return result;
}
catch (Exception ex)
{
Log.Error(ex);
return null;
}
}
2020-03-26 16:00:58 +00:00
private void CreateCaldavSharedEvents(string calendarId, string calendarIcs, Uri myUri, string currentUserEmail, string currentAccountPaswd, BaseCalendar icalendar, Common.Security.Authentication.IAccount currentUser, int tenantId)
{
var parseCalendar = DDayICalParser.DeserializeCalendar(calendarIcs);
var calendar = parseCalendar.FirstOrDefault();
TenantManager.SetCurrentTenant(tenantId);
try
{
if (calendar != null)
{
var events = new List<CalendarEvent>();
var isFullAccess = false;
if (calendarId != BirthdayReminderCalendar.CalendarId && calendarId != "crm_calendar" && !calendarId.Contains("Project_"))
{
foreach (var e in icalendar.LoadEvents(currentUser.ID, DateTime.MinValue, DateTime.MaxValue))
{
events.Add(DDayICalParser.ConvertEvent(e as BaseEvent));
}
}
else
{
events.AddRange(calendar.Events);
}
foreach (var e in events)
{
Event evt = null;
evt = DataProvider.GetEventOnlyByUid(e.Uid);
isFullAccess = calendarId != BirthdayReminderCalendar.CalendarId && calendarId != "crm_calendar" ?
evt != null ? PermissionContext.PermissionResolver.Check(currentUser, (ISecurityObject)evt, null, CalendarAccessRights.FullAccessAction) : isFullAccess
: isFullAccess;
var uid = e.Uid;
string[] split = uid.Split(new Char[] { '@' });
e.Uid = split[0];
if (calendarId == BirthdayReminderCalendar.CalendarId)
{
e.Created = null;
e.End = new CalDateTime(e.Start.AddDays(1));
var evtUid = split[0].Split(new Char[] { '_' });
e.Uid = evtUid[1];
}
else if (calendarId.Contains("Project_"))
{
e.Created = null;
e.End = new CalDateTime(e.End.AddDays(1));
}
else if (calendarId == "crm_calendar" || calendarId.Contains("Project_"))
{
e.Created = null;
e.Status = EventStatus.Confirmed.ToString();
}
calendar.Events.Clear();
calendar.Events.Add(e);
var ics = DDayICalParser.SerializeCalendar(calendar);
var eventUid = isFullAccess ? e.Uid + "_write" : e.Uid;
updateCaldavEvent(ics, eventUid, true, calendarId,
myUri, currentUserEmail, currentAccountPaswd, DateTime.Now,
calendar.TimeZones[0], icalendar.TimeZone, false, true);
}
}
}
catch (Exception exception)
{
Log.Error("ERROR. Create shared caldav events: " + exception.Message);
}
}
private void updateCaldavEvent(
string ics,
string uid,
bool sendToRadicale,
string guid,
Uri myUri,
string userEmail,
string currentAccountPaswd,
DateTime updateDate = default(DateTime),
VTimeZone calendarVTimeZone = null,
TimeZoneInfo calendarTimeZone = null,
bool isDelete = false,
bool isSrared = false
)
{
if (sendToRadicale)
{
try
{
if (guid != null && guid != "")
{
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
var caldavHost = myUri.Host;
Log.Info("RADICALE REWRITE URL: " + myUri);
var currentUserName = userEmail.ToLower() + "@" + caldavHost;
var encoded = isSrared ? Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID)) : Convert.ToBase64String(Encoding.UTF8.GetBytes(userEmail.ToLower() + ":" + currentAccountPaswd));
int indexOfChar = ics.IndexOf("BEGIN:VTIMEZONE");
int indexOfCharEND = ics.IndexOf("END:VTIMEZONE");
if (indexOfChar != -1)
{
ics = ics.Remove(indexOfChar, indexOfCharEND + 14 - indexOfChar);
if (ics.IndexOf("BEGIN:VTIMEZONE") > -1) updateCaldavEvent(ics, uid, true, guid, myUri, userEmail, currentAccountPaswd);
}
var requestUrl = calDavServerUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" + guid + (isSrared ? "-shared" : "") +
"/" + HttpUtility.UrlEncode(uid) + ".ics";
2020-03-26 16:00:58 +00:00
if (calendarTimeZone != null && calendarVTimeZone != null)
{
var icsCalendars = DDayICalParser.DeserializeCalendar(ics);
var icsCalendar = icsCalendars == null ? null : icsCalendars.FirstOrDefault();
var icsEvents = icsCalendar == null ? null : icsCalendar.Events;
var icsEvent = icsEvents == null ? null : icsEvents.FirstOrDefault();
if (icsEvent != null && !icsEvent.IsAllDay)
{
var offset = updateDate != DateTime.MinValue ? calendarTimeZone.GetUtcOffset(updateDate) : calendarTimeZone.GetUtcOffset(icsEvent.DtStart.Value);
if (icsEvent.DtStart.TzId != calendarVTimeZone.TzId)
{
var _DtStart = icsEvent.DtStart.Add(offset).Value;
icsEvent.DtStart = new CalDateTime(_DtStart.Year, _DtStart.Month, _DtStart.Day, _DtStart.Hour, _DtStart.Minute, _DtStart.Second, calendarVTimeZone.TzId);
}
if (icsEvent.DtEnd.TzId != calendarVTimeZone.TzId)
{
var _DtEnd = icsEvent.DtEnd.Add(offset).Value;
icsEvent.DtEnd = new CalDateTime(_DtEnd.Year, _DtEnd.Month, _DtEnd.Day, _DtEnd.Hour, _DtEnd.Minute, _DtEnd.Second, calendarVTimeZone.TzId);
}
foreach (var periodList in icsEvent.ExceptionDates)
{
periodList.Parameters.Add("TZID", calendarVTimeZone.TzId);
}
}
if (icsEvent != null)
{
icsEvent.Created = null;
2020-03-26 16:00:58 +00:00
if (!isDelete)
{
icsEvent.ExceptionDates.Clear();
}
icsEvent.Uid = null;
}
ics = DDayICalParser.SerializeCalendar(icsCalendar);
}
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
webRequest.Method = "PUT";
webRequest.ContentType = "text/calendar; charset=utf-8";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
var encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(ics);
webRequest.ContentLength = bytes.Length;
using (var writeStream = webRequest.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream())) { }
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound || resp.StatusCode == HttpStatusCode.Conflict)
Log.Debug("ERROR: " + ex.Message);
else
Log.Error("ERROR: " + ex.Message);
}
else
{
Log.Error("ERROR: " + ex.Message);
}
}
catch (Exception ex)
{
Log.Error("ERROR: " + ex.Message);
}
}
}
catch (Exception ex)
{
Log.Error("ERROR: " + ex.Message);
}
}
}
private void UpdateCalDavEvent(string change, Uri calDavUrl)
{
try
{
var serverCalDavUrl = new Uri(calDavUrl.Scheme + "://" + calDavUrl.Host + "/caldav");
var eventURl = serverCalDavUrl + "/" + change;
var changeData = change.Split('/');
var caldavGuid = changeData[1];
var eventGuid = changeData[2].Split('.')[0];
var sharedPostfixIndex = caldavGuid.IndexOf("-shared");
var calendarId = 0;
var ownerId = new Guid();
if (sharedPostfixIndex != -1)
{
int ind = caldavGuid.Length;
caldavGuid = caldavGuid.Remove(sharedPostfixIndex, ind - sharedPostfixIndex);
var fullAccessPostfixIndex = eventGuid.IndexOf("_write");
if (fullAccessPostfixIndex != -1)
{
eventGuid = eventGuid.Remove(fullAccessPostfixIndex, eventGuid.Length - fullAccessPostfixIndex);
}
}
if (caldavGuid == BirthdayReminderCalendar.CalendarId ||
caldavGuid == SharedEventsCalendar.CalendarId ||
caldavGuid == "crm_calendar")
{
var userName = changeData[0];
var userData = userName.Split('@');
var tenantName = userData[2];
try
{
var tenant = TenantManager.GetTenant(tenantName);
if (tenant != null)
{
var email = string.Join("@", userData[0], userData[1]);
TenantManager.SetCurrentTenant(tenant);
var user = UserManager.GetUserByEmail(email);
var extCalendar = CalendarManager.Instance.GetCalendarForUser(user.ID, caldavGuid, UserManager);
var events = extCalendar.LoadEvents(user.ID, DateTime.MinValue, DateTime.MaxValue);
string currentEventId =
(from e in events where e.Uid.Split('@')[0] == eventGuid select e.Id).FirstOrDefault();
if (currentEventId != null)
{
var evt = DataProvider.GetEventById(Convert.ToInt32(currentEventId));
calendarId = Convert.ToInt32(evt.CalendarId);
ownerId = Guid.Parse(evt.OwnerId.ToString());
SecurityContext.AuthenticateMe(ownerId);
}
else
{
Log.Error("ERROR: error update calDav event. get current event id");
return;
}
}
}
catch (Exception exception)
{
Log.Error(exception);
return;
}
}
else
{
var calendar = DataProvider.GetCalendarIdByCaldavGuid(caldavGuid);
calendarId = Convert.ToInt32(calendar[0][0]);
ownerId = Guid.Parse(calendar[0][1].ToString());
TenantManager.SetCurrentTenant(Convert.ToInt32(calendar[0][2]));
SecurityContext.AuthenticateMe(ownerId);
}
var currentUserName = UserManager.GetUsers(ownerId).Email.ToLower();
var _email = UserManager.GetUsers(ownerId).Email;
string currentAccountPaswd = Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, UserManager.GetUserByEmail(_email).ID);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(currentUserName + ":" + currentAccountPaswd));
if (sharedPostfixIndex != -1)
{
encoded =
Convert.ToBase64String(
Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID));
}
var webRequest = (HttpWebRequest)WebRequest.Create(eventURl);
webRequest.Method = "GET";
webRequest.ContentType = "text/calendar; charset=utf-8";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
Log.Info(String.Format("UpdateCalDavEvent eventURl: {0}, Authorization: {1}", eventURl, encoded));
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
string ics = reader.ReadToEnd();
Log.Info(String.Format("UpdateCalDavEvent: {0}", ics));
var existEvent = DataProvider.GetEventIdByUid(eventGuid + "%", calendarId); // new function
var existCalendar = DataProvider.GetCalendarById(calendarId);
var calendars = DDayICalParser.DeserializeCalendar(ics);
var _calendar = calendars == null ? null : calendars.FirstOrDefault();
var eventObj = _calendar == null || _calendar.Events == null ? null : _calendar.Events.FirstOrDefault();
if (eventObj != null)
{
var name = eventObj.Summary;
var description = eventObj.Description ?? " ";
var alarm = eventObj.Alarms == null ? null : eventObj.Alarms.FirstOrDefault();
var alertType = EventAlertType.Default;
if (alarm != null)
{
if (alarm.Trigger.Duration != null)
{
var alarmMinutes = alarm.Trigger.Duration.Value.Minutes;
var alarmHours = alarm.Trigger.Duration.Value.Hours;
var alarmDays = alarm.Trigger.Duration.Value.Days;
switch (alarmMinutes)
{
case -5:
alertType = EventAlertType.FiveMinutes;
break;
case -15:
alertType = EventAlertType.FifteenMinutes;
break;
case -30:
alertType = EventAlertType.HalfHour;
break;
}
switch (alarmHours)
{
case -1:
alertType = EventAlertType.Hour;
break;
case -2:
alertType = EventAlertType.TwoHours;
break;
}
if (alarmDays == -1)
alertType = EventAlertType.Day;
}
}
var utcStartDate = eventObj.IsAllDay ? eventObj.Start.Value : DDayICalParser.ToUtc(eventObj.Start);
var utcEndDate = eventObj.IsAllDay ? eventObj.End.Value : DDayICalParser.ToUtc(eventObj.End);
if (existEvent != null && existCalendar != null && !eventObj.IsAllDay)
{
var offset = existCalendar.TimeZone.GetUtcOffset(existEvent.UtcUpdateDate);
if (!eventObj.End.IsUtc && !eventObj.Start.IsUtc)
{
utcStartDate = eventObj.Start.Subtract(offset).Value;
utcEndDate = eventObj.End.Subtract(offset).Value;
}
else
{
var createOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.Created.Value);
var startOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.Start.Value);
var endOffset = existCalendar.TimeZone.GetUtcOffset(eventObj.End.Value);
if (createOffset != startOffset)
{
var _utcStartDate = eventObj.Start.Subtract(createOffset).Add(startOffset).Value;
utcStartDate = _utcStartDate;
}
if (createOffset != endOffset)
{
var _utcEndDate = eventObj.End.Subtract(createOffset).Add(endOffset).Value;
utcEndDate = _utcEndDate;
}
}
}
bool isAllDayLong = eventObj.IsAllDay;
var rrule = RecurrenceRule.Parse(GetRRuleString(eventObj));
var status = DDayICalParser.ConvertEventStatus(eventObj.Status);
if (existEvent != null)
{
var eventId = int.Parse(existEvent.Id);
var cal = new Ical.Net.Calendar();
var permissions = PublicItemCollectionHelper.GetForEvent(existEvent);
var sharingOptions = permissions.Items
.Where(x => x.SharingOption.Id != AccessOption.OwnerOption.Id)
.Select(x => new SharingParam
{
Id = x.Id,
actionId = x.SharingOption.Id,
isGroup = x.IsGroup
}).ToList();
eventObj.Start = new CalDateTime(DateTime.SpecifyKind(utcStartDate, DateTimeKind.Utc), TimeZoneInfo.Utc.Id);
eventObj.End = new CalDateTime(DateTime.SpecifyKind(utcEndDate, DateTimeKind.Utc), TimeZoneInfo.Utc.Id);
eventObj.Created = new CalDateTime(DateTime.SpecifyKind(eventObj.Created != null ? eventObj.Created.Value : DateTime.Now, DateTimeKind.Utc), TimeZoneInfo.Utc.Id);
cal.Events.Add(eventObj);
var eventModel = new EventModel
{
EventId = eventId,
CalendarId = calendarId.ToString(),
Ics = DDayICalParser.SerializeCalendar(cal),
AlertType = alertType,
SharingOptions = sharingOptions,
FromCalDavServer = true,
OwnerId = ownerId.ToString()
};
UpdateEvent(eventModel);
}
else
{
var eventModel = new EventModel
{
Ics = ics,
AlertType = alertType,
SharingOptions = null,
EventUid = null
};
AddEvent(calendarId, eventModel);
}
}
var todoObj = _calendar == null || _calendar.Todos == null ? null : _calendar.Todos.FirstOrDefault();
if (todoObj != null)
{
var todoName = todoObj.Summary;
var todoDescription = todoObj.Description ?? " ";
var todoUtcStartDate = todoObj.Start != null ? DDayICalParser.ToUtc(todoObj.Start) : DateTime.MinValue;
var todoCompleted = todoObj.Completed != null ? DDayICalParser.ToUtc(todoObj.Completed) : DateTime.MinValue;
var existTodo = DataProvider.GetTodoIdByUid(eventGuid + "%", calendarId);
if (existTodo != null)
{
var todoId = int.Parse(existTodo.Id);
UpdateTodo(
calendarId,
todoName,
todoDescription,
todoUtcStartDate,
existTodo.Uid,
todoCompleted);
}
else
{
CreateTodo(calendarId,
todoName,
todoDescription,
todoUtcStartDate,
eventGuid,
todoCompleted);
}
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound || resp.StatusCode == HttpStatusCode.Conflict)
Log.Debug("ERROR: " + ex.Message);
else
Log.Error("ERROR: " + ex.Message);
}
else
{
Log.Error("ERROR: " + ex.Message);
}
}
catch (Exception ex)
{
Log.Error(ex);
}
}
private void DeleteCalDavEvent(string eventInfo, Uri myUri)
{
Thread.Sleep(1000);
var caldavGuid = eventInfo.Split('/')[1].Replace("-shared", "");
var calEvent = eventInfo.Split('/')[2].Replace("_write", ""); ;
var eventGuid = calEvent.Split('.')[0];
if (caldavGuid != SharedEventsCalendar.CalendarId)
{
var calendar = DataProvider.GetCalendarIdByCaldavGuid(caldavGuid);
var calendarId = Convert.ToInt32(calendar[0][0]);
var ownerId = Guid.Parse(calendar[0][1].ToString());
TenantManager.SetCurrentTenant(Convert.ToInt32(calendar[0][2]));
SecurityContext.AuthenticateMe(ownerId);
var existEvent = DataProvider.GetEventIdByUid(eventGuid + "%", calendarId);
if (existEvent != null)
{
var eventDeleteModel = new EventDeleteModel
{
Date = null,
Type = EventRemoveType.AllSeries,
Uri = myUri,
FromCaldavServer = true
};
RemoveEvent(Convert.ToInt32(existEvent.Id), eventDeleteModel);
}
else
{
var existTodo = DataProvider.GetTodoByUid(eventGuid + "%");
if (existTodo != null)
{
var todoModel = new CreateTodoModel
{
fromCalDavServer = true
};
RemoveTodo(Convert.ToInt32(existTodo.Id), todoModel);
}
}
}
else
{
var existEvent = DataProvider.GetEventIdOnlyByUid(eventGuid + "%");
if (existEvent != null)
{
TenantManager.SetCurrentTenant(existEvent.TenantId);
SecurityContext.AuthenticateMe(existEvent.OwnerId);
var eventDeleteModel = new EventDeleteModel
{
Date = null,
Type = EventRemoveType.AllSeries,
Uri = myUri,
FromCaldavServer = true
};
RemoveEvent(Convert.ToInt32(existEvent.Id), eventDeleteModel);
}
}
}
private void CreateCaldavEvents(string calDavGuid, Uri myUri, string currentUserEmail, string currentAccountPaswd, BaseCalendar icalendar, string calendarIcs)
{
var parseCalendar = DDayICalParser.DeserializeCalendar(calendarIcs);
var calendar = parseCalendar.FirstOrDefault();
var calendarId = icalendar.Id;
var ddayCalendar = new Ical.Net.Calendar();
try
{
if (calendar != null)
{
var events = calendar.Events;
foreach (var evt in events)
{
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
ddayCalendar = DDayICalParser.ConvertCalendar(icalendar);
ddayCalendar.Events.Clear();
ddayCalendar.Events.Add(evt);
var ics = DDayICalParser.SerializeCalendar(ddayCalendar);
updateCaldavEvent(ics, split[0], true, calDavGuid, myUri, currentUserEmail,
currentAccountPaswd, DateTime.Now, ddayCalendar.TimeZones[0],
icalendar.TimeZone);
}
var todos = icalendar.GetTodoWrappers(SecurityContext.CurrentAccount.ID, new ApiDateTime(DateTime.MinValue, icalendar.TimeZone.GetOffset()), new ApiDateTime(DateTime.MaxValue, icalendar.TimeZone.GetOffset()));
foreach (var td in todos)
{
ddayCalendar = DDayICalParser.ConvertCalendar(icalendar);
ddayCalendar.Todos.Clear();
var todo = new Ical.Net.CalendarComponents.Todo
{
Summary = td.Name,
Description = td.Description,
Start = td.Start != DateTime.MinValue ? new CalDateTime(td.Start) : null,
Completed = td.Completed != DateTime.MinValue ? new CalDateTime(td.Completed) : null,
};
ddayCalendar.Todos.Add(todo);
var ics = DDayICalParser.SerializeCalendar(ddayCalendar);
var uid = td.Uid;
string[] split = uid.Split(new Char[] { '@' });
updateCaldavEvent(ics, split[0], true, calDavGuid, myUri, currentUserEmail, currentAccountPaswd, DateTime.Now, ddayCalendar.TimeZones[0], icalendar.TimeZone);
}
}
}
catch (Exception exception)
{
Log.Error("ERROR. Create caldav events: " + exception.Message);
}
}
private string UpdateCalDavCalendar(string name, string description, string backgroundColor, string calDavGuid, Uri myUri, string email, string currentAccountPaswd, bool isSharedCalendar = false)
{
var currentUserName = email.ToLower() + "@" + myUri.Host;
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
var calDavUrl = calDavServerUrl.Insert(calDavServerUrl.IndexOf("://") + 3, HttpUtility.UrlEncode(currentUserName) + ":" + currentAccountPaswd + "@");
var requestUrl = calDavUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" + calDavGuid + (isSharedCalendar ? "-shared" : "");
name = (name ?? "").Trim();
if (String.IsNullOrEmpty(name))
throw new Exception(Resources.CalendarApiResource.ErrorEmptyName);
description = (description ?? "").Trim();
backgroundColor = (backgroundColor ?? "").Trim();
Log.Info("RADICALE REWRITE URL: " + myUri);
string[] numbers = Regex.Split(backgroundColor, @"\D+");
var color = numbers.Length > 4 ? HexFromRGB(int.Parse(numbers[1]), int.Parse(numbers[2]), int.Parse(numbers[3])) : "#000000";
var data = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
"<propertyupdate xmlns=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:CR=\"urn:ietf:params:xml:ns:carddav\" xmlns:I=\"http://apple.com/ns/ical/\" xmlns:INF=\"http://inf-it.com/ns/ab/\">" +
"<set><prop>" +
"<C:supported-calendar-component-set><C:comp name=\"VEVENT\" /><C:comp name=\"VJOURNAL\" /><C:comp name=\"VTODO\" />" +
"</C:supported-calendar-component-set><displayname>" + name + "</displayname>" +
"<I:calendar-color>" + color + "</I:calendar-color>" +
"<C:calendar-description>" + description + "</C:calendar-description></prop></set><remove><prop>" +
"<INF:addressbook-color /><CR:addressbook-description /></prop></remove></propertyupdate>";
try
{
var encoded = isSharedCalendar ? Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID)) : Convert.ToBase64String(Encoding.UTF8.GetBytes(email.ToLower() + ":" + currentAccountPaswd));
var webRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
webRequest.Method = "PROPPATCH";
webRequest.ContentType = "text/calendar; charset=utf-8";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
var encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(data);
webRequest.ContentLength = bytes.Length;
using (var writeStream = webRequest.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
return requestUrl;
}
}
catch (Exception ex)
{
Log.Error(ex);
return "";
}
}
private void UpdateSharedCalDavCalendar(string name, string description, string backgroundColor, string calDavGuid, Uri myUri, List<SharingParam> sharingOptionsList, List<IEvent> events, string calendarId, string calendarGuid, int tenantId, DateTime updateDate = default(DateTime),
VTimeZone calendarVTimeZone = null,
TimeZoneInfo calendarTimeZone = null)
{
try
{
TenantManager.SetCurrentTenant(tenantId);
var calendarIcs = GetCalendariCalString(calendarId);
var parseCalendar = DDayICalParser.DeserializeCalendar(calendarIcs);
var calendar = parseCalendar.FirstOrDefault();
foreach (var sharingParam in sharingOptionsList)
{
var fullAccess = sharingParam.actionId == AccessOption.FullAccessOption.Id ||
sharingParam.actionId == AccessOption.OwnerOption.Id;
if (sharingParam.isGroup)
{
var users = UserManager.GetUsersByGroup(sharingParam.itemId);
foreach (var userGroup in users)
{
UpdateCalDavCalendar(name, description, backgroundColor, calDavGuid, myUri, userGroup.Email.ToLower(), null, true);
foreach (var e in events)
{
var evt = DDayICalParser.ConvertEvent(e as BaseEvent);
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
evt.Uid = split[0];
calendar.Events.Clear();
calendar.Events.Add(evt);
var ics = DDayICalParser.SerializeCalendar(calendar);
//TODO
2020-03-27 14:21:31 +00:00
UpdateSharedEvent(userGroup, evt.Uid, fullAccess, myUri, ics, calendarGuid, updateDate, calendarVTimeZone, calendarTimeZone);
2020-03-26 16:00:58 +00:00
}
}
}
else
{
var user = UserManager.GetUsers(sharingParam.itemId);
UpdateCalDavCalendar(name, description, backgroundColor, calDavGuid, myUri, user.Email.ToLower(), null, true);
foreach (var sharedEvent in events)
{
var evt = DDayICalParser.ConvertEvent(sharedEvent as BaseEvent);
var uid = evt.Uid;
string[] split = uid.Split(new Char[] { '@' });
evt.Uid = split[0];
calendar.Events.Clear();
calendar.Events.Add(evt);
var ics = DDayICalParser.SerializeCalendar(calendar);
//TODO
2020-03-27 14:21:31 +00:00
UpdateSharedEvent(user, evt.Uid, fullAccess, myUri, ics, calendarGuid, updateDate, calendarVTimeZone, calendarTimeZone);
2020-03-26 16:00:58 +00:00
}
}
}
}
catch (Exception ex)
{
Log.Error("ERROR: " + ex.Message);
}
}
2020-03-27 13:14:23 +00:00
private void ReplaceSharingEvent(
ASC.Core.Users.UserInfo user,
string actionId,
string guid,
Uri myUri,
string oldIcs,
string calendarId,
DateTime updateDate = default(DateTime),
VTimeZone calendarVTimeZone = null,
TimeZoneInfo calendarTimeZone = null,
string calGuid = null)
{
if (calGuid != "" && myUri != null && user != null)
{
string eventUid = guid,
oldEventUid = guid;
if (actionId == AccessOption.FullAccessOption.Id)
{
eventUid = guid + "_write";
oldEventUid = guid;
}
else if (actionId != AccessOption.OwnerOption.Id)
{
oldEventUid = guid + "_write";
eventUid = guid;
}
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
var caldavHost = myUri.Host;
Log.Info("RADICALE REWRITE URL: " + myUri);
var encoded =
Convert.ToBase64String(
Encoding.UTF8.GetBytes("admin@ascsystem" + ":" +
ASC.Core.Configuration.Constants.CoreSystem.ID));
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
var requestDeleteUrl = calDavServerUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" +
(calGuid ?? SharedEventsCalendar.CalendarId) + (actionId != AccessOption.OwnerOption.Id ? "-shared" : "") + "/" + oldEventUid +
".ics";
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(requestDeleteUrl);
webRequest.Method = "DELETE";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound || resp.StatusCode == HttpStatusCode.Conflict)
Log.Debug("ERROR: " + ex.Message);
else
Log.Error("ERROR: " + ex.Message);
}
else
{
Log.Error("ERROR: " + ex.Message);
}
}
catch (Exception ex)
{
Log.Error("ERROR: " + ex.Message);
}
finally
{
updateCaldavEvent(oldIcs, eventUid, true,
(calGuid ?? SharedEventsCalendar.CalendarId), myUri,
user.Email, actionId != AccessOption.OwnerOption.Id ? null : Authentication.GetUserPasswordHash(TenantManager.GetCurrentTenant().TenantId, user.ID), updateDate, calendarVTimeZone, calendarTimeZone, false, actionId != AccessOption.OwnerOption.Id);
}
}
}
2020-03-27 14:21:31 +00:00
private void UpdateSharedEvent(UserInfo userSharingInfo, string guid, bool fullAccess,
Uri myUri,
string oldIcs,
string calendarId,
DateTime updateDate = default(DateTime),
VTimeZone calendarVTimeZone = null,
TimeZoneInfo calendarTimeZone = null)
{
string eventUid = guid,
oldEventUid = guid;
if (fullAccess)
{
eventUid = guid + "_write";
oldEventUid = guid;
}
else
{
oldEventUid = guid + "_write";
eventUid = guid;
}
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
var caldavHost = myUri.Host;
Log.Info("RADICALE REWRITE URL: " + myUri);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin@ascsystem" + ":" + ASC.Core.Configuration.Constants.CoreSystem.ID));
var currentUserName = userSharingInfo.Email.ToLower() + "@" + caldavHost;
var requestDeleteUrl = calDavServerUrl + "/" + HttpUtility.UrlEncode(currentUserName) + "/" + calendarId + "-shared" + "/" + oldEventUid + ".ics";
updatedEvents.Add(guid);
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(requestDeleteUrl);
webRequest.Method = "DELETE";
webRequest.Headers.Add("Authorization", "Basic " + encoded);
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound || resp.StatusCode == HttpStatusCode.Conflict)
Log.Debug("ERROR: " + ex.Message);
else
Log.Error("ERROR: " + ex.Message);
}
else
{
Log.Error("ERROR: " + ex.Message);
}
}
catch (Exception ex)
{
Log.Error(ex);
}
finally
{
updateCaldavEvent(oldIcs, eventUid, true, calendarId, myUri,
userSharingInfo.Email, null, updateDate, calendarVTimeZone, calendarTimeZone, false, true);
}
}
2020-02-12 07:58:31 +00:00
}
2020-02-21 12:33:51 +00:00
public static class CalendarControllerExtention
2020-02-12 07:58:31 +00:00
{
2020-02-27 14:15:25 +00:00
public static DIHelper AddCalendarController(this DIHelper services)
2020-02-12 07:58:31 +00:00
{
return services
.AddApiContextService()
.AddSecurityContextService()
2020-02-27 08:50:06 +00:00
.AddPermissionContextService()
.AddCommonLinkUtilityService()
2020-03-19 12:09:03 +00:00
.AddSignatureService()
2020-02-27 08:50:06 +00:00
.AddDisplayUserSettingsService()
.AddCalendarDbContextService()
2020-02-21 12:33:51 +00:00
.AddCalendarDataProviderService()
2020-03-03 12:29:07 +00:00
.AddCalendarWrapper()
.AddCalendarNotifyClient()
.AddDDayICalParser()
2020-03-06 06:56:05 +00:00
.AddEventHistoryWrapper()
2020-03-16 08:41:25 +00:00
.AddEventWrapper()
2020-03-19 12:09:03 +00:00
.AddTodoWrapper()
2020-03-23 12:23:46 +00:00
.AddExportDataCache()
2020-03-26 10:58:30 +00:00
.AddSubscriptionWrapperHelper()
.AddEmailValidationKeyProviderService();
2020-02-12 07:58:31 +00:00
}
}
}