From f29ba94860ad69f783f6a681a65459ba74173ba9 Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Sun, 9 Jan 2022 01:44:02 +0200 Subject: [PATCH] Enforce ownership --- server/router/library/index.js | 74 +++++++++- server/router/translate/index.js | 114 +++++++++++++-- server/router/versions/index.js | 136 +++++++++++++++++- server/views/account.pug | 3 +- server/views/artifact-version.pug | 51 ++++--- server/views/library.pug | 10 +- server/views/translation-artifact-version.pug | 47 ++++-- 7 files changed, 388 insertions(+), 47 deletions(-) diff --git a/server/router/library/index.js b/server/router/library/index.js index 361f8d5..85bf515 100644 --- a/server/router/library/index.js +++ b/server/router/library/index.js @@ -1,5 +1,5 @@ const express = require('express'); -const req = require('express/lib/request'); +const { Op } = require('sequelize') module.exports = function (options) { const db = options.db; @@ -7,13 +7,77 @@ module.exports = function (options) { router.route('/') .get(function(request, response, next) { - db.Artifact.findAll({ - - }).then(artifacts => { + Promise.all([ + db.Artifact.findAll({ + include: [ + { + association: db.Artifact.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] + } + ] + }), + db.TranslationArtifactVersion.findAll({ + where: { + forkedFromId: { + [Op.ne]: null, + } + }, + include: [ + { + association: db.TranslationArtifactVersion.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] + } + ] + }) + ]) + .then(results => { response.display("library", { user: request.user, pageTitle: "Library - Mantra", - artifacts: artifacts + artifacts: results[0], + translationArtifactVersions: results[1], }) }).catch(error => { next(error) diff --git a/server/router/translate/index.js b/server/router/translate/index.js index ce1eadd..9cfbf97 100644 --- a/server/router/translate/index.js +++ b/server/router/translate/index.js @@ -29,6 +29,7 @@ module.exports = function (options) { ] }).then(translationArtifactVersion => { if (translationArtifactVersion) { + // Show translation without artifactVersion response.redirect(`/translate/${translationArtifactVersion.id}/chapter/${translationArtifactVersion.translationChapters[0].id}`) } else { next() @@ -295,6 +296,31 @@ module.exports = function (options) { { association: db.TranslationArtifactVersion.BackTranslation, }, + { + association: db.TranslationArtifactVersion.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] + } ] }).then((translationArtifactVersion) => { if (translationArtifactVersion) { @@ -370,25 +396,50 @@ module.exports = function (options) { include: [ { association: db.TranslationArtifactVersion.TranslationArtifactVersionCampaigns, - required: true, include: [ { association: db.TranslationArtifactVersionCampaign.Campaign, - required: true + } + ] + }, + { + association: db.TranslationArtifactVersion.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] } ] } ] }).then(translationArtifactVersion => { if (translationArtifactVersion) { - if (translationArtifactVersion.translationArtifactVersionCampaigns.length == 1) { + if (translationArtifactVersion.translationArtifactVersionCampaigns.length == 0) { + response.redirect(`/translate/${request.params.id}/campaigns/create`) + } else if (translationArtifactVersion.translationArtifactVersionCampaigns.length == 1) { response.redirect(`/campaigns/${translationArtifactVersion.translationArtifactVersionCampaigns[0].campaignId}`) } else { // TODO: Display translation artifact campaign... next() } } else { - response.redirect(`/translate/${request.params.id}/campaigns/create`) + next() } }) }) @@ -407,17 +458,41 @@ module.exports = function (options) { }, { association: db.TranslationArtifactVersion.TranslationArtifactVersionCampaigns, - required: false, include: [ { association: db.TranslationArtifactVersionCampaign.Campaign, - required: false + } + ] + }, + { + association: db.TranslationArtifactVersion.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] } ] } ] }).then(translationArtifactVersion => { if (translationArtifactVersion) { + // TODO: Check if campaign exits... response.display("campaign-form", { user: request.user, pageTitle: "Campaign - Mantra", @@ -446,11 +521,34 @@ module.exports = function (options) { }, { association: db.TranslationArtifactVersion.TranslationArtifactVersionCampaigns, - required: false, include: [ { association: db.TranslationArtifactVersionCampaign.Campaign, - required: false + } + ] + }, + { + association: db.TranslationArtifactVersion.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] } ] } diff --git a/server/router/versions/index.js b/server/router/versions/index.js index 07cac91..5db7633 100644 --- a/server/router/versions/index.js +++ b/server/router/versions/index.js @@ -11,9 +11,35 @@ module.exports = function (options) { include: [ { association: db.ArtifactVersion.Artifact, + // required: true, include: [ { association: db.Artifact.ArtifactApproval + }, + { + association: db.Artifact.Owner, + // required: false, + include: [ + { + association: db.Owner.OwnerEntities, + // required: true, + include: [ + { + association: db.OwnerEntity.Entity, + // required: false, + include: [ + { + association: db.Entity.EntityUsers, + required: false, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] } ] }, @@ -50,9 +76,35 @@ module.exports = function (options) { include: [ { association: db.ArtifactVersion.Artifact, + required: true, include: [ { - association: db.Artifact.ArtifactApproval + association: db.Artifact.ArtifactApproval, + }, + { + association: db.Artifact.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] } ] }, @@ -80,9 +132,35 @@ module.exports = function (options) { include: [ { association: db.ArtifactVersion.Artifact, + required: true, include: [ { - association: db.Artifact.ArtifactApproval + association: db.Artifact.ArtifactApproval, + }, + { + association: db.Artifact.Owner, + required: true, + include: [ + { + association: db.Owner.OwnerEntities, + required: true, + include: [ + { + association: db.OwnerEntity.Entity, + required: true, + include: [ + { + association: db.Entity.EntityUsers, + required: true, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] } ] }, @@ -178,7 +256,34 @@ module.exports = function (options) { association: db.TranslationArtifactVersion.ArtifactVersion, include: [ { - association: db.ArtifactVersion.Artifact + association: db.ArtifactVersion.Artifact, + include: [ + { + association: db.Artifact.Owner, + // required: false, + include: [ + { + association: db.Owner.OwnerEntities, + // required: true, + include: [ + { + association: db.OwnerEntity.Entity, + // required: false, + include: [ + { + association: db.Entity.EntityUsers, + required: false, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] + } + ] }, { association: db.ArtifactVersion.Chapters @@ -195,6 +300,31 @@ module.exports = function (options) { association: db.TranslationChapter.Chapter } ] + }, + { + association: db.TranslationArtifactVersion.Owner, + // required: false, + include: [ + { + association: db.Owner.OwnerEntities, + // required: true, + include: [ + { + association: db.OwnerEntity.Entity, + // required: false, + include: [ + { + association: db.Entity.EntityUsers, + required: false, + where: { + userId: request.user.id + } + } + ] + } + ] + } + ] } ] }).then(translationArtifactVersion => { diff --git a/server/views/account.pug b/server/views/account.pug index 72734b1..f39fce4 100644 --- a/server/views/account.pug +++ b/server/views/account.pug @@ -3,4 +3,5 @@ extend templates/layout.pug block content .container .center - h1 Account \ No newline at end of file + h1 Account + p.flow-text= user.individualEntityUser.entityUser.entity.name \ No newline at end of file diff --git a/server/views/artifact-version.pug b/server/views/artifact-version.pug index debbfba..480d748 100644 --- a/server/views/artifact-version.pug +++ b/server/views/artifact-version.pug @@ -1,34 +1,51 @@ extend templates/layout.pug block content + - + const isOwnedByUser = artifactVersion.artifact.owner.ownerEntities.some(ownerEntity => { + return ownerEntity.entity.entityUsers.some(entityUser => { + return entityUser.userId == user?.id + }) + }) .container .center h1 #{artifactVersion.artifact.name} h2 #{artifactVersion.tag} - - .row - .col.s12 - a.btn.black(href=`/fork/e/${artifactVersion.id}`) fork + p.flow-text + each ownerEntity, index in artifactVersion.artifact.owner.ownerEntities + small + if index > 0 + span and + span.chip #{ownerEntity.entity.name} + if !isOwnedByUser + .row + .col.s12 + a.btn.black(href=`/fork/e/${artifactVersion.id}`) fork //- .row .col.s12 a.btn.black(href=`/v/${artifactVersion.id}/campaign/create`) funding campaign - .divider - .row - a.btn.black(href=`/v/${artifactVersion.id}/chapters/add`) add chapter - if artifactVersion.chapters.length == 0 - p.flow-text No chapters added - else - .row - each chapter in artifactVersion.chapters - .col.s12 - a(href=`/v/${artifactVersion.id}/chapters/${chapter.id}`) - .card-panel - p.flow-text= chapter.name + + if isOwnedByUser + .divider + .row + a.btn.black(href=`/v/${artifactVersion.id}/chapters/add`) add chapter + + if artifactVersion.chapters.length == 0 + p.flow-text No chapters added + else + .row + each chapter in artifactVersion.chapters + .col.s12 + a(href=`/v/${artifactVersion.id}/chapters/${chapter.id}`) + .card-panel + p.flow-text= chapter.name .divider .row - a.btn.black(href=`/v/${artifactVersion.id}/translations/add`) add translation + + if isOwnedByUser + a.btn.black(href=`/v/${artifactVersion.id}/translations/add`) add translation if artifactVersion.translationArtifactVersions.length == 0 p.flow-text No translations added diff --git a/server/views/library.pug b/server/views/library.pug index f24377f..8436c9d 100644 --- a/server/views/library.pug +++ b/server/views/library.pug @@ -14,4 +14,12 @@ block content .col.s12 a(href=`/library/${artifact.id}`) .card-panel - p.flow-text= artifact.name \ No newline at end of file + p.flow-text= artifact.name + + .divider + h2 forks + if translationArtifactVersions.length > 0 + each translationArtifactVersion in translationArtifactVersions + p.flow-text + a(href=`/v/${translationArtifactVersion.artifactVersionId}/translations/${translationArtifactVersion.id}`)= translationArtifactVersion.name + else diff --git a/server/views/translation-artifact-version.pug b/server/views/translation-artifact-version.pug index b821d70..92af810 100644 --- a/server/views/translation-artifact-version.pug +++ b/server/views/translation-artifact-version.pug @@ -1,10 +1,31 @@ extend templates/layout.pug block content + - + const isOwnedByUser = translationArtifactVersion.owner.ownerEntities.some(ownerEntity => { + return ownerEntity.entity.entityUsers.some(entityUser => { + return entityUser.userId == user?.id + }) + }) + const ownerForTranslationIsOwnerForArtifact = false + .container .center h1= translationArtifactVersion.name + if !ownerForTranslationIsOwnerForArtifact + p.flow-text + each ownerEntity, index in translationArtifactVersion.owner.ownerEntities + small + if index > 0 + span and + span.chip #{ownerEntity.entity.name} h2= translationArtifactVersion.artifactVersion.artifact.name + p.flow-text + each ownerEntity, index in translationArtifactVersion.artifactVersion.artifact.owner.ownerEntities + small + if index > 0 + span and + span.chip #{ownerEntity.entity.name} if translationArtifactVersion.forkedFrom p.flow-text is a @@ -15,20 +36,22 @@ block content .col.s12 a.btn.black(href=`/translate/${translationArtifactVersion.id}`) Translate //- TODO: Condition to show fork button - .row - .col.s12 - form(action=`/fork/t/${translationArtifactVersion.id}`, method="post") - button.btn.black(type="submit") fork + if !isOwnedByUser + .row + .col.s12 + form(action=`/fork/t/${translationArtifactVersion.id}`, method="post") + button.btn.black(type="submit") fork - .row - .col.s12 - form(action=`/translate/${translationArtifactVersion.id}/back`, method="post") - button.btn.black(type="submit") back translate + if isOwnedByUser + //- TODO: Check required conditions to start back translation... + .row + .col.s12 + form(action=`/translate/${translationArtifactVersion.id}/back`, method="post") + button.btn.black(type="submit") back translate - - .row - .col.s12 - a.btn.black(href=`/translate/${translationArtifactVersion.id}/campaigns`) funding campaign + .row + .col.s12 + a.btn.black(href=`/translate/${translationArtifactVersion.id}/campaigns`) funding campaign .row .col.s12 a.btn.black(href=`/translate/${translationArtifactVersion.id}/pledges`) pledge