QuickConnectController.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System.ComponentModel.DataAnnotations;
  2. using Jellyfin.Api.Constants;
  3. using Jellyfin.Api.Helpers;
  4. using MediaBrowser.Common.Extensions;
  5. using MediaBrowser.Controller.QuickConnect;
  6. using MediaBrowser.Model.QuickConnect;
  7. using Microsoft.AspNetCore.Authorization;
  8. using Microsoft.AspNetCore.Http;
  9. using Microsoft.AspNetCore.Mvc;
  10. namespace Jellyfin.Api.Controllers
  11. {
  12. /// <summary>
  13. /// Quick connect controller.
  14. /// </summary>
  15. public class QuickConnectController : BaseJellyfinApiController
  16. {
  17. private readonly IQuickConnect _quickConnect;
  18. /// <summary>
  19. /// Initializes a new instance of the <see cref="QuickConnectController"/> class.
  20. /// </summary>
  21. /// <param name="quickConnect">Instance of the <see cref="IQuickConnect"/> interface.</param>
  22. public QuickConnectController(IQuickConnect quickConnect)
  23. {
  24. _quickConnect = quickConnect;
  25. }
  26. /// <summary>
  27. /// Gets the current quick connect state.
  28. /// </summary>
  29. /// <response code="200">Quick connect state returned.</response>
  30. /// <returns>The current <see cref="QuickConnectState"/>.</returns>
  31. [HttpGet("Status")]
  32. [ProducesResponseType(StatusCodes.Status200OK)]
  33. public ActionResult<QuickConnectState> GetStatus()
  34. {
  35. _quickConnect.ExpireRequests();
  36. return _quickConnect.State;
  37. }
  38. /// <summary>
  39. /// Initiate a new quick connect request.
  40. /// </summary>
  41. /// <response code="200">Quick connect request successfully created.</response>
  42. /// <response code="401">Quick connect is not active on this server.</response>
  43. /// <returns>A <see cref="QuickConnectResult"/> with a secret and code for future use or an error message.</returns>
  44. [HttpGet("Initiate")]
  45. [ProducesResponseType(StatusCodes.Status200OK)]
  46. public ActionResult<QuickConnectResult> Initiate()
  47. {
  48. return _quickConnect.TryConnect();
  49. }
  50. /// <summary>
  51. /// Attempts to retrieve authentication information.
  52. /// </summary>
  53. /// <param name="secret">Secret previously returned from the Initiate endpoint.</param>
  54. /// <response code="200">Quick connect result returned.</response>
  55. /// <response code="404">Unknown quick connect secret.</response>
  56. /// <returns>An updated <see cref="QuickConnectResult"/>.</returns>
  57. [HttpGet("Connect")]
  58. [ProducesResponseType(StatusCodes.Status200OK)]
  59. [ProducesResponseType(StatusCodes.Status404NotFound)]
  60. public ActionResult<QuickConnectResult> Connect([FromQuery, Required] string secret)
  61. {
  62. try
  63. {
  64. return _quickConnect.CheckRequestStatus(secret);
  65. }
  66. catch (ResourceNotFoundException)
  67. {
  68. return NotFound("Unknown secret");
  69. }
  70. }
  71. /// <summary>
  72. /// Temporarily activates quick connect for five minutes.
  73. /// </summary>
  74. /// <response code="204">Quick connect has been temporarily activated.</response>
  75. /// <response code="403">Quick connect is unavailable on this server.</response>
  76. /// <returns>An <see cref="NoContentResult"/> on success.</returns>
  77. [HttpPost("Activate")]
  78. [Authorize(Policy = Policies.DefaultAuthorization)]
  79. [ProducesResponseType(StatusCodes.Status204NoContent)]
  80. [ProducesResponseType(StatusCodes.Status403Forbidden)]
  81. public ActionResult Activate()
  82. {
  83. if (_quickConnect.State == QuickConnectState.Unavailable)
  84. {
  85. return Forbid("Quick connect is unavailable");
  86. }
  87. _quickConnect.Activate();
  88. return NoContent();
  89. }
  90. /// <summary>
  91. /// Enables or disables quick connect.
  92. /// </summary>
  93. /// <param name="status">New <see cref="QuickConnectState"/>.</param>
  94. /// <response code="204">Quick connect state set successfully.</response>
  95. /// <returns>An <see cref="NoContentResult"/> on success.</returns>
  96. [HttpPost("Available")]
  97. [Authorize(Policy = Policies.RequiresElevation)]
  98. [ProducesResponseType(StatusCodes.Status204NoContent)]
  99. public ActionResult Available([FromQuery] QuickConnectState status = QuickConnectState.Available)
  100. {
  101. _quickConnect.SetState(status);
  102. return NoContent();
  103. }
  104. /// <summary>
  105. /// Authorizes a pending quick connect request.
  106. /// </summary>
  107. /// <param name="code">Quick connect code to authorize.</param>
  108. /// <response code="200">Quick connect result authorized successfully.</response>
  109. /// <response code="403">Unknown user id.</response>
  110. /// <returns>Boolean indicating if the authorization was successful.</returns>
  111. [HttpPost("Authorize")]
  112. [Authorize(Policy = Policies.DefaultAuthorization)]
  113. [ProducesResponseType(StatusCodes.Status200OK)]
  114. [ProducesResponseType(StatusCodes.Status403Forbidden)]
  115. public ActionResult<bool> Authorize([FromQuery, Required] string code)
  116. {
  117. var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
  118. if (!userId.HasValue)
  119. {
  120. return Forbid("Unknown user id");
  121. }
  122. return _quickConnect.AuthorizeRequest(userId.Value, code);
  123. }
  124. /// <summary>
  125. /// Deauthorize all quick connect devices for the current user.
  126. /// </summary>
  127. /// <response code="200">All quick connect devices were deleted.</response>
  128. /// <returns>The number of devices that were deleted.</returns>
  129. [HttpPost("Deauthorize")]
  130. [Authorize(Policy = Policies.DefaultAuthorization)]
  131. [ProducesResponseType(StatusCodes.Status200OK)]
  132. public ActionResult<int> Deauthorize()
  133. {
  134. var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
  135. if (!userId.HasValue)
  136. {
  137. return 0;
  138. }
  139. return _quickConnect.DeleteAllDevices(userId.Value);
  140. }
  141. }
  142. }