feat: persist user content restriction

This commit is contained in:
Gauthier Roebroeck 2022-03-02 10:44:12 +08:00
parent c7c5592c50
commit f1ab136b5e
4 changed files with 127 additions and 11 deletions

View file

@ -0,0 +1,13 @@
CREATE TABLE USER_SHARING
(
LABEL varchar NOT NULL,
ALLOW boolean NOT NULL,
USER_ID varchar NOT NULL,
PRIMARY KEY (LABEL, ALLOW, USER_ID),
FOREIGN KEY (USER_ID) REFERENCES USER (ID)
);
ALTER TABLE USER
add column AGE_RESTRICTION integer NULL;
ALTER TABLE USER
add column AGE_RESTRICTION_ALLOW_ONLY boolean NULL;

View file

@ -17,7 +17,7 @@ sealed class ContentRestriction {
class ExcludeOver(age: Int) : AgeRestriction(age)
}
sealed class LabelsRestriction(val labels: Collection<String>) : ContentRestriction() {
sealed class LabelsRestriction(val labels: Set<String>) : ContentRestriction() {
/**
* Allow only content that has at least one of the provided sharing [labels]
*

View file

@ -1,5 +1,7 @@
package org.gotson.komga.infrastructure.jooq
import org.gotson.komga.domain.model.ContentRestriction
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.persistence.KomgaUserRepository
import org.gotson.komga.jooq.Tables
@ -18,6 +20,7 @@ class KomgaUserDao(
private val u = Tables.USER
private val ul = Tables.USER_LIBRARY_SHARING
private val us = Tables.USER_SHARING
override fun count(): Long = dsl.fetchCount(u).toLong()
@ -41,6 +44,9 @@ class KomgaUserDao(
private fun ResultQuery<Record>.fetchAndMap() =
this.fetchGroups({ it.into(u) }, { it.into(ul) })
.map { (ur, ulr) ->
val usr = dsl.selectFrom(us)
.where(us.USER_ID.eq(ur.id))
.toList()
KomgaUser(
email = ur.email,
password = ur.password,
@ -49,6 +55,14 @@ class KomgaUserDao(
rolePageStreaming = ur.rolePageStreaming,
sharedLibrariesIds = ulr.mapNotNull { it.libraryId }.toSet(),
sharedAllLibraries = ur.sharedAllLibraries,
restrictions = ContentRestrictions(
ageRestriction = if (ur.ageRestriction != null && ur.ageRestrictionAllowOnly != null)
if (ur.ageRestrictionAllowOnly) ContentRestriction.AgeRestriction.AllowOnlyUnder(ur.ageRestriction)
else ContentRestriction.AgeRestriction.ExcludeOver(ur.ageRestriction)
else null,
labelsAllow = usr.filter { it.allow }.map { it.label }.toSet(),
labelsExclude = usr.filterNot { it.allow }.map { it.label }.toSet(),
),
id = ur.id,
createdDate = ur.createdDate.toCurrentTimeZone(),
lastModifiedDate = ur.lastModifiedDate.toCurrentTimeZone(),
@ -65,14 +79,19 @@ class KomgaUserDao(
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
.set(u.AGE_RESTRICTION, user.restrictions.ageRestriction?.age)
.set(
u.AGE_RESTRICTION_ALLOW_ONLY,
when (user.restrictions.ageRestriction) {
is ContentRestriction.AgeRestriction.AllowOnlyUnder -> true
is ContentRestriction.AgeRestriction.ExcludeOver -> false
null -> null
},
)
.execute()
user.sharedLibrariesIds.forEach {
dsl.insertInto(ul)
.columns(ul.USER_ID, ul.LIBRARY_ID)
.values(user.id, it)
.execute()
}
insertSharedLibraries(user)
insertSharingRestrictions(user)
}
@Transactional
@ -84,6 +103,15 @@ class KomgaUserDao(
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
.set(u.AGE_RESTRICTION, user.restrictions.ageRestriction?.age)
.set(
u.AGE_RESTRICTION_ALLOW_ONLY,
when (user.restrictions.ageRestriction) {
is ContentRestriction.AgeRestriction.AllowOnlyUnder -> true
is ContentRestriction.AgeRestriction.ExcludeOver -> false
null -> null
},
)
.set(u.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
.where(u.ID.eq(user.id))
.execute()
@ -92,6 +120,15 @@ class KomgaUserDao(
.where(ul.USER_ID.eq(user.id))
.execute()
dsl.deleteFrom(us)
.where(us.USER_ID.eq(user.id))
.execute()
insertSharedLibraries(user)
insertSharingRestrictions(user)
}
private fun insertSharedLibraries(user: KomgaUser) {
user.sharedLibrariesIds.forEach {
dsl.insertInto(ul)
.columns(ul.USER_ID, ul.LIBRARY_ID)
@ -100,14 +137,32 @@ class KomgaUserDao(
}
}
private fun insertSharingRestrictions(user: KomgaUser) {
user.restrictions.labelsAllowRestriction?.labels?.forEach { label ->
dsl.insertInto(us)
.columns(us.USER_ID, us.ALLOW, us.LABEL)
.values(user.id, true, label)
.execute()
}
user.restrictions.labelsExcludeRestriction?.labels?.forEach { label ->
dsl.insertInto(us)
.columns(us.USER_ID, us.ALLOW, us.LABEL)
.values(user.id, false, label)
.execute()
}
}
@Transactional
override fun delete(userId: String) {
dsl.deleteFrom(us).where(us.USER_ID.equal(userId)).execute()
dsl.deleteFrom(ul).where(ul.USER_ID.equal(userId)).execute()
dsl.deleteFrom(u).where(u.ID.equal(userId)).execute()
}
@Transactional
override fun deleteAll() {
dsl.deleteFrom(us).execute()
dsl.deleteFrom(ul).execute()
dsl.deleteFrom(u).execute()
}

View file

@ -1,6 +1,8 @@
package org.gotson.komga.infrastructure.jooq
import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.domain.model.ContentRestriction
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.persistence.LibraryRepository
@ -59,9 +61,12 @@ class KomgaUserDaoTest(
assertThat(lastModifiedDate).isCloseTo(now, offset)
assertThat(email).isEqualTo("user@example.org")
assertThat(password).isEqualTo("password")
assertThat(roleAdmin).isFalse()
assertThat(roleAdmin).isFalse
assertThat(sharedLibrariesIds).containsExactly(library.id)
assertThat(sharedAllLibraries).isFalse()
assertThat(sharedAllLibraries).isFalse
assertThat(restrictions.ageRestriction).isNull()
assertThat(restrictions.labelsAllowRestriction).isNull()
assertThat(restrictions.labelsExcludeRestriction).isNull()
}
}
@ -73,10 +78,29 @@ class KomgaUserDaoTest(
roleAdmin = false,
sharedLibrariesIds = setOf(library.id),
sharedAllLibraries = false,
restrictions = ContentRestrictions(
ageRestriction = ContentRestriction.AgeRestriction.AllowOnlyUnder(10),
labelsAllow = setOf("allow"),
labelsExclude = setOf("exclude"),
)
)
komgaUserDao.insert(user)
val created = komgaUserDao.findByIdOrNull(user.id)!!
with(created) {
assertThat(restrictions.ageRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.AgeRestriction.AllowOnlyUnder::class.java)
assertThat(restrictions.ageRestriction!!.age).isEqualTo(10)
assertThat(restrictions.labelsAllowRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.LabelsRestriction.AllowOnly::class.java)
assertThat(restrictions.labelsAllowRestriction!!.labels).containsExactly("allow")
assertThat(restrictions.labelsExcludeRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.LabelsRestriction.Exclude::class.java)
assertThat(restrictions.labelsExcludeRestriction!!.labels).containsExactly("exclude")
}
val modified = created.copy(
email = "user2@example.org",
@ -84,6 +108,11 @@ class KomgaUserDaoTest(
roleAdmin = true,
sharedLibrariesIds = emptySet(),
sharedAllLibraries = true,
restrictions = ContentRestrictions(
ageRestriction = ContentRestriction.AgeRestriction.ExcludeOver(16),
labelsAllow = setOf("allow2"),
labelsExclude = setOf("exclude2"),
),
)
val modifiedDate = LocalDateTime.now()
komgaUserDao.update(modified)
@ -97,9 +126,28 @@ class KomgaUserDaoTest(
.isNotEqualTo(modified.createdDate)
assertThat(email).isEqualTo("user2@example.org")
assertThat(password).isEqualTo("password2")
assertThat(roleAdmin).isTrue()
assertThat(roleAdmin).isTrue
assertThat(sharedLibrariesIds).isEmpty()
assertThat(sharedAllLibraries).isTrue()
assertThat(sharedAllLibraries).isTrue
assertThat(restrictions.ageRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.AgeRestriction.ExcludeOver::class.java)
assertThat(restrictions.ageRestriction!!.age).isEqualTo(16)
assertThat(restrictions.labelsAllowRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.LabelsRestriction.AllowOnly::class.java)
assertThat(restrictions.labelsAllowRestriction!!.labels).containsExactly("allow2")
assertThat(restrictions.labelsExcludeRestriction)
.isNotNull
.isExactlyInstanceOf(ContentRestriction.LabelsRestriction.Exclude::class.java)
assertThat(restrictions.labelsExcludeRestriction!!.labels).containsExactly("exclude2")
}
komgaUserDao.update(modifiedSaved.copy(restrictions = ContentRestrictions()))
with(komgaUserDao.findByIdOrNull(modified.id)!!) {
assertThat(restrictions.ageRestriction).isNull()
assertThat(restrictions.labelsAllowRestriction).isNull()
assertThat(restrictions.labelsExcludeRestriction).isNull()
}
}