diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-07-02 14:34:08 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-07-02 14:34:08 -0400 |
| commit | 59dc591f66c20b6417aa2baa9503a154585386f9 (patch) | |
| tree | 68ee71de2e4162550bb95f5e661ef413ddf1e046 /MediaBrowser.Server.Implementations | |
| parent | 9bab99d4d8659e69478722d72028e84b64575ab2 (diff) | |
update to jquery mobile 1.4.3
Diffstat (limited to 'MediaBrowser.Server.Implementations')
9 files changed, 170 insertions, 81 deletions
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index 1a7f9db28..c29a7d14e 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -51,13 +51,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security private void ValidateUser(IRequest req) { - User user = null; - //This code is executed before the service var auth = AuthorizationContext.GetAuthorizationInfo(req); - if (auth != null) + if (string.IsNullOrWhiteSpace(auth.Token)) { + // Legacy + // TODO: Deprecate this in Oct 2014 + + User user = null; + if (!string.IsNullOrWhiteSpace(auth.UserId)) { var userId = auth.UserId; @@ -65,22 +68,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security user = UserManager.GetUserById(new Guid(userId)); } - string deviceId = auth.DeviceId; - string device = auth.Device; - string client = auth.Client; - string version = auth.Version; - - if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device) && !string.IsNullOrEmpty(version)) + if (user == null || user.Configuration.IsDisabled) { - var remoteEndPoint = req.RemoteIp; - - SessionManager.LogSessionActivity(client, version, deviceId, device, remoteEndPoint, user); + throw new UnauthorizedAccessException("Unauthorized access."); } } - - if (user == null || user.Configuration.IsDisabled) + else { - throw new UnauthorizedAccessException("Unauthorized access."); + SessionManager.ValidateSecurityToken(auth.Token); } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index 6ea77f251..77343ab4e 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -42,7 +42,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security Device = device, DeviceId = deviceId, UserId = userId, - Version = version + Version = version, + Token = httpReq.Headers["X-AUTH-TOKEN"] }; } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index f9d7479ce..1e0bbc39b 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -121,17 +121,20 @@ namespace MediaBrowser.Server.Implementations.Library /// <summary> /// Authenticates a User and returns a result indicating whether or not it succeeded /// </summary> - /// <param name="user">The user.</param> + /// <param name="username">The username.</param> /// <param name="password">The password.</param> /// <returns>Task{System.Boolean}.</returns> /// <exception cref="System.ArgumentNullException">user</exception> - public async Task<bool> AuthenticateUser(User user, string password) + /// <exception cref="System.UnauthorizedAccessException"></exception> + public async Task<bool> AuthenticateUser(string username, string password) { - if (user == null) + if (string.IsNullOrWhiteSpace(username)) { - throw new ArgumentNullException("user"); + throw new ArgumentNullException("username"); } + var user = Users.First(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); + if (user.Configuration.IsDisabled) { throw new UnauthorizedAccessException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 467bedcf1..ad1ddba88 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -49,8 +49,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly List<ILiveTvService> _services = new List<ILiveTvService>(); - private readonly ConcurrentDictionary<string, LiveStreamInfo> _openStreams = - new ConcurrentDictionary<string, LiveStreamInfo>(); + private readonly ConcurrentDictionary<string, LiveStreamData> _openStreams = + new ConcurrentDictionary<string, LiveStreamData>(); private List<Guid> _channelIdList = new List<Guid>(); private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>(); @@ -292,65 +292,68 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task<LiveStreamInfo> GetRecordingStream(string id, CancellationToken cancellationToken) { + return await GetLiveStream(id, false, cancellationToken).ConfigureAwait(false); + } + + public async Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken) + { + return await GetLiveStream(id, true, cancellationToken).ConfigureAwait(false); + } + + private async Task<LiveStreamInfo> GetLiveStream(string id, bool isChannel, CancellationToken cancellationToken) + { await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { - var service = ActiveService; - - var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); - - var recording = recordings.First(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id)); - - var result = await service.GetRecordingStream(recording.Id, cancellationToken).ConfigureAwait(false); - - Sanitize(result); + // Avoid implicitly captured closure + var itemId = id; - _logger.Debug("Live stream info: " + _json.SerializeToString(result)); + var stream = _openStreams + .Where(i => string.Equals(i.Value.ItemId, itemId) && isChannel == i.Value.IsChannel) + .Take(1) + .Select(i => i.Value) + .FirstOrDefault(); - if (!string.IsNullOrEmpty(result.Id)) + if (stream != null) { - _openStreams.AddOrUpdate(result.Id, result, (key, info) => result); + stream.ConsumerCount++; + _logger.Debug("Returning existing live tv stream"); + return stream.Info; } - return result; - } - catch (Exception ex) - { - _logger.ErrorException("Error getting recording stream", ex); - - throw; - } - finally - { - _liveStreamSemaphore.Release(); - } - } - - public async Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken) - { - await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { var service = ActiveService; + LiveStreamInfo info; - var channel = GetInternalChannel(id); - - _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId); + if (isChannel) + { + var channel = GetInternalChannel(id); + _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId); - var result = await service.GetChannelStream(channel.ExternalId, cancellationToken).ConfigureAwait(false); + info = await service.GetChannelStream(channel.ExternalId, cancellationToken).ConfigureAwait(false); + } + else + { + var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); + var recording = recordings.First(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id)); - Sanitize(result); + _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.Id); + info = await service.GetRecordingStream(recording.Id, cancellationToken).ConfigureAwait(false); + } - _logger.Debug("Live stream info: " + _json.SerializeToString(result)); + Sanitize(info); - if (!string.IsNullOrEmpty(result.Id)) + var data = new LiveStreamData { - _openStreams.AddOrUpdate(result.Id, result, (key, info) => result); - } + Info = info, + ConsumerCount = 1, + IsChannel = isChannel, + ItemId = id + }; - return result; + _openStreams.AddOrUpdate(info.Id, data, (key, i) => data); + + return info; } catch (Exception ex) { @@ -1597,20 +1600,38 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } + class LiveStreamData + { + internal LiveStreamInfo Info; + internal int ConsumerCount; + internal string ItemId; + internal bool IsChannel; + } + public async Task CloseLiveStream(string id, CancellationToken cancellationToken) { await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - var service = ActiveService; - - _logger.Info("Closing live stream from {0}, stream Id: {1}", service.Name, id); - try { - await service.CloseLiveStream(id, cancellationToken).ConfigureAwait(false); + var service = ActiveService; + + LiveStreamData data; + if (_openStreams.TryGetValue(id, out data)) + { + if (data.ConsumerCount > 1) + { + data.ConsumerCount--; + _logger.Info("Decrementing live stream client count."); + return; + } - LiveStreamInfo removed; - _openStreams.TryRemove(id, out removed); + } + _openStreams.TryRemove(id, out data); + + _logger.Info("Closing live stream from {0}, stream Id: {1}", service.Name, id); + + await service.CloseLiveStream(id, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -1662,7 +1683,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { foreach (var stream in _openStreams.Values.ToList()) { - var task = CloseLiveStream(stream.Id, CancellationToken.None); + var task = CloseLiveStream(stream.Info.Id, CancellationToken.None); Task.WaitAll(task); } diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index b3280dac7..41555fe82 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -201,5 +201,21 @@ "ButtonOpenInNewTab": "Open in new tab", "ButtonShuffle": "Shuffle", "ButtonInstantMix": "Instant mix", - "ButtonResume": "Resume" + "ButtonResume": "Resume", + "HeaderScenes": "Scenes", + "HeaderAudioTracks": "Audio Tracks", + "LabelUnknownLanguage": "Unknown language", + "HeaderSubtitles": "Subtitles", + "HeaderVideoQuality": "Video Quality", + "MessageErrorPlayingVideo": "There was an error playing the video.", + "MessageEnsureOpenTuner": "Please ensure there is an open tuner availalble.", + "ButtonHome": "Home", + "ButtonDashboard": "Dashboard", + "ButtonReports": "Reports", + "ButtonMetadataManager": "Metadata Manager", + "HeaderTime": "Time", + "HeaderName": "Name", + "HeaderAlbum": "Album", + "HeaderAlbumArtist": "Album Artist", + "HeaderArtist": "Artist" }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 10e27bc30..a909929ae 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -200,6 +200,7 @@ <Compile Include="News\NewsService.cs" /> <Compile Include="Notifications\CoreNotificationTypes.cs" /> <Compile Include="Notifications\InternalNotificationService.cs" /> + <Compile Include="Notifications\NotificationConfigurationFactory.cs" /> <Compile Include="Notifications\NotificationManager.cs" /> <Compile Include="Persistence\SqliteChapterRepository.cs" /> <Compile Include="Persistence\SqliteExtensions.cs" /> diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationConfigurationFactory.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationConfigurationFactory.cs new file mode 100644 index 000000000..a336eba0e --- /dev/null +++ b/MediaBrowser.Server.Implementations/Notifications/NotificationConfigurationFactory.cs @@ -0,0 +1,21 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Notifications; +using System.Collections.Generic; + +namespace MediaBrowser.Server.Implementations.Notifications +{ + public class NotificationConfigurationFactory : IConfigurationFactory + { + public IEnumerable<ConfigurationStore> GetConfigurations() + { + return new List<ConfigurationStore> + { + new ConfigurationStore + { + Key = "notifications", + ConfigurationType = typeof (NotificationOptions) + } + }; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs index 416b29e86..964e2cd24 100644 --- a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs +++ b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -30,13 +31,18 @@ namespace MediaBrowser.Server.Implementations.Notifications _logger = logManager.GetLogger(GetType().Name); } + private NotificationOptions GetConfiguration() + { + return _config.GetConfiguration<NotificationOptions>("notifications"); + } + public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken) { var notificationType = request.NotificationType; var options = string.IsNullOrWhiteSpace(notificationType) ? null : - _config.Configuration.NotificationOptions.GetOptions(notificationType); + GetConfiguration().GetOptions(notificationType); var users = GetUserIds(request, options) .Except(request.ExcludeUserIds) @@ -223,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.Notifications private bool IsEnabled(INotificationService service, string notificationType) { return string.IsNullOrEmpty(notificationType) || - _config.Configuration.NotificationOptions.IsServiceEnabled(service.Name, notificationType); + GetConfiguration().IsServiceEnabled(service.Name, notificationType); } public void AddParts(IEnumerable<INotificationService> services, IEnumerable<INotificationTypeFactory> notificationTypeFactories) @@ -248,9 +254,11 @@ namespace MediaBrowser.Server.Implementations.Notifications }).SelectMany(i => i).ToList(); + var config = GetConfiguration(); + foreach (var i in list) { - i.Enabled = _config.Configuration.NotificationOptions.IsEnabled(i.Type); + i.Enabled = config.IsEnabled(i.Type); } return list; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 4e2b3c7b7..2f6790a3e 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -25,6 +25,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Server.Implementations.Session { @@ -1138,10 +1139,15 @@ namespace MediaBrowser.Server.Implementations.Session } } + public void ValidateSecurityToken(string token) + { + + } + /// <summary> /// Authenticates the new session. /// </summary> - /// <param name="user">The user.</param> + /// <param name="username">The username.</param> /// <param name="password">The password.</param> /// <param name="clientType">Type of the client.</param> /// <param name="appVersion">The application version.</param> @@ -1149,17 +1155,34 @@ namespace MediaBrowser.Server.Implementations.Session /// <param name="deviceName">Name of the device.</param> /// <param name="remoteEndPoint">The remote end point.</param> /// <returns>Task{SessionInfo}.</returns> + /// <exception cref="System.UnauthorizedAccessException">Invalid user or password entered.</exception> /// <exception cref="UnauthorizedAccessException"></exception> - public async Task<SessionInfo> AuthenticateNewSession(User user, string password, string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint) + public async Task<AuthenticationResult> AuthenticateNewSession(string username, string password, string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint) { - var result = await _userManager.AuthenticateUser(user, password).ConfigureAwait(false); + var result = await _userManager.AuthenticateUser(username, password).ConfigureAwait(false); if (!result) { throw new UnauthorizedAccessException("Invalid user or password entered."); } - return await LogSessionActivity(clientType, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false); + var user = _userManager.Users + .First(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); + + var session = await LogSessionActivity(clientType, + appVersion, + deviceId, + deviceName, + remoteEndPoint, + user) + .ConfigureAwait(false); + + return new AuthenticationResult + { + User = _dtoService.GetUserDto(user), + SessionInfo = GetSessionInfoDto(session), + AuthenticationToken = Guid.NewGuid().ToString("N") + }; } /// <summary> |
