aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Data/Entities
diff options
context:
space:
mode:
authorBaronGreenback <jimcartlidge@yahoo.co.uk>2020-06-15 10:01:55 +0100
committerGitHub <noreply@github.com>2020-06-15 10:01:55 +0100
commit862bcdba67d3b992fc7e68a7428fc225c898fce3 (patch)
tree10a66c6cc918962cd2dad54fe85c65016af9cf9d /Jellyfin.Data/Entities
parent4d50941d4458dc93880d99192fd1c26a8f625d66 (diff)
parent100e9d586dff877610c488936aa035f61f6fedb5 (diff)
Merge pull request #23 from jellyfin/master
updating
Diffstat (limited to 'Jellyfin.Data/Entities')
-rw-r--r--Jellyfin.Data/Entities/AccessSchedule.cs91
-rw-r--r--Jellyfin.Data/Entities/Artwork.cs1
-rw-r--r--Jellyfin.Data/Entities/Book.cs1
-rw-r--r--Jellyfin.Data/Entities/BookMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Chapter.cs1
-rw-r--r--Jellyfin.Data/Entities/Collection.cs1
-rw-r--r--Jellyfin.Data/Entities/CollectionItem.cs1
-rw-r--r--Jellyfin.Data/Entities/Company.cs1
-rw-r--r--Jellyfin.Data/Entities/CompanyMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/CustomItem.cs1
-rw-r--r--Jellyfin.Data/Entities/CustomItemMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Episode.cs1
-rw-r--r--Jellyfin.Data/Entities/EpisodeMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Genre.cs1
-rw-r--r--Jellyfin.Data/Entities/Group.cs103
-rw-r--r--Jellyfin.Data/Entities/ImageInfo.cs30
-rw-r--r--Jellyfin.Data/Entities/Library.cs1
-rw-r--r--Jellyfin.Data/Entities/LibraryItem.cs1
-rw-r--r--Jellyfin.Data/Entities/LibraryRoot.cs1
-rw-r--r--Jellyfin.Data/Entities/MediaFile.cs1
-rw-r--r--Jellyfin.Data/Entities/MediaFileStream.cs1
-rw-r--r--Jellyfin.Data/Entities/Metadata.cs1
-rw-r--r--Jellyfin.Data/Entities/MetadataProvider.cs1
-rw-r--r--Jellyfin.Data/Entities/MetadataProviderId.cs1
-rw-r--r--Jellyfin.Data/Entities/Movie.cs1
-rw-r--r--Jellyfin.Data/Entities/MovieMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/MusicAlbum.cs1
-rw-r--r--Jellyfin.Data/Entities/MusicAlbumMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Permission.cs137
-rw-r--r--Jellyfin.Data/Entities/Person.cs1
-rw-r--r--Jellyfin.Data/Entities/PersonRole.cs1
-rw-r--r--Jellyfin.Data/Entities/Photo.cs1
-rw-r--r--Jellyfin.Data/Entities/PhotoMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Preference.cs100
-rw-r--r--Jellyfin.Data/Entities/ProviderMapping.cs7
-rw-r--r--Jellyfin.Data/Entities/Rating.cs1
-rw-r--r--Jellyfin.Data/Entities/RatingSource.cs1
-rw-r--r--Jellyfin.Data/Entities/Release.cs1
-rw-r--r--Jellyfin.Data/Entities/Season.cs1
-rw-r--r--Jellyfin.Data/Entities/SeasonMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Series.cs21
-rw-r--r--Jellyfin.Data/Entities/SeriesMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/Track.cs1
-rw-r--r--Jellyfin.Data/Entities/TrackMetadata.cs1
-rw-r--r--Jellyfin.Data/Entities/User.cs500
45 files changed, 660 insertions, 366 deletions
diff --git a/Jellyfin.Data/Entities/AccessSchedule.cs b/Jellyfin.Data/Entities/AccessSchedule.cs
new file mode 100644
index 000000000..7d1b76a3f
--- /dev/null
+++ b/Jellyfin.Data/Entities/AccessSchedule.cs
@@ -0,0 +1,91 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text.Json.Serialization;
+using System.Xml.Serialization;
+using Jellyfin.Data.Enums;
+
+namespace Jellyfin.Data.Entities
+{
+ /// <summary>
+ /// An entity representing a user's access schedule.
+ /// </summary>
+ public class AccessSchedule
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AccessSchedule"/> class.
+ /// </summary>
+ /// <param name="dayOfWeek">The day of the week.</param>
+ /// <param name="startHour">The start hour.</param>
+ /// <param name="endHour">The end hour.</param>
+ /// <param name="userId">The associated user's id.</param>
+ public AccessSchedule(DynamicDayOfWeek dayOfWeek, double startHour, double endHour, Guid userId)
+ {
+ UserId = userId;
+ DayOfWeek = dayOfWeek;
+ StartHour = startHour;
+ EndHour = endHour;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AccessSchedule"/> class.
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </summary>
+ protected AccessSchedule()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id of this instance.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [XmlIgnore]
+ [Key]
+ [Required]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the id of the associated user.
+ /// </summary>
+ [XmlIgnore]
+ [Required]
+ public Guid UserId { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the day of week.
+ /// </summary>
+ /// <value>The day of week.</value>
+ [Required]
+ public DynamicDayOfWeek DayOfWeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the start hour.
+ /// </summary>
+ /// <value>The start hour.</value>
+ [Required]
+ public double StartHour { get; set; }
+
+ /// <summary>
+ /// Gets or sets the end hour.
+ /// </summary>
+ /// <value>The end hour.</value>
+ [Required]
+ public double EndHour { get; set; }
+
+ /// <summary>
+ /// Static create function (for use in LINQ queries, etc.)
+ /// </summary>
+ /// <param name="dayOfWeek">The day of the week.</param>
+ /// <param name="startHour">The start hour.</param>
+ /// <param name="endHour">The end hour.</param>
+ /// <param name="userId">The associated user's id.</param>
+ /// <returns>The newly created instance.</returns>
+ public static AccessSchedule Create(DynamicDayOfWeek dayOfWeek, double startHour, double endHour, Guid userId)
+ {
+ return new AccessSchedule(dayOfWeek, startHour, endHour, userId);
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Artwork.cs b/Jellyfin.Data/Entities/Artwork.cs
index bf3029368..214fb4cb1 100644
--- a/Jellyfin.Data/Entities/Artwork.cs
+++ b/Jellyfin.Data/Entities/Artwork.cs
@@ -189,7 +189,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Book.cs b/Jellyfin.Data/Entities/Book.cs
index 42d24e31d..faefc7400 100644
--- a/Jellyfin.Data/Entities/Book.cs
+++ b/Jellyfin.Data/Entities/Book.cs
@@ -63,7 +63,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/BookMetadata.cs b/Jellyfin.Data/Entities/BookMetadata.cs
index d52fe7605..dd389b64a 100644
--- a/Jellyfin.Data/Entities/BookMetadata.cs
+++ b/Jellyfin.Data/Entities/BookMetadata.cs
@@ -101,7 +101,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Company_Publishers_Id")]
public virtual ICollection<Company> Publishers { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Chapter.cs b/Jellyfin.Data/Entities/Chapter.cs
index d48cb9b62..9b3a5e827 100644
--- a/Jellyfin.Data/Entities/Chapter.cs
+++ b/Jellyfin.Data/Entities/Chapter.cs
@@ -257,7 +257,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Collection.cs b/Jellyfin.Data/Entities/Collection.cs
index e2fa3a5bd..c040cfe33 100644
--- a/Jellyfin.Data/Entities/Collection.cs
+++ b/Jellyfin.Data/Entities/Collection.cs
@@ -114,7 +114,6 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("CollectionItem_CollectionItem_Id")]
public virtual ICollection<CollectionItem> CollectionItem { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/CollectionItem.cs b/Jellyfin.Data/Entities/CollectionItem.cs
index 4a3d06639..c5e54c3a2 100644
--- a/Jellyfin.Data/Entities/CollectionItem.cs
+++ b/Jellyfin.Data/Entities/CollectionItem.cs
@@ -137,7 +137,6 @@ namespace Jellyfin.Data.Entities
/// </remarks>
[ForeignKey("CollectionItem_Previous_Id")]
public virtual CollectionItem Previous { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Company.cs b/Jellyfin.Data/Entities/Company.cs
index 0650271c6..7d6f3b207 100644
--- a/Jellyfin.Data/Entities/Company.cs
+++ b/Jellyfin.Data/Entities/Company.cs
@@ -131,7 +131,6 @@ namespace Jellyfin.Data.Entities
public virtual ICollection<CompanyMetadata> CompanyMetadata { get; protected set; }
[ForeignKey("Company_Parent_Id")]
public virtual Company Parent { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/CompanyMetadata.cs b/Jellyfin.Data/Entities/CompanyMetadata.cs
index b3ec9c1a7..1ad03b4f9 100644
--- a/Jellyfin.Data/Entities/CompanyMetadata.cs
+++ b/Jellyfin.Data/Entities/CompanyMetadata.cs
@@ -210,7 +210,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/CustomItem.cs b/Jellyfin.Data/Entities/CustomItem.cs
index 2006717bf..5f6fc3a23 100644
--- a/Jellyfin.Data/Entities/CustomItem.cs
+++ b/Jellyfin.Data/Entities/CustomItem.cs
@@ -62,7 +62,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/CustomItemMetadata.cs b/Jellyfin.Data/Entities/CustomItemMetadata.cs
index e09e4467a..ee37aaaa9 100644
--- a/Jellyfin.Data/Entities/CustomItemMetadata.cs
+++ b/Jellyfin.Data/Entities/CustomItemMetadata.cs
@@ -61,7 +61,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Episode.cs b/Jellyfin.Data/Entities/Episode.cs
index 6f6baa14d..88531205f 100644
--- a/Jellyfin.Data/Entities/Episode.cs
+++ b/Jellyfin.Data/Entities/Episode.cs
@@ -104,7 +104,6 @@ namespace Jellyfin.Data.Entities
public virtual ICollection<Release> Releases { get; protected set; }
[ForeignKey("EpisodeMetadata_EpisodeMetadata_Id")]
public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/EpisodeMetadata.cs b/Jellyfin.Data/Entities/EpisodeMetadata.cs
index e5431bf22..0aa4b4270 100644
--- a/Jellyfin.Data/Entities/EpisodeMetadata.cs
+++ b/Jellyfin.Data/Entities/EpisodeMetadata.cs
@@ -173,7 +173,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Genre.cs b/Jellyfin.Data/Entities/Genre.cs
index 38f289a8e..ff0710671 100644
--- a/Jellyfin.Data/Entities/Genre.cs
+++ b/Jellyfin.Data/Entities/Genre.cs
@@ -146,7 +146,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Group.cs b/Jellyfin.Data/Entities/Group.cs
index 54f9f4905..5cbb126f9 100644
--- a/Jellyfin.Data/Entities/Group.cs
+++ b/Jellyfin.Data/Entities/Group.cs
@@ -2,19 +2,32 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using Jellyfin.Data.Enums;
namespace Jellyfin.Data.Entities
{
- public partial class Group
+ /// <summary>
+ /// An entity representing a group.
+ /// </summary>
+ public partial class Group : IHasPermissions, ISavingChanges
{
- partial void Init();
-
/// <summary>
- /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// Initializes a new instance of the <see cref="Group"/> class.
+ /// Public constructor with required data.
/// </summary>
- protected Group()
+ /// <param name="name">The name of the group.</param>
+ public Group(string name)
{
- GroupPermissions = new HashSet<Permission>();
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+ Id = Guid.NewGuid();
+
+ Permissions = new HashSet<Permission>();
ProviderMappings = new HashSet<ProviderMapping>();
Preferences = new HashSet<Preference>();
@@ -22,66 +35,45 @@ namespace Jellyfin.Data.Entities
}
/// <summary>
- /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
- /// </summary>
- public static Group CreateGroupUnsafe()
- {
- return new Group();
- }
-
- /// <summary>
- /// Public constructor with required data
+ /// Initializes a new instance of the <see cref="Group"/> class.
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
- /// <param name="name"></param>
- /// <param name="_user0"></param>
- public Group(string name, User _user0)
+ protected Group()
{
- if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
- this.Name = name;
-
- if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
- _user0.Groups.Add(this);
-
- this.GroupPermissions = new HashSet<Permission>();
- this.ProviderMappings = new HashSet<ProviderMapping>();
- this.Preferences = new HashSet<Preference>();
-
Init();
}
- /// <summary>
- /// Static create function (for use in LINQ queries, etc.)
- /// </summary>
- /// <param name="name"></param>
- /// <param name="_user0"></param>
- public static Group Create(string name, User _user0)
- {
- return new Group(name, _user0);
- }
-
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
- /// Identity, Indexed, Required
+ /// Gets or sets the id of this group.
/// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
[Key]
[Required]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int Id { get; protected set; }
+ public Guid Id { get; protected set; }
/// <summary>
- /// Required, Max length = 255
+ /// Gets or sets the group's name.
/// </summary>
+ /// <remarks>
+ /// Required, Max length = 255.
+ /// </remarks>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <summary>
- /// Required, ConcurrenyToken
+ /// Gets or sets the row version.
/// </summary>
+ /// <remarks>
+ /// Required, Concurrency Token.
+ /// </remarks>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
@@ -96,7 +88,7 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("Permission_GroupPermissions_Id")]
- public virtual ICollection<Permission> GroupPermissions { get; protected set; }
+ public virtual ICollection<Permission> Permissions { get; protected set; }
[ForeignKey("ProviderMapping_ProviderMappings_Id")]
public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; }
@@ -104,6 +96,27 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Preference_Preferences_Id")]
public virtual ICollection<Preference> Preferences { get; protected set; }
+ /// <summary>
+ /// Static create function (for use in LINQ queries, etc.)
+ /// </summary>
+ /// <param name="name">The name of this group</param>
+ public static Group Create(string name)
+ {
+ return new Group(name);
+ }
+
+ /// <inheritdoc/>
+ public bool HasPermission(PermissionKind kind)
+ {
+ return Permissions.First(p => p.Kind == kind).Value;
+ }
+
+ /// <inheritdoc/>
+ public void SetPermission(PermissionKind kind, bool value)
+ {
+ Permissions.First(p => p.Kind == kind).Value = value;
+ }
+
+ partial void Init();
}
}
-
diff --git a/Jellyfin.Data/Entities/ImageInfo.cs b/Jellyfin.Data/Entities/ImageInfo.cs
new file mode 100644
index 000000000..64e36a791
--- /dev/null
+++ b/Jellyfin.Data/Entities/ImageInfo.cs
@@ -0,0 +1,30 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Jellyfin.Data.Entities
+{
+ public class ImageInfo
+ {
+ public ImageInfo(string path)
+ {
+ Path = path;
+ LastModified = DateTime.UtcNow;
+ }
+
+ [Key]
+ [Required]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ public Guid? UserId { get; protected set; }
+
+ [Required]
+ [MaxLength(512)]
+ [StringLength(512)]
+ public string Path { get; set; }
+
+ [Required]
+ public DateTime LastModified { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Library.cs b/Jellyfin.Data/Entities/Library.cs
index c11c09e91..a5cc5c8da 100644
--- a/Jellyfin.Data/Entities/Library.cs
+++ b/Jellyfin.Data/Entities/Library.cs
@@ -141,7 +141,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/LibraryItem.cs b/Jellyfin.Data/Entities/LibraryItem.cs
index af6c640b9..c2ba7059d 100644
--- a/Jellyfin.Data/Entities/LibraryItem.cs
+++ b/Jellyfin.Data/Entities/LibraryItem.cs
@@ -164,7 +164,6 @@ namespace Jellyfin.Data.Entities
/// </summary>
[ForeignKey("LibraryRoot_Id")]
public virtual LibraryRoot LibraryRoot { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/LibraryRoot.cs b/Jellyfin.Data/Entities/LibraryRoot.cs
index bbc23e1c9..7823db02a 100644
--- a/Jellyfin.Data/Entities/LibraryRoot.cs
+++ b/Jellyfin.Data/Entities/LibraryRoot.cs
@@ -186,7 +186,6 @@ namespace Jellyfin.Data.Entities
/// </summary>
[ForeignKey("Library_Id")]
public virtual Library Library { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MediaFile.cs b/Jellyfin.Data/Entities/MediaFile.cs
index 719539e5c..94c39a28a 100644
--- a/Jellyfin.Data/Entities/MediaFile.cs
+++ b/Jellyfin.Data/Entities/MediaFile.cs
@@ -194,7 +194,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("MediaFileStream_MediaFileStreams_Id")]
public virtual ICollection<MediaFileStream> MediaFileStreams { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MediaFileStream.cs b/Jellyfin.Data/Entities/MediaFileStream.cs
index 7b3399731..723977fdf 100644
--- a/Jellyfin.Data/Entities/MediaFileStream.cs
+++ b/Jellyfin.Data/Entities/MediaFileStream.cs
@@ -143,7 +143,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs
index 467ee6822..6558642cf 100644
--- a/Jellyfin.Data/Entities/Metadata.cs
+++ b/Jellyfin.Data/Entities/Metadata.cs
@@ -374,7 +374,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MetadataProvider.cs b/Jellyfin.Data/Entities/MetadataProvider.cs
index 4e4f107fb..bf9689709 100644
--- a/Jellyfin.Data/Entities/MetadataProvider.cs
+++ b/Jellyfin.Data/Entities/MetadataProvider.cs
@@ -141,7 +141,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/MetadataProviderId.cs b/Jellyfin.Data/Entities/MetadataProviderId.cs
index 926f223de..c49c6f42e 100644
--- a/Jellyfin.Data/Entities/MetadataProviderId.cs
+++ b/Jellyfin.Data/Entities/MetadataProviderId.cs
@@ -173,7 +173,6 @@ namespace Jellyfin.Data.Entities
/// </summary>
[ForeignKey("MetadataProvider_Id")]
public virtual MetadataProvider MetadataProvider { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Movie.cs b/Jellyfin.Data/Entities/Movie.cs
index b359b42fc..ad2504b0d 100644
--- a/Jellyfin.Data/Entities/Movie.cs
+++ b/Jellyfin.Data/Entities/Movie.cs
@@ -63,7 +63,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("MovieMetadata_MovieMetadata_Id")]
public virtual ICollection<MovieMetadata> MovieMetadata { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MovieMetadata.cs b/Jellyfin.Data/Entities/MovieMetadata.cs
index 319ae94e5..1f8f1c2a0 100644
--- a/Jellyfin.Data/Entities/MovieMetadata.cs
+++ b/Jellyfin.Data/Entities/MovieMetadata.cs
@@ -217,7 +217,6 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("Company_Studios_Id")]
public virtual ICollection<Company> Studios { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MusicAlbum.cs b/Jellyfin.Data/Entities/MusicAlbum.cs
index 00cb8fe00..e07f4357b 100644
--- a/Jellyfin.Data/Entities/MusicAlbum.cs
+++ b/Jellyfin.Data/Entities/MusicAlbum.cs
@@ -62,7 +62,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Track_Tracks_Id")]
public virtual ICollection<Track> Tracks { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs
index b52ca6564..7743890a6 100644
--- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs
+++ b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs
@@ -181,7 +181,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Company_Labels_Id")]
public virtual ICollection<Company> Labels { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Permission.cs b/Jellyfin.Data/Entities/Permission.cs
index 0b5b52cbd..b675e911d 100644
--- a/Jellyfin.Data/Entities/Permission.cs
+++ b/Jellyfin.Data/Entities/Permission.cs
@@ -1,64 +1,35 @@
-using System;
-using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
-using System.Runtime.CompilerServices;
+using Jellyfin.Data.Enums;
namespace Jellyfin.Data.Entities
{
- public partial class Permission
+ /// <summary>
+ /// An entity representing whether the associated user has a specific permission.
+ /// </summary>
+ public partial class Permission : ISavingChanges
{
- partial void Init();
-
- /// <summary>
- /// Default constructor. Protected due to required properties, but present because EF needs it.
- /// </summary>
- protected Permission()
- {
- Init();
- }
-
/// <summary>
- /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+ /// Initializes a new instance of the <see cref="Permission"/> class.
+ /// Public constructor with required data.
/// </summary>
- public static Permission CreatePermissionUnsafe()
+ /// <param name="kind">The permission kind.</param>
+ /// <param name="value">The value of this permission.</param>
+ public Permission(PermissionKind kind, bool value)
{
- return new Permission();
- }
-
- /// <summary>
- /// Public constructor with required data
- /// </summary>
- /// <param name="kind"></param>
- /// <param name="value"></param>
- /// <param name="_user0"></param>
- /// <param name="_group1"></param>
- public Permission(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
- {
- this.Kind = kind;
-
- this.Value = value;
-
- if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
- _user0.Permissions.Add(this);
-
- if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
- _group1.GroupPermissions.Add(this);
-
+ Kind = kind;
+ Value = value;
Init();
}
/// <summary>
- /// Static create function (for use in LINQ queries, etc.)
+ /// Initializes a new instance of the <see cref="Permission"/> class.
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
- /// <param name="kind"></param>
- /// <param name="value"></param>
- /// <param name="_user0"></param>
- /// <param name="_group1"></param>
- public static Permission Create(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
+ protected Permission()
{
- return new Permission(kind, value, _user0, _group1);
+ Init();
}
/*************************************************************************
@@ -66,79 +37,61 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
/// <summary>
- /// Identity, Indexed, Required
+ /// Gets or sets the id of this permission.
/// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }
/// <summary>
- /// Backing field for Kind
- /// </summary>
- protected Enums.PermissionKind _Kind;
- /// <summary>
- /// When provided in a partial class, allows value of Kind to be changed before setting.
- /// </summary>
- partial void SetKind(Enums.PermissionKind oldValue, ref Enums.PermissionKind newValue);
- /// <summary>
- /// When provided in a partial class, allows value of Kind to be changed before returning.
- /// </summary>
- partial void GetKind(ref Enums.PermissionKind result);
-
- /// <summary>
- /// Required
+ /// Gets or sets the type of this permission.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
- public Enums.PermissionKind Kind
- {
- get
- {
- Enums.PermissionKind value = _Kind;
- GetKind(ref value);
- return (_Kind = value);
- }
- set
- {
- Enums.PermissionKind oldValue = _Kind;
- SetKind(oldValue, ref value);
- if (oldValue != value)
- {
- _Kind = value;
- OnPropertyChanged();
- }
- }
- }
+ public PermissionKind Kind { get; protected set; }
/// <summary>
- /// Required
+ /// Gets or sets a value indicating whether the associated user has this permission.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
public bool Value { get; set; }
/// <summary>
- /// Required, ConcurrenyToken
+ /// Gets or sets the row version.
/// </summary>
+ /// <remarks>
+ /// Required, ConcurrencyToken.
+ /// </remarks>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
- public void OnSavingChanges()
+ /// <summary>
+ /// Static create function (for use in LINQ queries, etc.)
+ /// </summary>
+ /// <param name="kind">The permission kind.</param>
+ /// <param name="value">The value of this permission.</param>
+ /// <returns>The newly created instance.</returns>
+ public static Permission Create(PermissionKind kind, bool value)
{
- RowVersion++;
+ return new Permission(kind, value);
}
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- public virtual event PropertyChangedEventHandler PropertyChanged;
-
- protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ /// <inheritdoc/>
+ public void OnSavingChanges()
{
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ RowVersion++;
}
+ partial void Init();
}
}
-
diff --git a/Jellyfin.Data/Entities/Person.cs b/Jellyfin.Data/Entities/Person.cs
index d893b7e39..f71418819 100644
--- a/Jellyfin.Data/Entities/Person.cs
+++ b/Jellyfin.Data/Entities/Person.cs
@@ -296,7 +296,6 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("MetadataProviderId_Sources_Id")]
public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/PersonRole.cs b/Jellyfin.Data/Entities/PersonRole.cs
index 9bd12c7fb..a3d047115 100644
--- a/Jellyfin.Data/Entities/PersonRole.cs
+++ b/Jellyfin.Data/Entities/PersonRole.cs
@@ -203,7 +203,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("MetadataProviderId_Sources_Id")]
public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Photo.cs b/Jellyfin.Data/Entities/Photo.cs
index 7abe62891..226730126 100644
--- a/Jellyfin.Data/Entities/Photo.cs
+++ b/Jellyfin.Data/Entities/Photo.cs
@@ -62,7 +62,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/PhotoMetadata.cs b/Jellyfin.Data/Entities/PhotoMetadata.cs
index c5502f707..2bb239cdd 100644
--- a/Jellyfin.Data/Entities/PhotoMetadata.cs
+++ b/Jellyfin.Data/Entities/PhotoMetadata.cs
@@ -62,7 +62,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Preference.cs b/Jellyfin.Data/Entities/Preference.cs
index 505f52e6b..0ca9d7eff 100644
--- a/Jellyfin.Data/Entities/Preference.cs
+++ b/Jellyfin.Data/Entities/Preference.cs
@@ -1,63 +1,33 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
namespace Jellyfin.Data.Entities
{
- public partial class Preference
+ /// <summary>
+ /// An entity representing a preference attached to a user or group.
+ /// </summary>
+ public class Preference : ISavingChanges
{
- partial void Init();
-
- /// <summary>
- /// Default constructor. Protected due to required properties, but present because EF needs it.
- /// </summary>
- protected Preference()
- {
- Init();
- }
-
/// <summary>
- /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+ /// Initializes a new instance of the <see cref="Preference"/> class.
+ /// Public constructor with required data.
/// </summary>
- public static Preference CreatePreferenceUnsafe()
+ /// <param name="kind">The preference kind.</param>
+ /// <param name="value">The value.</param>
+ public Preference(PreferenceKind kind, string value)
{
- return new Preference();
- }
-
- /// <summary>
- /// Public constructor with required data
- /// </summary>
- /// <param name="kind"></param>
- /// <param name="value"></param>
- /// <param name="_user0"></param>
- /// <param name="_group1"></param>
- public Preference(Enums.PreferenceKind kind, string value, User _user0, Group _group1)
- {
- this.Kind = kind;
-
- if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value));
- this.Value = value;
-
- if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
- _user0.Preferences.Add(this);
-
- if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
- _group1.Preferences.Add(this);
-
-
- Init();
+ Kind = kind;
+ Value = value ?? throw new ArgumentNullException(nameof(value));
}
/// <summary>
- /// Static create function (for use in LINQ queries, etc.)
+ /// Initializes a new instance of the <see cref="Preference"/> class.
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
- /// <param name="kind"></param>
- /// <param name="value"></param>
- /// <param name="_user0"></param>
- /// <param name="_group1"></param>
- public static Preference Create(Enums.PreferenceKind kind, string value, User _user0, Group _group1)
+ protected Preference()
{
- return new Preference(kind, value, _user0, _group1);
}
/*************************************************************************
@@ -65,43 +35,61 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
/// <summary>
- /// Identity, Indexed, Required
+ /// Gets or sets the id of this preference.
/// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }
/// <summary>
- /// Required
+ /// Gets or sets the type of this preference.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
- public Enums.PreferenceKind Kind { get; set; }
+ public PreferenceKind Kind { get; protected set; }
/// <summary>
- /// Required, Max length = 65535
+ /// Gets or sets the value of this preference.
/// </summary>
+ /// <remarks>
+ /// Required, Max length = 65535.
+ /// </remarks>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Value { get; set; }
/// <summary>
- /// Required, ConcurrenyToken
+ /// Gets or sets the row version.
/// </summary>
+ /// <remarks>
+ /// Required, ConcurrencyToken.
+ /// </remarks>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
+ /// <summary>
+ /// Static create function (for use in LINQ queries, etc.)
+ /// </summary>
+ /// <param name="kind">The preference kind.</param>
+ /// <param name="value">The value.</param>
+ /// <returns>The new instance.</returns>
+ public static Preference Create(PreferenceKind kind, string value)
+ {
+ return new Preference(kind, value);
+ }
+
+ /// <inheritdoc/>
public void OnSavingChanges()
{
RowVersion++;
}
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
}
}
-
diff --git a/Jellyfin.Data/Entities/ProviderMapping.cs b/Jellyfin.Data/Entities/ProviderMapping.cs
index 6197bd97b..e86d9737f 100644
--- a/Jellyfin.Data/Entities/ProviderMapping.cs
+++ b/Jellyfin.Data/Entities/ProviderMapping.cs
@@ -43,12 +43,6 @@ namespace Jellyfin.Data.Entities
if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata));
this.ProviderData = providerdata;
- if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
- _user0.ProviderMappings.Add(this);
-
- if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
- _group1.ProviderMappings.Add(this);
-
Init();
}
@@ -117,7 +111,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Rating.cs b/Jellyfin.Data/Entities/Rating.cs
index f70ea8b33..0c8b99ca2 100644
--- a/Jellyfin.Data/Entities/Rating.cs
+++ b/Jellyfin.Data/Entities/Rating.cs
@@ -181,7 +181,6 @@ namespace Jellyfin.Data.Entities
/// </summary>
[ForeignKey("RatingSource_RatingType_Id")]
public virtual RatingSource RatingType { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/RatingSource.cs b/Jellyfin.Data/Entities/RatingSource.cs
index 070f1ae27..c829042b5 100644
--- a/Jellyfin.Data/Entities/RatingSource.cs
+++ b/Jellyfin.Data/Entities/RatingSource.cs
@@ -225,7 +225,6 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("MetadataProviderId_Source_Id")]
public virtual MetadataProviderId Source { get; set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Release.cs b/Jellyfin.Data/Entities/Release.cs
index d1928fcf7..35fcbb4b7 100644
--- a/Jellyfin.Data/Entities/Release.cs
+++ b/Jellyfin.Data/Entities/Release.cs
@@ -182,7 +182,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Chapter_Chapters_Id")]
public virtual ICollection<Chapter> Chapters { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Season.cs b/Jellyfin.Data/Entities/Season.cs
index 96e89cde0..2a861b660 100644
--- a/Jellyfin.Data/Entities/Season.cs
+++ b/Jellyfin.Data/Entities/Season.cs
@@ -105,7 +105,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Episode_Episodes_Id")]
public virtual ICollection<Episode> Episodes { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/SeasonMetadata.cs b/Jellyfin.Data/Entities/SeasonMetadata.cs
index 64ecbfbfa..10320c6bb 100644
--- a/Jellyfin.Data/Entities/SeasonMetadata.cs
+++ b/Jellyfin.Data/Entities/SeasonMetadata.cs
@@ -100,7 +100,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/Series.cs b/Jellyfin.Data/Entities/Series.cs
index 097b9958e..cf1d6b781 100644
--- a/Jellyfin.Data/Entities/Series.cs
+++ b/Jellyfin.Data/Entities/Series.cs
@@ -20,14 +20,6 @@ namespace Jellyfin.Data.Entities
}
/// <summary>
- /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
- /// </summary>
- public static Series CreateSeriesUnsafe()
- {
- return new Series();
- }
-
- /// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
@@ -57,27 +49,27 @@ namespace Jellyfin.Data.Entities
/// <summary>
/// Backing field for AirsDayOfWeek
/// </summary>
- protected Enums.Weekday? _AirsDayOfWeek;
+ protected DayOfWeek? _AirsDayOfWeek;
/// <summary>
/// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting.
/// </summary>
- partial void SetAirsDayOfWeek(Enums.Weekday? oldValue, ref Enums.Weekday? newValue);
+ partial void SetAirsDayOfWeek(DayOfWeek? oldValue, ref DayOfWeek? newValue);
/// <summary>
/// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning.
/// </summary>
- partial void GetAirsDayOfWeek(ref Enums.Weekday? result);
+ partial void GetAirsDayOfWeek(ref DayOfWeek? result);
- public Enums.Weekday? AirsDayOfWeek
+ public DayOfWeek? AirsDayOfWeek
{
get
{
- Enums.Weekday? value = _AirsDayOfWeek;
+ DayOfWeek? value = _AirsDayOfWeek;
GetAirsDayOfWeek(ref value);
return (_AirsDayOfWeek = value);
}
set
{
- Enums.Weekday? oldValue = _AirsDayOfWeek;
+ DayOfWeek? oldValue = _AirsDayOfWeek;
SetAirsDayOfWeek(oldValue, ref value);
if (oldValue != value)
{
@@ -161,7 +153,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("Season_Seasons_Id")]
public virtual ICollection<Season> Seasons { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/SeriesMetadata.cs b/Jellyfin.Data/Entities/SeriesMetadata.cs
index 52691783f..bb31c2e4e 100644
--- a/Jellyfin.Data/Entities/SeriesMetadata.cs
+++ b/Jellyfin.Data/Entities/SeriesMetadata.cs
@@ -217,7 +217,6 @@ namespace Jellyfin.Data.Entities
*************************************************************************/
[ForeignKey("Company_Networks_Id")]
public virtual ICollection<Company> Networks { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/Track.cs b/Jellyfin.Data/Entities/Track.cs
index 079d73d2b..c9e8fd1c3 100644
--- a/Jellyfin.Data/Entities/Track.cs
+++ b/Jellyfin.Data/Entities/Track.cs
@@ -106,7 +106,6 @@ namespace Jellyfin.Data.Entities
[ForeignKey("TrackMetadata_TrackMetadata_Id")]
public virtual ICollection<TrackMetadata> TrackMetadata { get; protected set; }
-
}
}
diff --git a/Jellyfin.Data/Entities/TrackMetadata.cs b/Jellyfin.Data/Entities/TrackMetadata.cs
index 86c9161f6..7b99c0683 100644
--- a/Jellyfin.Data/Entities/TrackMetadata.cs
+++ b/Jellyfin.Data/Entities/TrackMetadata.cs
@@ -62,7 +62,6 @@ namespace Jellyfin.Data.Entities
/*************************************************************************
* Navigation properties
*************************************************************************/
-
}
}
diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs
index a81d5215b..b89b0a8f4 100644
--- a/Jellyfin.Data/Entities/User.cs
+++ b/Jellyfin.Data/Entities/User.cs
@@ -2,234 +2,506 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Globalization;
+using System.Linq;
+using System.Text.Json.Serialization;
+using Jellyfin.Data.Enums;
namespace Jellyfin.Data.Entities
{
- public partial class User
+ /// <summary>
+ /// An entity representing a user.
+ /// </summary>
+ public partial class User : IHasPermissions, ISavingChanges
{
- partial void Init();
+ /// <summary>
+ /// The values being delimited here are Guids, so commas work as they do not appear in Guids.
+ /// </summary>
+ private const char Delimiter = ',';
/// <summary>
- /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// Initializes a new instance of the <see cref="User"/> class.
+ /// Public constructor with required data.
/// </summary>
- protected User()
+ /// <param name="username">The username for the new user.</param>
+ /// <param name="authenticationProviderId">The Id of the user's authentication provider.</param>
+ /// <param name="passwordResetProviderId">The Id of the user's password reset provider.</param>
+ public User(string username, string authenticationProviderId, string passwordResetProviderId)
{
- Groups = new HashSet<Group>();
+ if (string.IsNullOrEmpty(username))
+ {
+ throw new ArgumentNullException(nameof(username));
+ }
+
+ if (string.IsNullOrEmpty(authenticationProviderId))
+ {
+ throw new ArgumentNullException(nameof(authenticationProviderId));
+ }
+
+ if (string.IsNullOrEmpty(passwordResetProviderId))
+ {
+ throw new ArgumentNullException(nameof(passwordResetProviderId));
+ }
+
+ Username = username;
+ AuthenticationProviderId = authenticationProviderId;
+ PasswordResetProviderId = passwordResetProviderId;
+
+ AccessSchedules = new HashSet<AccessSchedule>();
+ // Groups = new HashSet<Group>();
Permissions = new HashSet<Permission>();
- ProviderMappings = new HashSet<ProviderMapping>();
Preferences = new HashSet<Preference>();
-
+ // ProviderMappings = new HashSet<ProviderMapping>();
+
+ // Set default values
+ Id = Guid.NewGuid();
+ InvalidLoginAttemptCount = 0;
+ EnableUserPreferenceAccess = true;
+ MustUpdatePassword = false;
+ DisplayMissingEpisodes = false;
+ DisplayCollectionsView = false;
+ HidePlayedInLatest = true;
+ RememberAudioSelections = true;
+ RememberSubtitleSelections = true;
+ EnableNextEpisodeAutoPlay = true;
+ EnableAutoLogin = false;
+ PlayDefaultAudioTrack = true;
+ SubtitleMode = SubtitlePlaybackMode.Default;
+ SyncPlayAccess = SyncPlayAccess.CreateAndJoinGroups;
+
+ AddDefaultPermissions();
+ AddDefaultPreferences();
Init();
}
/// <summary>
- /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
- /// </summary>
- public static User CreateUserUnsafe()
- {
- return new User();
- }
-
- /// <summary>
- /// Public constructor with required data
+ /// Initializes a new instance of the <see cref="User"/> class.
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
- /// <param name="username"></param>
- /// <param name="mustupdatepassword"></param>
- /// <param name="audiolanguagepreference"></param>
- /// <param name="authenticationproviderid"></param>
- /// <param name="invalidloginattemptcount"></param>
- /// <param name="subtitlemode"></param>
- /// <param name="playdefaultaudiotrack"></param>
- public User(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
+ protected User()
{
- if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
- this.Username = username;
-
- this.MustUpdatePassword = mustupdatepassword;
-
- if (string.IsNullOrEmpty(audiolanguagepreference)) throw new ArgumentNullException(nameof(audiolanguagepreference));
- this.AudioLanguagePreference = audiolanguagepreference;
-
- if (string.IsNullOrEmpty(authenticationproviderid)) throw new ArgumentNullException(nameof(authenticationproviderid));
- this.AuthenticationProviderId = authenticationproviderid;
-
- this.InvalidLoginAttemptCount = invalidloginattemptcount;
-
- if (string.IsNullOrEmpty(subtitlemode)) throw new ArgumentNullException(nameof(subtitlemode));
- this.SubtitleMode = subtitlemode;
-
- this.PlayDefaultAudioTrack = playdefaultaudiotrack;
-
- this.Groups = new HashSet<Group>();
- this.Permissions = new HashSet<Permission>();
- this.ProviderMappings = new HashSet<ProviderMapping>();
- this.Preferences = new HashSet<Preference>();
-
Init();
}
- /// <summary>
- /// Static create function (for use in LINQ queries, etc.)
- /// </summary>
- /// <param name="username"></param>
- /// <param name="mustupdatepassword"></param>
- /// <param name="audiolanguagepreference"></param>
- /// <param name="authenticationproviderid"></param>
- /// <param name="invalidloginattemptcount"></param>
- /// <param name="subtitlemode"></param>
- /// <param name="playdefaultaudiotrack"></param>
- public static User Create(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
- {
- return new User(username, mustupdatepassword, audiolanguagepreference, authenticationproviderid, invalidloginattemptcount, subtitlemode, playdefaultaudiotrack);
- }
-
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
- /// Identity, Indexed, Required
+ /// Gets or sets the Id of the user.
/// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
[Key]
[Required]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int Id { get; protected set; }
+ [JsonIgnore]
+ public Guid Id { get; set; }
/// <summary>
- /// Required, Max length = 255
+ /// Gets or sets the user's name.
/// </summary>
+ /// <remarks>
+ /// Required, Max length = 255.
+ /// </remarks>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Username { get; set; }
/// <summary>
- /// Max length = 65535
+ /// Gets or sets the user's password, or <c>null</c> if none is set.
/// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
[MaxLength(65535)]
[StringLength(65535)]
public string Password { get; set; }
/// <summary>
- /// Required
+ /// Gets or sets the user's easy password, or <c>null</c> if none is set.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string EasyPassword { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the user must update their password.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
public bool MustUpdatePassword { get; set; }
/// <summary>
- /// Required, Max length = 255
+ /// Gets or sets the audio language preference.
/// </summary>
- [Required]
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string AudioLanguagePreference { get; set; }
/// <summary>
- /// Required, Max length = 255
+ /// Gets or sets the authentication provider id.
/// </summary>
+ /// <remarks>
+ /// Required, Max length = 255.
+ /// </remarks>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string AuthenticationProviderId { get; set; }
/// <summary>
- /// Max length = 65535
+ /// Gets or sets the password reset provider id.
/// </summary>
- [MaxLength(65535)]
- [StringLength(65535)]
- public string GroupedFolders { get; set; }
+ /// <remarks>
+ /// Required, Max length = 255.
+ /// </remarks>
+ [Required]
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string PasswordResetProviderId { get; set; }
/// <summary>
- /// Required
+ /// Gets or sets the invalid login attempt count.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
public int InvalidLoginAttemptCount { get; set; }
/// <summary>
- /// Max length = 65535
+ /// Gets or sets the last activity date.
/// </summary>
- [MaxLength(65535)]
- [StringLength(65535)]
- public string LatestItemExcludes { get; set; }
-
- public int? LoginAttemptsBeforeLockout { get; set; }
+ public DateTime? LastActivityDate { get; set; }
/// <summary>
- /// Max length = 65535
+ /// Gets or sets the last login date.
/// </summary>
- [MaxLength(65535)]
- [StringLength(65535)]
- public string MyMediaExcludes { get; set; }
+ public DateTime? LastLoginDate { get; set; }
/// <summary>
- /// Max length = 65535
+ /// Gets or sets the number of login attempts the user can make before they are locked out.
/// </summary>
- [MaxLength(65535)]
- [StringLength(65535)]
- public string OrderedViews { get; set; }
+ public int? LoginAttemptsBeforeLockout { get; set; }
/// <summary>
- /// Required, Max length = 255
+ /// Gets or sets the subtitle mode.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
- [MaxLength(255)]
- [StringLength(255)]
- public string SubtitleMode { get; set; }
+ public SubtitlePlaybackMode SubtitleMode { get; set; }
/// <summary>
- /// Required
+ /// Gets or sets a value indicating whether the default audio track should be played.
/// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
[Required]
public bool PlayDefaultAudioTrack { get; set; }
/// <summary>
- /// Max length = 255
+ /// Gets or sets the subtitle language preference.
/// </summary>
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
[MaxLength(255)]
[StringLength(255)]
- public string SubtitleLanguagePrefernce { get; set; }
+ public string SubtitleLanguagePreference { get; set; }
- public bool? DisplayMissingEpisodes { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether missing episodes should be displayed.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool DisplayMissingEpisodes { get; set; }
- public bool? DisplayCollectionsView { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether to display the collections view.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool DisplayCollectionsView { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the user has a local password.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool EnableLocalPassword { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the server should hide played content in "Latest".
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool HidePlayedInLatest { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to remember audio selections on played content.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool RememberAudioSelections { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to remember subtitle selections on played content.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool RememberSubtitleSelections { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable auto-play for the next episode.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool EnableNextEpisodeAutoPlay { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the user should auto-login.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool EnableAutoLogin { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the user can change their preferences.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public bool EnableUserPreferenceAccess { get; set; }
- public bool? HidePlayedInLatest { get; set; }
+ /// <summary>
+ /// Gets or sets the maximum parental age rating.
+ /// </summary>
+ public int? MaxParentalAgeRating { get; set; }
- public bool? RememberAudioSelections { get; set; }
+ /// <summary>
+ /// Gets or sets the remote client bitrate limit.
+ /// </summary>
+ public int? RemoteClientBitrateLimit { get; set; }
- public bool? RememberSubtitleSelections { get; set; }
+ /// <summary>
+ /// Gets or sets the internal id.
+ /// This is a temporary stopgap for until the library db is migrated.
+ /// This corresponds to the value of the index of this user in the library db.
+ /// </summary>
+ [Required]
+ public long InternalId { get; set; }
- public bool? EnableNextEpisodeAutoPlay { get; set; }
+ /// <summary>
+ /// Gets or sets the user's profile image. Can be <c>null</c>.
+ /// </summary>
+ // [ForeignKey("UserId")]
+ public virtual ImageInfo ProfileImage { get; set; }
- public bool? EnableUserPreferenceAccess { get; set; }
+ [Required]
+ public SyncPlayAccess SyncPlayAccess { get; set; }
/// <summary>
- /// Required, ConcurrenyToken
+ /// Gets or sets the row version.
/// </summary>
+ /// <remarks>
+ /// Required, Concurrency Token.
+ /// </remarks>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
/*************************************************************************
* Navigation properties
*************************************************************************/
- [ForeignKey("Group_Groups_Id")]
+
+ /// <summary>
+ /// Gets or sets the list of access schedules this user has.
+ /// </summary>
+ public virtual ICollection<AccessSchedule> AccessSchedules { get; protected set; }
+
+ /*
+ /// <summary>
+ /// Gets or sets the list of groups this user is a member of.
+ /// </summary>
+ [ForeignKey("Group_Groups_Guid")]
public virtual ICollection<Group> Groups { get; protected set; }
+ */
- [ForeignKey("Permission_Permissions_Id")]
+ /// <summary>
+ /// Gets or sets the list of permissions this user has.
+ /// </summary>
+ [ForeignKey("Permission_Permissions_Guid")]
public virtual ICollection<Permission> Permissions { get; protected set; }
+ /*
+ /// <summary>
+ /// Gets or sets the list of provider mappings this user has.
+ /// </summary>
[ForeignKey("ProviderMapping_ProviderMappings_Id")]
public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; }
+ */
- [ForeignKey("Preference_Preferences_Id")]
+ /// <summary>
+ /// Gets or sets the list of preferences this user has.
+ /// </summary>
+ [ForeignKey("Preference_Preferences_Guid")]
public virtual ICollection<Preference> Preferences { get; protected set; }
+ /// <summary>
+ /// Static create function (for use in LINQ queries, etc.)
+ /// </summary>
+ /// <param name="username">The username for the created user.</param>
+ /// <param name="authenticationProviderId">The Id of the user's authentication provider.</param>
+ /// <param name="passwordResetProviderId">The Id of the user's password reset provider.</param>
+ /// <returns>The created instance.</returns>
+ public static User Create(string username, string authenticationProviderId, string passwordResetProviderId)
+ {
+ return new User(username, authenticationProviderId, passwordResetProviderId);
+ }
+
+ /// <inheritdoc/>
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+
+ /// <summary>
+ /// Checks whether the user has the specified permission.
+ /// </summary>
+ /// <param name="kind">The permission kind.</param>
+ /// <returns><c>True</c> if the user has the specified permission.</returns>
+ public bool HasPermission(PermissionKind kind)
+ {
+ return Permissions.First(p => p.Kind == kind).Value;
+ }
+
+ /// <summary>
+ /// Sets the given permission kind to the provided value.
+ /// </summary>
+ /// <param name="kind">The permission kind.</param>
+ /// <param name="value">The value to set.</param>
+ public void SetPermission(PermissionKind kind, bool value)
+ {
+ Permissions.First(p => p.Kind == kind).Value = value;
+ }
+
+ /// <summary>
+ /// Gets the user's preferences for the given preference kind.
+ /// </summary>
+ /// <param name="preference">The preference kind.</param>
+ /// <returns>A string array containing the user's preferences.</returns>
+ public string[] GetPreference(PreferenceKind preference)
+ {
+ var val = Preferences.First(p => p.Kind == preference).Value;
+
+ return Equals(val, string.Empty) ? Array.Empty<string>() : val.Split(Delimiter);
+ }
+
+ /// <summary>
+ /// Sets the specified preference to the given value.
+ /// </summary>
+ /// <param name="preference">The preference kind.</param>
+ /// <param name="values">The values.</param>
+ public void SetPreference(PreferenceKind preference, string[] values)
+ {
+ Preferences.First(p => p.Kind == preference).Value
+ = string.Join(Delimiter.ToString(CultureInfo.InvariantCulture), values);
+ }
+
+ /// <summary>
+ /// Checks whether this user is currently allowed to use the server.
+ /// </summary>
+ /// <returns><c>True</c> if the current time is within an access schedule, or there are no access schedules.</returns>
+ public bool IsParentalScheduleAllowed()
+ {
+ return AccessSchedules.Count == 0
+ || AccessSchedules.Any(i => IsParentalScheduleAllowed(i, DateTime.UtcNow));
+ }
+
+ /// <summary>
+ /// Checks whether the provided folder is in this user's grouped folders.
+ /// </summary>
+ /// <param name="id">The Guid of the folder.</param>
+ /// <returns><c>True</c> if the folder is in the user's grouped folders.</returns>
+ public bool IsFolderGrouped(Guid id)
+ {
+ return GetPreference(PreferenceKind.GroupedFolders).Any(i => new Guid(i) == id);
+ }
+
+ private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
+ {
+ var localTime = date.ToLocalTime();
+ var hour = localTime.TimeOfDay.TotalHours;
+
+ return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek)
+ && hour >= schedule.StartHour
+ && hour <= schedule.EndHour;
+ }
+
+ // TODO: make these user configurable?
+ private void AddDefaultPermissions()
+ {
+ Permissions.Add(new Permission(PermissionKind.IsAdministrator, false));
+ Permissions.Add(new Permission(PermissionKind.IsDisabled, false));
+ Permissions.Add(new Permission(PermissionKind.IsHidden, true));
+ Permissions.Add(new Permission(PermissionKind.EnableAllChannels, true));
+ Permissions.Add(new Permission(PermissionKind.EnableAllDevices, true));
+ Permissions.Add(new Permission(PermissionKind.EnableAllFolders, true));
+ Permissions.Add(new Permission(PermissionKind.EnableContentDeletion, false));
+ Permissions.Add(new Permission(PermissionKind.EnableContentDownloading, true));
+ Permissions.Add(new Permission(PermissionKind.EnableMediaConversion, true));
+ Permissions.Add(new Permission(PermissionKind.EnableMediaPlayback, true));
+ Permissions.Add(new Permission(PermissionKind.EnablePlaybackRemuxing, true));
+ Permissions.Add(new Permission(PermissionKind.EnablePublicSharing, true));
+ Permissions.Add(new Permission(PermissionKind.EnableRemoteAccess, true));
+ Permissions.Add(new Permission(PermissionKind.EnableSyncTranscoding, true));
+ Permissions.Add(new Permission(PermissionKind.EnableAudioPlaybackTranscoding, true));
+ Permissions.Add(new Permission(PermissionKind.EnableLiveTvAccess, true));
+ Permissions.Add(new Permission(PermissionKind.EnableLiveTvManagement, true));
+ Permissions.Add(new Permission(PermissionKind.EnableSharedDeviceControl, true));
+ Permissions.Add(new Permission(PermissionKind.EnableVideoPlaybackTranscoding, true));
+ Permissions.Add(new Permission(PermissionKind.ForceRemoteSourceTranscoding, false));
+ Permissions.Add(new Permission(PermissionKind.EnableRemoteControlOfOtherUsers, false));
+ }
+
+ private void AddDefaultPreferences()
+ {
+ foreach (var val in Enum.GetValues(typeof(PreferenceKind)).Cast<PreferenceKind>())
+ {
+ Preferences.Add(new Preference(val, string.Empty));
+ }
+ }
+
+ partial void Init();
}
}
-