diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index c486407..7d8082d 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -4,6 +4,8 @@ using xCommons.Extensions; using xDataService.Interfaces; using xDataService.Providers; using xExceptions.Constants; +using xFileService.Interfaces; +using xTagService.Interfaces; using xWebinarService.Interfaces; using xWebinarService.Interfaces.Entities; using xWebinarService.Models.Entities; @@ -83,11 +85,13 @@ namespace xWebinarService.DI // Check Dependencies Exists ... var isDependenciesPassed = !services .GetRegisteredService() - .IsNull(); + .IsNull() && + !services.GetRegisteredService().IsNull() && + !services.GetRegisteredService().IsNull(); if (!isDependenciesPassed) { // - Log("AddFileService failed due Dependencies Issues, IXWebinarSubscriberRepository not provided ..."); + Log("AddFileService failed due Dependencies Issues, IXTagProvider, IXFileProvider, IXWebinarSubscriberRepository not provided ..."); throw exception; } @@ -113,6 +117,14 @@ namespace xWebinarService.DI services.Add(new ServiceDescriptor(typeof(IXWebinarTitleResourceProvider), typeof(XWebinarTitleResourceProvider), lifeTime)); services.Add(new ServiceDescriptor(typeof(IXWebinarDescriptionResourceProvider), typeof(XWebinarDescriptionResourceProvider), lifeTime)); + // + // Register Webinar Tag Provider ... + services.Add(new ServiceDescriptor(typeof(IXWebinarTagProvider), typeof(XWebinarTagProvider), lifeTime)); + + // + // Register Webinar File Provider ... + services.Add(new ServiceDescriptor(typeof(IXWebinarFileProvider), typeof(XWebinarFileProvider), lifeTime)); + // // Register Main Provider ... services.Add(new ServiceDescriptor(typeof(IXWebinarProvider), typeof(XWebinarProvider), lifeTime)); diff --git a/Interfaces/IXWebinarFileProvider.cs b/Interfaces/IXWebinarFileProvider.cs new file mode 100644 index 0000000..08c6b9e --- /dev/null +++ b/Interfaces/IXWebinarFileProvider.cs @@ -0,0 +1,8 @@ +using System; +using xFileService.Interfaces; + +namespace xWebinarService.Interfaces +{ + public interface IXWebinarFileProvider : IXBaseFileProvider + { } +} \ No newline at end of file diff --git a/Interfaces/IXWebinarProvider.cs b/Interfaces/IXWebinarProvider.cs index d2e5106..0647026 100644 --- a/Interfaces/IXWebinarProvider.cs +++ b/Interfaces/IXWebinarProvider.cs @@ -19,6 +19,8 @@ namespace xWebinarService.Interfaces IHubContext Hub { get; } IXIdentityProvider IdentityProvider { get; } IXWebinarRepository WebinarRepository { get; } + IXWebinarTagProvider WebinarTagProvider { get; } + IXWebinarFileProvider WebinarFileProvider { get; } XDataServiceConfiguration DataSercviceConfiguration { get; } IXWebinarTitleResourceProvider TitleResourceProvider { get; } IXWebinarSubscriberRepository WebinarSubscriberRepository { get; } diff --git a/Interfaces/IXWebinarTagProvider.cs b/Interfaces/IXWebinarTagProvider.cs new file mode 100644 index 0000000..47c8a16 --- /dev/null +++ b/Interfaces/IXWebinarTagProvider.cs @@ -0,0 +1,8 @@ +using System; +using xTagService.Interfaces; + +namespace xWebinarService.Interfaces +{ + public interface IXWebinarTagProvider : IXBaseTagProvider + { } +} \ No newline at end of file diff --git a/Providers/XWebinarFileProvider.cs b/Providers/XWebinarFileProvider.cs new file mode 100644 index 0000000..c0ff042 --- /dev/null +++ b/Providers/XWebinarFileProvider.cs @@ -0,0 +1,19 @@ +using System; +using xFileService.Interfaces; +using xFileService.Providers; +using xWebinarService.Interfaces; +using xWebinarService.Models.Entities; + +namespace xWebinarService.Providers +{ + public class XWebinarFileProvider : XBaseFileProvider, IXWebinarFileProvider + { + public XWebinarFileProvider( + IXFileProvider provider + ) : base( + providedFor: nameof(XWebinar), + provider: provider + ) + { } + } +} \ No newline at end of file diff --git a/Providers/XWebinarProvider.cs b/Providers/XWebinarProvider.cs index afeb9e5..7b8bc17 100644 --- a/Providers/XWebinarProvider.cs +++ b/Providers/XWebinarProvider.cs @@ -2,12 +2,14 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using xCommons.Extensions; using xDataService.Configuration; using xDataService.Extensions; using xExceptions.Constants; using xIdentityModels.Dtos; +using xIdentityModels.Models; using xIdentityService.Extensions; using xIdentityService.Interfaces; using xModels.Dtos; @@ -18,6 +20,7 @@ using xWebinarService.Interfaces; using xWebinarService.Interfaces.Entities; using xWebinarService.Models.Dtos; using xWebinarService.Models.Entities; +using XFileDto = xFileService.Models.Dtos.XFileDto; namespace xWebinarService.Providers { @@ -31,6 +34,8 @@ namespace xWebinarService.Providers public IHubContext Hub { get; } public IXIdentityProvider IdentityProvider { get; } public IXWebinarRepository WebinarRepository { get; } + public IXWebinarTagProvider WebinarTagProvider { get; } + public IXWebinarFileProvider WebinarFileProvider { get; } public XDataServiceConfiguration DataSercviceConfiguration { get; } public IXWebinarTitleResourceProvider TitleResourceProvider { get; } public IXWebinarSubscriberRepository WebinarSubscriberRepository { get; } @@ -42,6 +47,8 @@ namespace xWebinarService.Providers public XWebinarProvider( IXIdentityProvider identityProvider, IXWebinarRepository webinarRepository, + IXWebinarTagProvider webinarTagProvider, + IXWebinarFileProvider webinarFileProvider, XDataServiceConfiguration dataSercviceConfiguration, IXWebinarTitleResourceProvider titleResourceProvider, IXWebinarSubscriberRepository webinarSubscriberRepository, @@ -50,13 +57,15 @@ namespace xWebinarService.Providers ) { // + Hub = hub; IdentityProvider = identityProvider; WebinarRepository = webinarRepository; - DataSercviceConfiguration = dataSercviceConfiguration; + WebinarTagProvider = webinarTagProvider; + WebinarFileProvider = webinarFileProvider; TitleResourceProvider = titleResourceProvider; + DataSercviceConfiguration = dataSercviceConfiguration; WebinarSubscriberRepository = webinarSubscriberRepository; DescriptionResourceProvider = descriptionResourceProvider; - Hub = hub; } #endregion @@ -1143,6 +1152,347 @@ namespace xWebinarService.Providers } #endregion + // + #region File Actions ... + /// + /// Upload Files ... + /// + /// + /// + /// + /// + public async Task> Upload( + Guid id, + IFormFileCollection files, + XUserClaimsInfoDto userInfo = null + ) + { + // + // Validate ... + var isValid = !id.IsNull() && + !id.IsDefaultGuid() && + !userInfo.IsNullOrDefault(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Permission ... + isValid = await HasPermission(id, userInfo); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + var result = new List(); + try + { + // + result = (await WebinarFileProvider.Upload( + files: files, + forProvidedId: id, + userInfo: userInfo + )) + .ToList(); + } + catch { } + + // + return result; + } + + /// + /// Get Webinar Files ... + /// + /// + /// + public async Task> GetFiles(Guid id) + { + // + var result = new List(); + + // + var dto = await GetWebinar(id); + if (!dto.IsNullOrDefault()) + { + // + result = (await WebinarFileProvider + .GetAllFor(id)) + .ToList(); + } + + // + return result; + } + #endregion + + // + #region Tags Actions ... + /// + /// Attach Tag to Specified File ... + /// + /// + /// + /// + /// + /// + public async Task TagAttach( + string tag, + Guid id, + XUserClaimsInfoDto userInfo = null, + bool forceAttachToFiles = true + ) + { + // + // Validate ... + var isValid = !tag.IsNullOrEmpty() && + !id.IsNull() && + !id.IsDefaultGuid() && + !userInfo.IsNullOrDefault(); + if (isValid) + { + // + // Check Permissions ... + isValid = await HasPermission( + id: id, + userInfo: userInfo + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + try + { + // + // Attached Tag to Webinar ... + await WebinarTagProvider.Attach(tag, id); + + // + if (forceAttachToFiles) + { + // + var medias = await WebinarFileProvider.GetAllFor(id); + isValid = !medias.IsNull() && medias.HasChild(); + if (isValid) + { + // + foreach (var media in medias) + { + await WebinarFileProvider.Provider.TagAttach(tag, media.Id); + } + } + } + } + catch { } + } + } + + /// + /// Detach Tag fro Specified File ... + /// + /// + /// + /// + /// + /// + public async Task TagDetach( + string tag, + Guid id, + XUserClaimsInfoDto userInfo = null, + bool forceDetachFromFiles = true + ) + { + // + // Validate ... + var isValid = !tag.IsNullOrEmpty() && + !id.IsNull() && + !id.IsDefaultGuid(); + if (isValid) + { + // + // Check Permissions ... + isValid = await HasPermission( + id: id, + userInfo: userInfo + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + try + { + // + await WebinarTagProvider.Detach(tag, id); + + // + if (forceDetachFromFiles) + { + // + var medias = await WebinarFileProvider.GetAllFor(id); + isValid = !medias.IsNull() && medias.HasChild(); + if (isValid) + { + // + foreach (var media in medias) + { + await WebinarFileProvider.Provider.TagDetach(tag, media.Id); + } + } + } + } + catch { } + } + } + + /// + /// Attach Tags for Specified File ... + /// + /// + /// + /// + /// + /// + public async Task TagsAttach( + IEnumerable tags, + Guid id, + XUserClaimsInfoDto userInfo = null, + bool forceAttachToFiles = true + ) + { + // + // Validate ... + var isValid = !tags.IsNull() && + tags.HasChild() && + !id.IsNull() && + !id.IsDefaultGuid(); + if (isValid) + { + // + // Check Permissions ... + isValid = await HasPermission( + id: id, + userInfo: userInfo + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + try + { + // + foreach (var tag in tags) + { + // + await TagAttach( + tag, + id, + userInfo, + forceAttachToFiles + ); + } + } + catch { } + } + } + + /// + /// Detach Tags for Specified File ... + /// + /// + /// + /// + /// + /// + public async Task TagsDetach( + IEnumerable tags, + Guid id, + XUserClaimsInfoDto userInfo = null, + bool forceDetachFromFiles = true + ) + { + // + // Validate ... + var isValid = !tags.IsNull() && + tags.HasChild() && + !id.IsNull() && + !id.IsDefaultGuid(); + if (isValid) + { + // + // Check Permissions ... + isValid = await HasPermission( + id: id, + userInfo: userInfo + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + try + { + // + foreach (var tag in tags) + { + // + await TagDetach( + tag, + id, + userInfo, + forceDetachFromFiles + ); + } + } + catch { } + } + } + + /// + /// Detach all Attached Tags for Specified File ... + /// + /// + /// + public async Task TagsDetach( + Guid id, + XUserClaimsInfoDto userInfo = null + ) + { + // + // Validate ... + var isValid = !id.IsNull() && !id.IsDefaultGuid(); + if (isValid) + { + // + // Check Permissions ... + isValid = await HasPermission( + id: id, + userInfo: userInfo + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + try + { + // + var tags = await WebinarTagProvider.RemoveTagsFor(id); + } + catch { } + } + } + #endregion + // #region Hub Actions ... /// @@ -1196,5 +1546,50 @@ namespace xWebinarService.Providers catch { } } #endregion + + // + #region Private ... + /// + /// Check Specified User Info Has Permissions for Specified Webinar ... + /// + /// + /// + /// + private async Task HasPermission( + Guid id, + XUserClaimsInfoDto userInfo = null + ) + { + // + var result = false; + + // + // Validate ... + result = !id.IsNull() && + !id.IsDefaultGuid() && + !userInfo.IsNullOrDefault(); + if (!result) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Item Exists ... + var dto = await GetWebinar(id); + result = !dto.IsNullOrDefault(); + if (!result) + { + XException.NotFound.Throw(); + } + + // + result = + dto.OwnerId == userInfo.UserId || + userInfo.Roles.Any(r => r.ToNormalString() == "admin"); + + // + return result; + } + #endregion } } \ No newline at end of file diff --git a/Providers/XWebinarTagProvider.cs b/Providers/XWebinarTagProvider.cs new file mode 100644 index 0000000..87cad23 --- /dev/null +++ b/Providers/XWebinarTagProvider.cs @@ -0,0 +1,19 @@ +using System; +using xTagService.Interfaces; +using xTagService.Providers; +using xWebinarService.Interfaces; +using xWebinarService.Models.Entities; + +namespace xWebinarService.Providers +{ + public class XWebinarTagProvider : XBaseTagProvider, IXWebinarTagProvider + { + public XWebinarTagProvider( + IXTagProvider tagProvider + ) : base( + nameof(XWebinar), + tagProvider + ) + { } + } +} \ No newline at end of file diff --git a/xWebinarService.csproj b/xWebinarService.csproj index 7ac77bb..48885a9 100644 --- a/xWebinarService.csproj +++ b/xWebinarService.csproj @@ -29,9 +29,11 @@ + + - +