aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/publish-nightly.yml46
-rw-r--r--.ci/publish-release.yml48
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--Dockerfile17
-rw-r--r--Dockerfile.arm16
-rw-r--r--Dockerfile.arm6416
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs47
-rw-r--r--Jellyfin.Drawing.Skia/SkiaCodecException.cs46
-rw-r--r--Jellyfin.Drawing.Skia/SkiaEncoder.cs12
-rw-r--r--Jellyfin.Drawing.Skia/SkiaException.cs26
-rw-r--r--Jellyfin.Drawing.Skia/SkiaHelper.cs23
-rw-r--r--MediaBrowser.Model/Users/UserPolicy.cs2
12 files changed, 251 insertions, 49 deletions
diff --git a/.ci/publish-nightly.yml b/.ci/publish-nightly.yml
new file mode 100644
index 000000000..a693e10f6
--- /dev/null
+++ b/.ci/publish-nightly.yml
@@ -0,0 +1,46 @@
+name: Nightly-$(date:yyyyMMdd).$(rev:r)
+
+variables:
+ - name: Version
+ value: '1.0.0'
+
+trigger: none
+pr: none
+
+jobs:
+ - job: publish_artifacts_nightly
+ displayName: Publish Artifacts Nightly
+ pool:
+ vmImage: ubuntu-latest
+ steps:
+ - checkout: none
+ - task: DownloadPipelineArtifact@2
+ displayName: Download the Windows Setup Artifact
+ inputs:
+ source: 'specific' # Options: current, specific
+ artifact: 'Jellyfin Server Setup' # Optional
+ path: '$(System.ArtifactsDirectory)/win-installer'
+ project: '$(System.TeamProjectId)' # Required when source == Specific
+ pipelineId: 1 # Required when source == Specific
+ runVersion: 'latestFromBranch' # Required when source == Specific. Options: latest, latestFromBranch, specific
+ runBranch: 'refs/heads/master' # Required when source == Specific && runVersion == LatestFromBranch
+
+ - task: SSH@0
+ displayName: 'Create Drop directory'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_nightly_azure_upload'
+
+ - task: CopyFilesOverSSH@0
+ displayName: 'Copy the Windows Setup to the Repo'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ sourceFolder: '$(System.ArtifactsDirectory)/win-installer'
+ contents: 'jellyfin_*.exe'
+ targetFolder: '/srv/incoming/jellyfin_nightly_azure_upload/win-installer'
+
+ - task: SSH@0
+ displayName: 'Clean up SCP symlink'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ commands: 'rm -f /srv/incoming/jellyfin_nightly_azure_upload'
diff --git a/.ci/publish-release.yml b/.ci/publish-release.yml
new file mode 100644
index 000000000..57e77ae5a
--- /dev/null
+++ b/.ci/publish-release.yml
@@ -0,0 +1,48 @@
+name: Release-$(Version)-$(date:yyyyMMdd).$(rev:r)
+
+variables:
+ - name: Version
+ value: '1.0.0'
+ - name: UsedRunId
+ value: 0
+
+trigger: none
+pr: none
+
+jobs:
+ - job: publish_artifacts_release
+ displayName: Publish Artifacts Release
+ pool:
+ vmImage: ubuntu-latest
+ steps:
+ - checkout: none
+ - task: DownloadPipelineArtifact@2
+ displayName: Download the Windows Setup Artifact
+ inputs:
+ source: 'specific' # Options: current, specific
+ artifact: 'Jellyfin Server Setup' # Optional
+ path: '$(System.ArtifactsDirectory)/win-installer'
+ project: '$(System.TeamProjectId)' # Required when source == Specific
+ pipelineId: 1 # Required when source == Specific
+ runVersion: 'specific' # Required when source == Specific. Options: latest, latestFromBranch, specific
+ runId: $(UsedRunId)
+
+ - task: SSH@0
+ displayName: 'Create Drop directory'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_release_azure_upload'
+
+ - task: CopyFilesOverSSH@0
+ displayName: 'Copy the Windows Setup to the Repo'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ sourceFolder: '$(System.ArtifactsDirectory)/win-installer'
+ contents: 'jellyfin_*.exe'
+ targetFolder: '/srv/incoming/jellyfin_release_azure_upload/win-installer'
+
+ - task: SSH@0
+ displayName: 'Clean up SCP symlink'
+ inputs:
+ sshEndpoint: 'Jellyfin Build Server'
+ commands: 'rm -f /srv/incoming/jellyfin_release_azure_upload'
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index c95133dfd..f22944a8b 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -29,6 +29,7 @@
- [joern-h](https://github.com/joern-h)
- [Khinenw](https://github.com/HelloWorld017)
- [fhriley](https://github.com/fhriley)
+ - [nevado](https://github.com/nevado)
# Emby Contributors
diff --git a/Dockerfile b/Dockerfile
index ec64398b2..017f8c697 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,15 @@
ARG DOTNET_VERSION=2.2
ARG FFMPEG_VERSION=latest
+FROM node:alpine as web-builder
+ARG JELLYFIN_WEB_VERSION=v10.4.0
+RUN apk add curl \
+ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ && cd jellyfin-web-* \
+ && yarn install \
+ && yarn build \
+ && mv dist /dist
+
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
@@ -13,7 +22,7 @@ FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}
# libfontconfig1 is required for Skia
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
- libfontconfig1 \
+ libfontconfig1 mesa-va-drivers \
&& apt-get clean autoclean \
&& apt-get autoremove \
&& rm -rf /var/lib/apt/lists/* \
@@ -21,11 +30,7 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin
-
-ARG JELLYFIN_WEB_VERSION=v10.4.0
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
- && rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-* /jellyfin/jellyfin-web
+COPY --from=web-builder /dist /jellyfin/jellyfin-web/src
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Dockerfile.arm b/Dockerfile.arm
index 2b1c6bb62..d06eeb561 100644
--- a/Dockerfile.arm
+++ b/Dockerfile.arm
@@ -3,6 +3,16 @@
ARG DOTNET_VERSION=3.0
+FROM node:alpine as web-builder
+ARG JELLYFIN_WEB_VERSION=v10.4.0
+RUN apk add curl \
+ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ && cd jellyfin-web-* \
+ && yarn install \
+ && yarn build \
+ && mv dist /dist
+
+
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
@@ -25,11 +35,7 @@ RUN apt-get update \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-
-ARG JELLYFIN_WEB_VERSION=v10.4.0
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
- && rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-* /jellyfin/jellyfin-web
+COPY --from=web-builder /dist /jellyfin/jellyfin-web/src
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Dockerfile.arm64 b/Dockerfile.arm64
index 5ebc82ebc..1c5de4ed0 100644
--- a/Dockerfile.arm64
+++ b/Dockerfile.arm64
@@ -3,6 +3,16 @@
ARG DOTNET_VERSION=3.0
+FROM node:alpine as web-builder
+ARG JELLYFIN_WEB_VERSION=v10.4.0
+RUN apk add curl \
+ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ && cd jellyfin-web-* \
+ && yarn install \
+ && yarn build \
+ && mv dist /dist
+
+
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
@@ -25,11 +35,7 @@ RUN apt-get update \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-
-ARG JELLYFIN_WEB_VERSION=v10.4.0
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
- && rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-* /jellyfin/jellyfin-web
+COPY --from=web-builder /dist /jellyfin/jellyfin-web/src
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index a7ea13ca6..afa53ff37 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -353,11 +353,11 @@ namespace Emby.Server.Implementations.Library
UpdateUser(user);
}
- UpdateInvalidLoginAttemptCount(user, 0);
+ ResetInvalidLoginAttemptCount(user);
}
else
{
- UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1);
+ IncrementInvalidLoginAttemptCount(user);
}
_logger.LogInformation("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied");
@@ -509,41 +509,28 @@ namespace Emby.Server.Implementations.Library
: PasswordHash.ConvertToByteString(new PasswordHash(user.EasyPassword).Hash);
}
- private void UpdateInvalidLoginAttemptCount(User user, int newValue)
+ private void ResetInvalidLoginAttemptCount(User user)
{
- if (user.Policy.InvalidLoginAttemptCount == newValue || newValue <= 0)
- {
- return;
- }
-
- user.Policy.InvalidLoginAttemptCount = newValue;
-
- // Check for users without a value here and then fill in the default value
- // also protect from an always lockout if misconfigured
- if (user.Policy.LoginAttemptsBeforeLockout == null || user.Policy.LoginAttemptsBeforeLockout == 0)
- {
- user.Policy.LoginAttemptsBeforeLockout = user.Policy.IsAdministrator ? 5 : 3;
- }
-
- var maxCount = user.Policy.LoginAttemptsBeforeLockout;
-
- var fireLockout = false;
+ user.Policy.InvalidLoginAttemptCount = 0;
+ UpdateUserPolicy(user, user.Policy, false);
+ }
- // -1 can be used to specify no lockout value
- if (maxCount != -1 && newValue >= maxCount)
+ private void IncrementInvalidLoginAttemptCount(User user)
+ {
+ int invalidLogins = ++user.Policy.InvalidLoginAttemptCount;
+ int maxInvalidLogins = user.Policy.LoginAttemptsBeforeLockout;
+ if (maxInvalidLogins > 0
+ && invalidLogins >= maxInvalidLogins)
{
- _logger.LogDebug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue);
user.Policy.IsDisabled = true;
-
- fireLockout = true;
+ UserLockedOut?.Invoke(this, new GenericEventArgs<User>(user));
+ _logger.LogWarning(
+ "Disabling user {UserName} due to {Attempts} unsuccessful login attempts.",
+ user.Name,
+ invalidLogins);
}
UpdateUserPolicy(user, user.Policy, false);
-
- if (fireLockout)
- {
- UserLockedOut?.Invoke(this, new GenericEventArgs<User>(user));
- }
}
/// <summary>
diff --git a/Jellyfin.Drawing.Skia/SkiaCodecException.cs b/Jellyfin.Drawing.Skia/SkiaCodecException.cs
new file mode 100644
index 000000000..f848636bc
--- /dev/null
+++ b/Jellyfin.Drawing.Skia/SkiaCodecException.cs
@@ -0,0 +1,46 @@
+using System.Globalization;
+using SkiaSharp;
+
+namespace Jellyfin.Drawing.Skia
+{
+ /// <summary>
+ /// Represents errors that occur during interaction with Skia codecs.
+ /// </summary>
+ public class SkiaCodecException : SkiaException
+ {
+ /// <summary>
+ /// Returns the non-successfull codec result returned by Skia.
+ /// </summary>
+ /// <value>The non-successfull codec result returned by Skia.</value>
+ public SKCodecResult CodecResult { get; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SkiaCodecException" /> class.
+ /// </summary>
+ /// <param name="result">The non-successfull codec result returned by Skia.</param>
+ public SkiaCodecException(SKCodecResult result) : base()
+ {
+ CodecResult = result;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SkiaCodecException" /> class
+ /// with a specified error message.
+ /// </summary>
+ /// <param name="result">The non-successfull codec result returned by Skia.</param>
+ /// <param name="message">The message that describes the error.</param>
+ public SkiaCodecException(SKCodecResult result, string message)
+ : base(message)
+ {
+ CodecResult = result;
+ }
+
+ /// <inheritdoc />
+ public override string ToString()
+ => string.Format(
+ CultureInfo.InvariantCulture,
+ "Non-success codec result: {0}\n{1}",
+ CodecResult,
+ base.ToString());
+ }
+}
diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index 80b9974fa..66b814f6e 100644
--- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -9,6 +9,7 @@ using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Globalization;
using Microsoft.Extensions.Logging;
using SkiaSharp;
+using static Jellyfin.Drawing.Skia.SkiaHelper;
namespace Jellyfin.Drawing.Skia
{
@@ -184,16 +185,23 @@ namespace Jellyfin.Drawing.Skia
}
}
+ /// <inheritdoc />
public ImageDimensions GetImageSize(string path)
{
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
if (!File.Exists(path))
{
throw new FileNotFoundException("File not found", path);
}
- using (var s = new SKFileStream(path))
- using (var codec = SKCodec.Create(s))
+ using (var codec = SKCodec.Create(path, out SKCodecResult result))
{
+ EnsureSuccess(result);
+
var info = codec.Info;
return new ImageDimensions(info.Width, info.Height);
diff --git a/Jellyfin.Drawing.Skia/SkiaException.cs b/Jellyfin.Drawing.Skia/SkiaException.cs
new file mode 100644
index 000000000..7aeaf083e
--- /dev/null
+++ b/Jellyfin.Drawing.Skia/SkiaException.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Jellyfin.Drawing.Skia
+{
+ /// <summary>
+ /// Represents errors that occur during interaction with Skia.
+ /// </summary>
+ public class SkiaException : Exception
+ {
+ /// <inheritdoc />
+ public SkiaException() : base()
+ {
+ }
+
+ /// <inheritdoc />
+ public SkiaException(string message) : base(message)
+ {
+ }
+
+ /// <inheritdoc />
+ public SkiaException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ }
+}
diff --git a/Jellyfin.Drawing.Skia/SkiaHelper.cs b/Jellyfin.Drawing.Skia/SkiaHelper.cs
new file mode 100644
index 000000000..f9c79c855
--- /dev/null
+++ b/Jellyfin.Drawing.Skia/SkiaHelper.cs
@@ -0,0 +1,23 @@
+using SkiaSharp;
+
+namespace Jellyfin.Drawing.Skia
+{
+ /// <summary>
+ /// Class containing helper methods for working with SkiaSharp.
+ /// </summary>
+ public static class SkiaHelper
+ {
+ /// <summary>
+ /// Ensures the result is a success
+ /// by throwing an exception when that's not the case.
+ /// </summary>
+ /// <param name="result">The result returned by Skia.</param>
+ public static void EnsureSuccess(SKCodecResult result)
+ {
+ if (result != SKCodecResult.Success)
+ {
+ throw new SkiaCodecException(result);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs
index f63ab2bb4..9336c720f 100644
--- a/MediaBrowser.Model/Users/UserPolicy.cs
+++ b/MediaBrowser.Model/Users/UserPolicy.cs
@@ -66,7 +66,7 @@ namespace MediaBrowser.Model.Users
public bool EnableAllFolders { get; set; }
public int InvalidLoginAttemptCount { get; set; }
- public int? LoginAttemptsBeforeLockout { get; set; }
+ public int LoginAttemptsBeforeLockout { get; set; }
public bool EnablePublicSharing { get; set; }