Skip to content

Commit 797271e

Browse files
committed
Merge v0.2024.009 into 'release'.
2 parents 327b774 + 4ea497f commit 797271e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3150
-584
lines changed

appsv/model/src/main/scala/com/debiki/core/user.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,9 +1077,14 @@ case class Anonym(
10771077
// Currently only approved users may use anonyms, so, for now:
10781078
override def isAuthenticated: Bo = true
10791079

1080-
// Or use the real user's levels? But then it can be simpler to know how hen is?
1080+
// Don't use the real user's levels — that'd make it simpler to guess how the
1081+
// true user is. For now, let's use NewMember.
1082+
// Later: Set the trust level to the min level required, to post in the
1083+
// anonymous category? Then, can e.g. avoid moderators having to approve all
1084+
// anonymous comments (since they'd be by "new" members, anonyms being per page,
1085+
// not having posted elsewhere before), without leaking any info about the true
1086+
// user's trust level. [anon_tr_lv]
10811087
def effectiveTrustLevel: TrustLevel = TrustLevel.NewMember
1082-
//def effectiveThreatLevel: ThreatLevel = ThreatLevel.SeemsSafe
10831088

10841089
// But the accounts haven't been approved?
10851090
override def isApprovedOrStaff: Bo = false

appsv/server/controllers/VoteController.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class VoteController @Inject()(cc: ControllerComponents, edContext: TyContext)
123123
"TyE7M3MRSED5", "The post just got hard deleted?")
124124

125125
val storePatchJson = dao.jsonMaker.makeStorePatchForPost(
126-
updatedPost, showHidden = true, reqerId = request.theReqerId)
126+
updatedPost, showHidden = true)
127127

128128
var responseJson: JsObject =
129129
storePatchJson ++

