diff --git a/README.md b/README.md index 4c51fd3399c4cd555ba805d1aed06d24a2a9ddd4..1ca41b18c0974529f197555999bceb6f79d86794 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ User Account Management -MLAB-481 branch should be created from this branch \ No newline at end of file +This is the repository of the User Account of the TransferPortal. \ No newline at end of file diff --git a/app.js b/app.js index 8ff8ef12d7bf1369b82666981e8def19dbf591f0..5680690e17ddac58af6c0f9c59b19d833042c36a 100644 --- a/app.js +++ b/app.js @@ -11,6 +11,7 @@ const flash = require('express-flash-2'); const fileUpload = require('express-fileupload'); const helmet = require('helmet'); const compression = require('compression'); +const methodOverride = require('method-override'); const i18n = require('i18n'); // internationalization i18n.configure({ @@ -35,6 +36,7 @@ app.use(fileUpload({ } })); +app.use(methodOverride('_method')); app.use(helmet()); app.use(compression()); app.use(morgan('combined')); diff --git a/package-lock.json b/package-lock.json index 5879f5690c050446dff40cf401cce62455b495ee..d39052869da30ff0e943e5f31f7afd4bf1e8878e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5013,6 +5013,32 @@ "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz", "integrity": "sha1-/TTsOZEqFIaKFZXq63QkhauKs3I=" }, + "method-override": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", + "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", + "requires": { + "debug": "3.1.0", + "methods": "~1.1.2", + "parseurl": "~1.3.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", diff --git a/package.json b/package.json index 739f4247468a9d5709d69f33e94aa6eb85197c82..a1b45cc0affa8b1512bd201e7b0a742849a187c9 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "helmet": "^3.23.3", "i18n": "^0.8.5", "jest": "^26.6.3", + "method-override": "^3.0.0", "morgan": "^1.9.1", "mysql": "^2.17.1", "mysql2": "^2.2.5", diff --git a/routes/gitlab.js b/routes/gitlab.js index 9e82a8a0f064a862656c1d7551916a9088ff8728..62ff36508f80a0747538386a7838e4892c5a1706 100644 --- a/routes/gitlab.js +++ b/routes/gitlab.js @@ -66,6 +66,24 @@ var gitlab = { data: err.response.data }) }, + deleteProjectById: function(projectId){ + // https://docs.gitlab.com/ee/api/projects.html#delete-project + return axios({ + method: 'delete', + url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId, + headers: { + 'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects + } + }) + .then(res => res = { + error: false, + data: res.data + }) + .catch(err => res = { + error: true, + data: err.response.data + }) + }, getUserProjects: async function(gitlabUserId) { return axios({ method: 'get', @@ -96,7 +114,6 @@ var gitlab = { .then(res => res.data[0].status) .catch(err => console.error(err)) }, - // delete peoject: https://docs.gitlab.com/ee/api/projects.html#delete-project // // test GraphQL getGraphqlTest: function(callback) { diff --git a/routes/routes-account.js b/routes/routes-account.js index 0244ea77fd7dd1312c32d1cb19851f763267f33d..6c931ed90aa943dbd1d0e702b122063331276c1b 100644 --- a/routes/routes-account.js +++ b/routes/routes-account.js @@ -562,10 +562,13 @@ module.exports = function (app, config, passport, i18n) { } else { let project = await gitlab.getProjectById(req.query.id) if (!project) { - console.log(" =================== error or no project found") + console.log(" ========= Error or no project found") + res.redirect('/account/services') + } else if (!project.owner) { + console.log(" ========= Project cannot be accessed, since it does not have an owner") res.redirect('/account/services') } else if (project.owner.id != loggedInUser.getGitlabUserId()) { - console.log(" =================== not your project") + console.log(" ========= Access denied: Not your project") res.redirect('/account/services') } else { let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, project.name, project.description, @@ -579,7 +582,7 @@ module.exports = function (app, config, passport, i18n) { } } }) - + // update a website app.post('/updateInformation', async function(req, res){ if( !req.isAuthenticated() ) { res.redirect('/login') @@ -635,7 +638,35 @@ module.exports = function (app, config, passport, i18n) { } }) - // RS: delete projektInformation? + app.delete('/deleteProject', async function(req, res){ + console.log("delete project") + + if( !req.isAuthenticated() ) { + res.redirect('/login') + } else { + let loggedInUser = await getLoggedInUserData(req.user.email) + let projectId = req.body.id + + if (projectId) { + // check if the owner is valid + let project = await gitlab.getProjectById(projectId) + if (!project) { + console.log(" ========= Error or no project found") + } else if (!project.owner) { + console.log(" ========= Project cannot be accessed, since it does not have an owner") + } else if (project.owner.id != loggedInUser.getGitlabUserId()) { + console.log(" ========= Access denied: Not your project") + } else { + // delete project + let project = await gitlab.deleteProjectById(projectId) + if (project.error) { + res.flash("error", "Project cannot be deleted. Please try again.") + } + } + } + res.redirect('/account/services') + } + }) // ============= NEW USERS REGISTRATION =========================== app.get('/registration', function(req, res) { diff --git a/views/DE/account/updateInformation.pug b/views/DE/account/updateInformation.pug index acd0a143ac6807f3058dc20e7ef90343e3a0d368..3c0c875bc8f4a8a13fc1c11687b908ef75ed593e 100644 --- a/views/DE/account/updateInformation.pug +++ b/views/DE/account/updateInformation.pug @@ -82,6 +82,29 @@ html(lang="de") div(class="card-body") Passen Sie die Werte für projektname und projektseitenlink an, indem Sie die entsprechenden Werte in die Anführungszeichen schreiben. img(src="https://m4lab.hft-stuttgart.de/img/help/edit_settings.png", class="img-fluid", style="border: 1px solid gray;", alt="setting.js") p Klicken Sie anschließend auf <i>commit changes</i>, um die Änderungen zu speichern. + hr + div(class="mx-4") + div(class="alert alert-danger" role="alert") <h5><strong>Webseite löschen</strong></h5> + p Dies wird <strong><em>#{information.name}</em></strong> sofort endgültig löschen, inklusive ihrer Repositorien und aller zugehöriger Ressourcen. + p Sind Sie WIRKLICH SICHER, dass Sie diese Webseite löschen wollen? + button(type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteWebsiteConfirmation") Löschen + + // Modal + div(class="modal" id="deleteWebsiteConfirmation" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true") + div(class="modal-dialog" role="document") + div(class="modal-content") + div(class="modal-header") + h5(class="modal-title" id="modalLabel") Sind Sie WIRKLICH SICHER? + button(type="button" class="close" data-dismiss="modal" aria-label="Close") + span(aria-hidden="true") × + div(class="modal-body") + | <p>Sie sind dabei, diese Webseite, ihr Repositorium und alle zugehörigen Ressourcen, inklusive aller Inhalte, Bilder etc. endgültig zu löschen.</p> + | <p>Sobald eine Webseite endgültig gelöscht ist, kann sie nicht wiederhergestellt werden. <strong>Diese Aktion kann nicht rückgängig gemacht werden.</strong></p> + div(class="modal-footer") + form(method="POST", action="/deleteProject?_method=DELETE", encType="multipart/form-data") + input(name="id", value=information.id, type="hidden") + button(type="button" class="btn btn-primary mx-2" data-dismiss="modal") Abbrechen, Webseite behalten + button(type="submit" class="btn btn-danger") Ja, Webseite löschen // jQuery script(src="https://code.jquery.com/jquery-3.3.1.min.js")