using System.Linq; using System.Collections.Generic; using Nancy; using Nancy.ModelBinding; using Sony.Filtr.Applications; using Sony.Filtr.Contracts.Abstractions; using Sony.Filtr.Contracts.Definitions; using System; using AutoMapper; using Sony.Filtr.AdminAPI.Config; using Sony.Filtr.Contracts.Entities; namespace Sony.Filtr.AdminAPI.Modules { public class ServiceAccountModule : BaseModule { public ServiceAccountModule(ApplicationInstanceManager applicationInstanceManager, IServiceAccountManager serviceAccountManager) : base(applicationInstanceManager) { #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously Get["GetServiceAccounts", "/serviceAccounts", true] = async (parameters, cancellationToken) => { var serviceAccounts = serviceAccountManager.GetServiceAccounts(); var viewModels = Mapper.Map>(serviceAccounts); return Response.AsJson(viewModels); }; Get["GetServiceAccountsInMarket", "/serviceAccounts/{countryCode}/", true] = async (parameters, cancellationToken) => { if(CurrentApplication == null) { throw new NancyStatusException(HttpStatusCode.BadRequest, "No application/market supplied."); } var serviceAccounts = serviceAccountManager.GetServiceAccounts(CurrentApplication.ID); if (Request.Query.includeTokens != null && ((bool) Request.Query.includeTokens)) { var viewModelsWithTokens = Mapper.Map>(serviceAccounts); return Response.AsJson(viewModelsWithTokens); } var viewModels = Mapper.Map>(serviceAccounts); return Response.AsJson(viewModels); }; Delete["DeleteServiceAccount", "/serviceAccounts/{serviceAccountId}", true] = async (parameters, cancellationToken) => { var serviceAccountId = (int)parameters.serviceAccountId; var serviceAccount = serviceAccountManager.GetServiceAccount(serviceAccountId); if (serviceAccount == null) { throw new NancyStatusException(HttpStatusCode.NotFound, string.Format("Could not find serviceAccount with id {0}", serviceAccountId)); } serviceAccountManager.DeleteServiceAccount(serviceAccount); return HttpStatusCode.NoContent; }; Post["AddServiceAccount", "/serviceAccounts/{countryCode}", true] = async (parameters, cancellationToken) => { if(CurrentApplication == null) { throw new NancyStatusException(HttpStatusCode.BadRequest, "No application set for service account."); } var postObject = this.Bind("Id"); var serviceType = postObject.ServiceType; var musicServiceId = postObject.MusicServiceId; if (musicServiceId.HasValue) { serviceType = GetServiceType(musicServiceId); } else { musicServiceId = GetMusicServiceId(serviceType); } if (serviceType == null || musicServiceId == null) { throw new NancyStatusException(HttpStatusCode.BadRequest, "Missing serviceType or musicServiceId."); } var existingServiceAccount = serviceAccountManager.GetServiceAccount(musicServiceId.Value, postObject.UserIdentifier); if (existingServiceAccount != null) { throw new NancyStatusException(HttpStatusCode.Conflict, string.Format("Service account with userIdentifier {0} already exists for music service {1}.", existingServiceAccount.UserIdentifier, existingServiceAccount.MusicServiceId)); } var serviceAccount = BuildServiceAccount(postObject); serviceAccount.Id = 0; serviceAccount.MusicServiceId = musicServiceId.Value; serviceAccount.ServiceType = serviceType.Value; serviceAccount.ApplicationId = CurrentApplication.ID; serviceAccount.UpdatedDate = DateTime.UtcNow; var account = serviceAccountManager.AddServiceAccount(serviceAccount); if (account.MusicServiceId == (int)MusicService.Spotify) { await serviceAccountManager.AssignSpotifyApiClientIdToServiceAccountAsync(account.Id); } return Response.AsJson(account); }; Put["UpdateServiceAccount", "/serviceAccounts/{countryCode}/{serviceAccountId}", true] = async (parameters, cancellationToken) => { if (CurrentApplication == null) { throw new NancyStatusException(HttpStatusCode.BadRequest, "No application provided."); } var serviceAccountId = (int)parameters.serviceAccountId; var existingServiceAccount = serviceAccountManager.GetServiceAccount(serviceAccountId); if (existingServiceAccount == null) { throw new NancyStatusException(HttpStatusCode.NotFound, $"No service account with id {serviceAccountId}"); } var postObject = this.Bind("Id", "ApplicationId"); var serviceAccount = BuildServiceAccount(postObject); serviceAccount.Id = existingServiceAccount.Id; serviceAccount.ApplicationId = existingServiceAccount.ApplicationId; serviceAccount.ServiceType = existingServiceAccount.ServiceType; serviceAccount.MusicServiceId = existingServiceAccount.MusicServiceId; serviceAccount.UpdatedDate = DateTime.UtcNow; var account = serviceAccountManager.SaveServiceAccount(serviceAccount); return Response.AsJson(account); }; #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously } private ServiceAccount BuildServiceAccount(ServiceAccountPostObject postObject) { return AutoMapper.Mapper.Map(postObject); } private int? GetMusicServiceId(ServiceType? serviceType) { if (serviceType == ServiceType.Spotify) return (int)MusicService.Spotify; if (serviceType == ServiceType.Deezer) return (int)MusicService.Deezer; if (serviceType == ServiceType.YouTube) return (int)MusicService.YouTube; return null; } private ServiceType? GetServiceType(int? musicServiceId) { if (musicServiceId == (int)MusicService.Spotify) return ServiceType.Spotify; if (musicServiceId == (int)MusicService.Deezer) return ServiceType.Deezer; if (musicServiceId == (int)MusicService.YouTube) return ServiceType.YouTube; return null; } } public class ServiceAccountPostObject { public int Id { get; set; } public ServiceType? ServiceType { get; set; } public int? MusicServiceId { get; set; } public string DisplayName { get; set; } public string UserIdentifier { get; set; } public string AccessToken { get; set; } public int? AccessTokenExpiry { get; set; } public string RefreshToken { get; set; } public DateTime UpdatedDate { get; set; } public int ApplicationId { get; set; } public string ChannelName { get; set; } } public class ServiceAccountViewModel { public int Id { get; set; } public ServiceType ServiceType { get; set; } public int MusicServiceId { get; set; } public string DisplayName { get; set; } public string UserIdentifier { get; set; } public DateTime UpdatedDate { get; set; } public int ApplicationId { get; set; } } public class ServiceAccountWithTokenViewModel { public int Id { get; set; } public ServiceType ServiceType { get; set; } public int MusicServiceId { get; set; } public string DisplayName { get; set; } public string UserIdentifier { get; set; } public DateTime UpdatedDate { get; set; } public int ApplicationId { get; set; } public string AccessToken { get; set; } public string RefreshToken { get; set; } } }