appsv/server/debiki/ReactJson.scala

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,16 @@ class JsonMaker(dao: SiteDao) {
556556

557557
val reactStoreJsonString = jsonObj.toString()
558558

559+
// Make sure we [dont_leak_true_ids]. This page json is for everyone, not a specific
560+
// person, and then no aliases' true ids should be included. (However,
561+
// in userDataJson() and requestersJsonImpl() (below) it can be ok with true ids.)
562+
val trueIds = (jsonObj \\ JsX.AnonForIdFieldName)
563+
if (trueIds.nonEmpty) {
564+
// Only include in the server logs, don't show to the end user.
565+
System.err.println(s"True ids in page json: $reactStoreJsonString [TyEIDLEAKPAGE1]")
566+
die(s"Bug: True ids in page json, see server logs. [TyEIDLEAKPAGE2]")
567+
}
568+
559569
val version = CachedPageVersion(
560570
siteVersion = transaction.loadSiteVersion(),
561571
pageVersion = page.version,
@@ -1447,20 +1457,19 @@ class JsonMaker(dao: SiteDao) {
14471457

14481458

14491459
def makeStorePatchForPostIds(postIds: Set[PostId], showHidden: Bo,
1450-
inclUnapproved: Bo, maySquash: Bo, dao: SiteDao, reqerId: Opt[PatId] = None,
1451-
): JsObject = {
1460+
inclUnapproved: Bo, maySquash: Bo, dao: SiteDao): JsObject = {
14521461
dieIf(Globals.isDevOrTest && dao != this.dao, "TyE602MWJL43") ; CLEAN_UP // remove dao param?
14531462
dao.readTx { tx =>
14541463
// This might render CommonMark, in a tx — slightly bad. [nashorn_in_tx]
1455-
makeStorePatchForPostIds(postIds, showHidden = showHidden,
1456-
inclUnapproved = inclUnapproved, maySquash = maySquash, tx, reqerId = reqerId)
1464+
_makeStorePatchForPostIds(postIds, showHidden = showHidden,
1465+
inclUnapproved = inclUnapproved, maySquash = maySquash, tx)
14571466
}
14581467
}
14591468

14601469
// [post_to_json]
1461-
private def makeStorePatchForPostIds(postIds: Set[PostId],
1470+
private def _makeStorePatchForPostIds(postIds: Set[PostId],
14621471
showHidden: Bo, inclUnapproved: Bo, maySquash: Bo,
1463-
transaction: SiteTx, reqerId: Opt[PatId]): JsObject = {
1472+
transaction: SiteTx): JsObject = {
14641473
val posts = transaction.loadPostsByUniqueId(postIds).values
14651474
val tagsAndBadges = transaction.loadPostTagsAndAuthorBadges(postIds)
14661475
val tagTypes = dao.getTagTypes(tagsAndBadges.tagTypeIds)
@@ -1472,14 +1481,14 @@ class JsonMaker(dao: SiteDao) {
14721481
makeStorePatch3(pageIdVersions, posts,
14731482
showHidden = showHidden, inclUnapproved = inclUnapproved,
14741483
maySquash = maySquash, tagsAndBadges, tagTypes,
1475-
pats, reqerId = reqerId, appVersion = dao.globals.applicationVersion)(transaction)
1484+
pats, appVersion = dao.globals.applicationVersion)(transaction)
14761485
}
14771486

14781487

1479-
def makeStorePatchForPost(post: Post, showHidden: Bo, reqerId: PatId): JsObject = {
1488+
def makeStorePatchForPost(post: Post, showHidden: Bo): JsObject = {
14801489
makeStorePatchForPostIds(
14811490
postIds = Set(post.id), showHidden = showHidden, inclUnapproved = true,
1482-
maySquash = false, dao, reqerId = Some(reqerId))
1491+
maySquash = false, dao)
14831492
}
14841493

14851494

@@ -1494,7 +1503,7 @@ class JsonMaker(dao: SiteDao) {
14941503
private def makeStorePatch3(pageIdVersions: Iterable[PageIdVersion], posts: Iterable[Post],
14951504
showHidden: Bo, inclUnapproved: Bo, maySquash: Bo,
14961505
tagsAndBadges: TagsAndBadges, tagTypes: Seq[TagType],
1497-
pats: Iterable[Pat], reqerId: Opt[PatId] = None, appVersion: St)(
1506+
pats: Iterable[Pat], appVersion: St)(
14981507
tx: SiteTx): JsObject = {
14991508
require(posts.isEmpty || pats.nonEmpty, "Posts but no authors [EsE4YK7W2]")
15001509

@@ -1521,7 +1530,7 @@ class JsonMaker(dao: SiteDao) {
15211530
Json.obj(
15221531
"appVersion" -> appVersion,
15231532
"pageVersionsByPageId" -> pageVersionsByPageIdJson,
1524-
"usersBrief" -> pats.map(JsPat(_, tagsAndBadges, toShowForPatId = reqerId)),
1533+
"usersBrief" -> pats.map(JsPat(_, tagsAndBadges)),
15251534
"tagTypes" -> tagTypes.map(JsTagType),
15261535
"postsByPageId" -> postsByPageIdJson)
15271536
}

appsv/server/debiki/dao/PagesDao.scala

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -314,23 +314,31 @@ trait PagesDao {
314314
require(pinOrder.isDefined == pinWhere.isDefined, "Ese5MJK2")
315315
require(embeddingUrl.trimNoneIfBlank == embeddingUrl, "Cannot have blank emb urls [TyE75SPJBJ]")
316316

317+
SECURITY // Maybe page id shouldn't be public? [rand-page-id] To prevent people from
318+
// discovering all pages. E.g. iterating through all discussions, in a public blog.
319+
val pageId = tx.nextPageId()
320+
321+
val personaAndLevels: UserAndLevels = SiteDao.getPersonaAndLevels(
322+
realAuthorAndLevels, pageId = pageId, asAlias, mayReuseAnon = false,
323+
isCreatingPage = true)(tx, IfBadAbortReq)
324+
325+
val authorMaybeAnon: Pat = personaAndLevels.user
326+
317327
val pageSlug = anySlug.getOrElse({
318328
context.nashorn.slugifyTitle(title.source)
319329
}).take(PagePath.MaxSlugLength).dropRightWhile(_ == '-').dropWhile(_ == '-')
320330

321331
COULD // try to move this authz + review-reason check to talkyard.server.authz.Authz?
322332
val (
323333
reviewReasons: Seq[ReviewReason],
324-
shallApprove: Boolean) =
325-
throwOrFindReviewNewPageReasons(realAuthorAndLevels, pageRole, tx) // [mod_deanon_risk]
334+
shallApprove: Bo) =
335+
throwOrFindReviewNewPageReasons(personaAndLevels, pageRole, tx) // [mod_deanon_risk]
326336

337+
// Similar to: [find_approver_id]. [mod_deanon_risk]
327338
val approvedById =
328-
if (realAuthor.isStaff) { // [mod_deanon_risk]
329-
dieIf(!shallApprove, "EsE2UPU70")
330-
Some(realAuthor.id)
331-
}
332-
else if (shallApprove) Some(SystemUserId)
333-
else None
339+
if (!shallApprove) None
340+
else if (realAuthor.isStaff && asAlias.isEmpty) Some(realAuthor.id)
341+
else Some(SystemUserId)
334342

335343
if (pageRole.isSection) {
336344
// A forum page is created before its root category — verify that the root category
@@ -360,20 +368,13 @@ trait PagesDao {
360368
}
361369

362370
val folder = anyFolder getOrElse "/"
363-
SECURITY // Maybe page id shouldn't be public? [rand-page-id] To prevent people from
364-
// discovering all pages. E.g. iterating through all discussions, in a public blog.
365-
val pageId = tx.nextPageId()
366371
val siteId = tx.siteId // [5GKEPMW2] remove this row later
367372
val pagePath = PagePathWithId(folder = folder, pageId = pageId,
368373
showId = showId, pageSlug = pageSlug, canonical = true)
369374

370375
val titleUniqueId = tx.nextPostId()
371376
val bodyUniqueId = titleUniqueId + 1
372377

373-
val authorMaybeAnon: Pat = SiteDao.getAliasOrTruePat(
374-
truePat = realAuthor, pageId = pageId, asAlias, mayReuseAnon = false,
375-
isCreatingPage = true)(tx, IfBadAbortReq)
376-
377378
val titlePost = Post.createTitle(
378379
uniqueId = titleUniqueId,
379380
pageId = pageId,

0 commit comments

Comments
 (0)