Проведен аудит. Добавлено переключение треков
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PlaylistShared.Api.Entities;
|
||||
@@ -18,47 +18,50 @@ public class AudioController : ControllerBase
|
||||
private readonly YandexMusicService _yandexService;
|
||||
private readonly SharedPlaylistService _sharedService;
|
||||
private readonly JwtService _jwtService;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public AudioController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
YandexMusicService yandexService,
|
||||
SharedPlaylistService sharedService,
|
||||
JwtService jwtService)
|
||||
JwtService jwtService,
|
||||
IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_yandexService = yandexService;
|
||||
_sharedService = sharedService;
|
||||
_jwtService = jwtService;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
[HttpGet("play-token")]
|
||||
[Authorize]
|
||||
public IActionResult GetPlayToken()
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
var token = _jwtService.CreatePlayToken(userId);
|
||||
return Ok(ApiResponse<string>.Ok(token));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Потоковое воспроизведение трека из Яндекс.Музыки.
|
||||
/// </summary>
|
||||
/// <param name="trackId">ID трека (например, "21696942").</param>
|
||||
/// <param name="access_token">gwt пользователя</param>
|
||||
/// <param name="shared_id">ID расшаренного плейлиста</param>
|
||||
[HttpGet("track/{trackId}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> StreamTrack(string trackId, [FromQuery] string? access_token = null, [FromQuery] string? shared_id = null)
|
||||
public async Task<IActionResult> StreamTrack(string trackId, [FromQuery] string? play_token = null, [FromQuery] string? shared_id = null)
|
||||
{
|
||||
var user = await GetUserFromToken(access_token);
|
||||
var user = await GetUserFromPlayToken(play_token);
|
||||
if (user == null || user.YandexAccessToken is null) user = await GetUserFromSharedPlaylistId(shared_id);
|
||||
if (user == null) return Unauthorized();
|
||||
|
||||
var streamUrl = await _yandexService.GetTrackFileUrlAsync(user, trackId);
|
||||
if (string.IsNullOrEmpty(streamUrl)) return NotFound();
|
||||
|
||||
var httpClient = new HttpClient();
|
||||
var httpClient = _httpClientFactory.CreateClient();
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, streamUrl);
|
||||
|
||||
// Пробрасываем Range-заголовок клиента к Яндекс.Музыке
|
||||
if (Request.Headers.ContainsKey("Range"))
|
||||
{
|
||||
request.Headers.Add("Range", Request.Headers["Range"].ToString());
|
||||
}
|
||||
|
||||
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
// Если Яндекс.Музыка поддерживает range, пробрасываем статус 206
|
||||
Response.StatusCode = (int)response.StatusCode;
|
||||
Response.ContentType = response.Content.Headers.ContentType?.ToString() ?? "audio/mpeg";
|
||||
|
||||
@@ -75,9 +78,9 @@ public class AudioController : ControllerBase
|
||||
|
||||
[HttpGet("track-info/{trackId}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult<ApiResponse<YandexTrack>>> GetTrackInfo(string trackId, [FromQuery] string? access_token = null, [FromQuery] string? shared_id = null)
|
||||
public async Task<ActionResult<ApiResponse<YandexTrack>>> GetTrackInfo(string trackId, [FromQuery] string? play_token = null, [FromQuery] string? shared_id = null)
|
||||
{
|
||||
var user = await GetUserFromToken(access_token);
|
||||
var user = await GetUserFromPlayToken(play_token);
|
||||
if (user == null || user.YandexAccessToken is null) user = await GetUserFromSharedPlaylistId(shared_id);
|
||||
if (user == null) return Unauthorized();
|
||||
|
||||
@@ -99,30 +102,20 @@ public class AudioController : ControllerBase
|
||||
}));
|
||||
}
|
||||
|
||||
private async Task<ApplicationUser?> GetUserFromToken(string? token)
|
||||
private async Task<ApplicationUser?> GetUserFromPlayToken(string? token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token)) return null;
|
||||
|
||||
var principal = _jwtService.ValidateToken(token);
|
||||
if (principal == null) return null;
|
||||
|
||||
var userId = principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
if (string.IsNullOrEmpty(userId)) return null;
|
||||
|
||||
return await _userManager.FindByIdAsync(userId);
|
||||
var userId = _jwtService.ValidatePlayToken(token);
|
||||
if (!userId.HasValue) return null;
|
||||
return await _userManager.FindByIdAsync(userId.Value.ToString());
|
||||
}
|
||||
|
||||
private async Task<ApplicationUser?> GetUserFromSharedPlaylistId(string? sharedId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sharedId)) return null;
|
||||
|
||||
var playlist = await _sharedService.GetEntityByTokenAsync(sharedId);
|
||||
|
||||
if (playlist == null) return null;
|
||||
|
||||
if (!await _sharedService.CanPlayEveryoneAsync(playlist)) return null;
|
||||
|
||||
return await _userManager.FindByIdAsync(playlist.CreatorUserId.ToString());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user