From 344319f57226c2e2ddf7d517d646492151924e6b Mon Sep 17 00:00:00 2001 From: Rosanny <rosanny.sihombing@hft-stuttgart.de> Date: Wed, 24 Mar 2021 19:37:05 +0100 Subject: [PATCH] functionality updates --- classes/repo.js | 4 +- classes/website.js | 22 +--- routes/gitlab.js | 169 ++++++++++++------------ routes/routes-account.js | 269 ++++++++++++++------------------------- 4 files changed, 177 insertions(+), 287 deletions(-) diff --git a/classes/repo.js b/classes/repo.js index f0fef1f3..c99ac66f 100644 --- a/classes/repo.js +++ b/classes/repo.js @@ -1,8 +1,8 @@ const Project = require("./project"); class Repo extends Project { - constructor(ownerGitlabId, id, name, desc, logo) { - super(ownerGitlabId, id, name, desc, logo) + constructor(ownerGitlabId, id, name, desc, logo, path) { + super(ownerGitlabId, id, name, desc, logo, path) } } diff --git a/classes/website.js b/classes/website.js index 98189269..1d05c400 100644 --- a/classes/website.js +++ b/classes/website.js @@ -1,28 +1,8 @@ const Project = require("./project"); class Website extends Project { - constructor(ownerGitlabId, id, name, desc, logo, path, settingUrl, kontaktUrl, isPublished) { + constructor(ownerGitlabId, id, name, desc, logo, path) { super(ownerGitlabId, id, name, desc, logo, path) - this.settingUrl = settingUrl - this.kontaktUrl = kontaktUrl - this.isPublished = isPublished - } - // getter - getSettingUrl() { - return this.settingUrl - } - getKontaktUrl() { - return this.kontaktUrl - } - getIsPublished() { - return this.isPublished - } - // setter - setSettingUrl(newSettingUrl) { - this.settingUrl = newSettingUrl - } - setKontaktUrl(newKontaktUrl) { - this.kontaktUrl = newKontaktUrl } } diff --git a/routes/gitlab.js b/routes/gitlab.js index 49e89807..8766d917 100644 --- a/routes/gitlab.js +++ b/routes/gitlab.js @@ -5,67 +5,52 @@ const fs = require('fs') var formData = require('form-data') var gitlab = { - getUserIdByEmail: function(email, callback) { - let dataConfig = { + // todo: GraphQL currentUser + + getUserByEmail: async function(email) { + return axios({ method: 'get', url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users?search='+email, headers: { 'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects} - } - - axios(dataConfig) - .then(function (response) { - let res = { - error: false, - data: response.data[0].id} - callback(res) }) - .catch(function (err) { - let res = { - error: true, - data: err} - callback(res) + .then(res => userData = { + id: res.data[0].id, + username: res.data[0].username }) + .catch(err => console.error(err)) }, - createNewPages: function(newPagesData, newLogoFile, callback) { + createNewPages: async function(newPagesData, newLogoFile, template) { let data = new formData() data.append('avatar', fs.createReadStream(newLogoFile)) - let dataConfig = { + return axios({ method: 'post', url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/user/'+newPagesData.getOwnerGitlabId()+ '?name='+newPagesData.getName()+'&description='+newPagesData.getDesc()+'&tag_list=website'+ - '&use_custom_template=true&template_name=page_basic', + '&use_custom_template=true&template_name='+template, headers: { 'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects, ...data.getHeaders() }, - data : data - } - - axios(dataConfig) - .then(response => { - let res = { - error: false, - data: response.data} - callback(res) + data: data }) - .catch(err => { - console.log(err) - let res = { - error: true, - data: err.response.data} - callback(res) + .then(res => res = { + error: false, + data: res.data + }) + .catch(err => res = { + error: true, + data: err.response.data }) }, - updateProject: function(updatedProjectData, newLogoFile, callback){ - console.log(updatedProjectData) + updateProject: async function(updatedProjectData, newLogoFile){ let data = new formData() if (newLogoFile) { data.append('avatar', fs.createReadStream(newLogoFile)) } - - let dataConfig = { + + return axios({ method: 'put', url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+updatedProjectData.getId()+ '?name='+updatedProjectData.getName()+'&description='+updatedProjectData.getDesc(), @@ -74,68 +59,70 @@ var gitlab = { ...data.getHeaders() }, data : data - } - - axios(dataConfig) - .then(response => { - let res = { - error: false, - data: response.data} - callback(res) }) - .catch(err => { - console.log(err) - let res = { - error: true, - data: err.response.data} - callback(res) + .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', + url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users/'+gitlabUserId+'/projects?private_token='+ + config.gitlab.token_readWriteProjects+'&owned=true&simple=true&visibility=public' }) + .then(res => res.data) + .catch(err => console.error(err)) }, - getUserProjects: function(gitlabUserId, callback) { - axios.get('https://transfer.hft-stuttgart.de/gitlab/api/v4/users/'+gitlabUserId+'/projects?private_token='+ - config.gitlab.token_readWriteProjects+'&owned=true&simple=true&visibility=public') - .then(response => { - let res = { - error: false, - data: response.data} - callback(res) + getProjectById: async function(projectId) { + return axios({ + method: 'get', + url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'?private_token='+ + config.gitlab.token_readWriteProjects }) - .catch(err => { - let res = { - error: true, - data: err.message} - callback(res) + .then(res => res.data) + .catch(err => console.error(err)) + }, + getProjectPipelineLatestStatus: async function(projectId) { + return axios({ + method: 'get', + url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines' }) + .then(res => res.data[0].status) + .catch(err => console.error(err)) }, - getProjectIdsFromRunners: function(gitlabUserId, callback) { - let projectIds = [] - let dataConfig = { + // delete peoject: https://docs.gitlab.com/ee/api/projects.html#delete-project + // + // test GraphQL + getGraphqlTest: function(callback) { + axios({ + url: 'https://gitlab.com/api/graphql', method: 'get', - url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/runners/7', - headers: { - 'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects} - } - - axios(dataConfig) - .then(function (response) { - let projects = response.data.projects - projects.forEach((project) => { - if(project.namespace.id == gitlabUserId) { - projectIds.push(project.id) + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects + }, + data: { + query: `{ + currentUser { + id + username + } + }` + /* query: `{ + projects { + nodes { + id + } } - }) - let res = { - error: false, - data: projectIds} - - callback(res) - }) - .catch(function (err) { - let res = { - error: true, - data: err} - - callback(res) + }` */ + } + }).then((result) => { + console.log(JSON.stringify(result.data)) }); } } diff --git a/routes/routes-account.js b/routes/routes-account.js index 5baa62a4..269ab1ff 100644 --- a/routes/routes-account.js +++ b/routes/routes-account.js @@ -13,6 +13,7 @@ const crypto = require('crypto') const mailer = require('./mailer') const logoDir = 'public/upload/' const tpGitlabURL = 'https://transfer.hft-stuttgart.de/gitlab/' +const tpGitlabPagesURL = 'https://transfer.hft-stuttgart.de/pages/' const portalUser = require('../classes/user') const projectInformation = require('../classes/website') @@ -128,7 +129,6 @@ module.exports = function (app, config, passport, i18n) { } }) } - res.render(lang+'/account/home', { user: loggedInUser }); @@ -180,7 +180,7 @@ module.exports = function (app, config, passport, i18n) { } }) - app.get('/services', function(req, res){ + app.get('/services', async function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { @@ -189,65 +189,45 @@ module.exports = function (app, config, passport, i18n) { } else { let gitlabReposArr = [] let gitlabPagesArr = [] - + if(loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account - async.waterfall([ - // check projects in runners - function(callback) { - let gitlabRunnersProjectIdsArr - gitlab.getProjectIdsFromRunners(loggedInUser.getGitlabUserId(), function(data){ - if(data.error) - return res.status(500).send(data.data) - gitlabRunnersProjectIdsArr = data.data - callback(null, gitlabRunnersProjectIdsArr) - }) - } - ], function(err, gitlabRunnersProjectIdsArr) { - // get user projects - gitlab.getUserProjects(loggedInUser.getGitlabUserId(), function(data){ - if (data.error) - return res.status(500).send(data.data) - let gitlabData = data.data - for(let i = 0; i < gitlabData.length; i++){ - if (gitlabData[i].tag_list.includes('website')) { - let idxRunners = gitlabRunnersProjectIdsArr.indexOf(gitlabData[i].id) - let isWebsitePublished = false - if (idxRunners > 0) { - isWebsitePublished = true - } - let page = new projectInformation(loggedInUser.getGitlabUserId(), gitlabData[i].id, gitlabData[i].name, gitlabData[i].description, - gitlabData[i].avatar_url, gitlabData[i].path, null, null, isWebsitePublished) - gitlabPagesArr.push(page) - } else { - let repo = new projectRepo(loggedInUser.getGitlabUserId(), gitlabData[i].id, gitlabData[i].name, gitlabData[i].description, - gitlabData[i].avatar_url, gitlabData[i].path) - gitlabReposArr.push(repo) - } + let userProjects = await gitlab.getUserProjects(loggedInUser.getGitlabUserId()) + if (!userProjects) + res.status(500).send("something went wrong :/") + + for (project in userProjects) { + if (userProjects[project].tag_list.includes('website')) { + let page = { + projectInformation: new projectInformation(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name, + userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace), + pipelineStatus: await gitlab.getProjectPipelineLatestStatus(userProjects[project].id) } - - res.render(lang+'/account/services', { - user: loggedInUser, - gitlabRepos: gitlabReposArr, - gitlabPages: gitlabPagesArr - }) - }) + gitlabPagesArr.push(page) + } else { + let repo = new projectRepo(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name, + userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace) + gitlabReposArr.push(repo) + } + } + + res.render(lang+'/account/services', { + user: loggedInUser, + gitlabRepos: gitlabReposArr, + gitlabPages: gitlabPagesArr }) } else { // for users who have not activated their gitlab account yet - gitlab.getUserIdByEmail(loggedInUser.getEmail(), function(data){ - if (data.error) { - res.status(500).render(lang+'/500', { error: data.data }) + let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail()) + // RS: if error, then what? + let gitlabActivationData = { + user_id: loggedInUser.getId(), + gitlab_userId: gitlabUser.id} + // RS: update to await + methods.addGitlabUser(gitlabActivationData, function(err){ + if(err) { + res.status(500).render(lang+'/500', { error: err }) } else { - let gitlabActivationData = { - user_id: loggedInUser.getId(), - gitlab_userId: data.data} - methods.addGitlabUser(gitlabActivationData, function(err){ - if(err) { - res.status(500).render(lang+'/500', { error: err }) - } else { - loggedInUser.setGitlabUserId(gitlabActivationData.gitlab_userId) - res.redirect('/account/services') - } - }) + loggedInUser.setGitlabUserId(gitlabActivationData.gitlab_userId) + res.redirect('/account/services') } }) } @@ -480,13 +460,19 @@ module.exports = function (app, config, passport, i18n) { // ============= NEW GITLAB PAGES =========================== - app.get('/newInformation', function(req, res){ + app.get('/newInformation', async function(req, res){ if (!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { - res.render(lang+'/account/newInformation', { - user: loggedInUser - }) + let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail()) + if (!gitlabUser) { // no user found + res.redirect('/account/service') + } else { + res.render(lang+'/account/newInformation', { + user: loggedInUser, + gitlabUsername: gitlabUser.username + }) + } } }) app.post('/newInformation', function(req, res) { @@ -499,7 +485,8 @@ module.exports = function (app, config, passport, i18n) { } else { let projectName = req.body.name.toLowerCase().replace(/\s/g, '-') let projectDesc = req.body.description - let newInformation = new projectInformation(loggedInUser.getGitlabUserId(), null, projectName, projectDesc, null, null, null, null, false) + let projectTemplate = req.body.template + let newInformation = new projectInformation(loggedInUser.getGitlabUserId(), null, projectName, projectDesc, null, null) if (!req.files) { res.flash('error', 'Bitte geben Sie ein Projektlogo an.') @@ -513,28 +500,23 @@ module.exports = function (app, config, passport, i18n) { callback(err, newLogoFile) }) }, - function(newLogoFile, callback){ // create a new GitLab Page - gitlab.createNewPages(newInformation, newLogoFile, function(data){ - let result = data.data - if (data.error) { - if(result.message.name == "has already been taken") { - res.flash("error", "Der Projektname '"+newInformation.getName()+"' ist bereits vergeben, bitte wählen Sie einen anderen Namen.") - } else { - res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ") - } - res.redirect('/account/newInformation') + async function(newLogoFile){ // create a new GitLab Page + let newPages = await gitlab.createNewPages(newInformation, newLogoFile, projectTemplate) + if (newPages.error) { + if(newPages.data.message.name == "has already been taken") { + res.flash("error", "Der Projektname '"+newInformation.getName()+"' ist bereits vergeben, bitte wählen Sie einen anderen Namen.") } else { - newInformation.setId(result.id) - newInformation.setLogo(result.avatar_url) - newInformation.setPath(result.path) - newInformation.setSettingUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/settings.js') - newInformation.setKontaktUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/kontakt.html') - - res.flash("success", "Ihre Webseite wurde erstellt, aber noch nicht veröffentlicht. Bitte fahren Sie mit Schritten 2 und 3 fort, um Ihre Webseite zu veröffentlichen.") - res.redirect('/account/updateInformation?id='+newInformation.getId()+'&s=n') + res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ") } - callback(null) - }) + res.redirect('/account/newInformation') + } else { + let newPagesData = newPages.data + + //res.flash("success", "Ihre Webseite wurde erstellt, aber noch nicht veröffentlicht. Bitte fahren Sie mit Schritten 2 und 3 fort, um Ihre Webseite zu veröffentlichen.") + res.flash("success", "Your website will be published AFTER you complete your website by following the provided guideline below."+ + "\r\n Your website URL: "+tpGitlabPagesURL+newPagesData.path_with_namespace+"/home/") + res.redirect('/account/updateInformation?id='+newPagesData.id) + } } ], function (err) { if(err) console.log(err) @@ -548,51 +530,33 @@ module.exports = function (app, config, passport, i18n) { } }) - app.get('/updateInformation', function(req, res){ + app.get('/updateInformation', async function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if(!req.query.id) { res.redirect('/account/services') } else { - gitlab.getUserProjects(loggedInUser.getGitlabUserId(), function(data){ - if (data.error) { - res.status(500).render(lang+'/500', { error: data.data }) - } else { - // quick way to decide whether a website is already published or not - let informationStatus - if(req.query.s != "y" && req.query.s != "n") { - res.redirect('/account/services') - } else { - if(req.query.s == "y") { - informationStatus = true - } else if(req.query.s == "n") { - informationStatus = false - } - let gitlabData = data.data - let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, null, null, null, null, null, null, informationStatus) - for(let i = 0; i < gitlabData.length; i++){ - if (gitlabData[i].id == req.query.id) { - curInformation.setName(gitlabData[i].name) - curInformation.setDesc(gitlabData[i].description) - curInformation.setLogo(gitlabData[i].avatar_url) - curInformation.setPath(gitlabData[i].path) - curInformation.setSettingUrl(tpGitlabURL+gitlabData[i].path_with_namespace+'/-/edit/master/public/settings.js') - curInformation.setKontaktUrl(tpGitlabURL+gitlabData[i].path_with_namespace+'/-/edit/master/public/kontakt.html') - - break - } - } - res.render(lang+'/account/updateInformation', { - user: loggedInUser, - information: curInformation - }) - } - } - }) + let project = await gitlab.getProjectById(req.query.id) + if (!project) { + console.log(" =================== error or no project found") + res.redirect('/account/services') + } else if (project.owner.id != loggedInUser.getGitlabUserId()) { + console.log(" =================== not your project") + res.redirect('/account/services') + } else { + let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, project.name, project.description, + project.avatar_url, project.path_with_namespace) + + res.render(lang+'/account/updateInformation', { + user: loggedInUser, + information: curInformation + }) + } } } }) + app.post('/updateInformation', function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') @@ -603,13 +567,9 @@ module.exports = function (app, config, passport, i18n) { } else { let projectName = req.body.name.toLowerCase().replace(/\s/g, '-') let projectDesc = req.body.description - let isProjectPublished = true - if (req.body.isPublished == "false") { - isProjectPublished = false - } - let updatedInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, projectName, projectDesc, null, null, null, null, isProjectPublished) - + let updatedInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, projectName, projectDesc, null, null) let newLogoFile + async.waterfall([ function(callback){ // upload logo if(!req.files) { @@ -622,26 +582,21 @@ module.exports = function (app, config, passport, i18n) { }) } }, - function(newLogoFile, callback){ // update gitlab page - gitlab.updateProject(updatedInformation, newLogoFile, function(data){ - let result = data.data - if (data.error) { - if(result.message.name == "has already been taken") { - res.flash("error", "Der Projektname ist bereits vergeben, bitte wählen Sie einen anderen Namen.") - } else { - res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ") - } + async function(newLogoFile, callback){ // update gitlab page + let updatedPages = await gitlab.updateProject(updatedInformation, newLogoFile) + let pagesData = updatedPages.data + if (pagesData.error) { + if(pagesData.message.name == "has already been taken") { + res.flash("error", "Der Projektname ist bereits vergeben, bitte wählen Sie einen anderen Namen.") } else { - updatedInformation.setLogo(result.avatar_url) - updatedInformation.setPath(result.path) - updatedInformation.setSettingUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/settings.js') - updatedInformation.setKontaktUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/kontakt.html') - res.flash("success", "Your website has been updated") + res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ") } - res.redirect('/account/updateInformation?id='+updatedInformation.getId()) - - callback(null) - }) + } else { + updatedInformation.setLogo(pagesData.avatar_url) + updatedInformation.setPath(pagesData.path) + res.flash("success", "Your website has been updated") + } + res.redirect('/account/updateInformation?id='+updatedInformation.getId()) } ], function (err) { if(err) console.log(err) @@ -657,38 +612,6 @@ module.exports = function (app, config, passport, i18n) { // RS: delete projektInformation? - app.post('/sendPublishRequest', function(req, res) { - if (!req.isAuthenticated() && loggedInUser) { - res.redirect('/login') - } else { - let emailAddress = loggedInUser.getEmail() - let supportAddress = "support-transfer@hft-stuttgart.de" - let projectName = req.body.projectName - let emailContent = "Guten Tag, \n\nhiermit beantrage Ich die Freischaltung einer Webseite auf dem Transferportal für folgendes Projekt: \n" - +projectName+"\n\nVielen Dank,\n"+loggedInUser.getFullName() - let emailSubject = "M4_LAB Anfrage zur Veröffentlichung einer neuen Webseite" - async.waterfall([ - function(done) { - mailer.options.to = supportAddress - mailer.options.cc = emailAddress - mailer.options.subject = emailSubject - mailer.options.text = emailContent - mailer.transport.sendMail(mailer.options, function(err) { - done(err, 'done') - }) - } - ], function(err) { - if (err) { - console.log(err) - res.send('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.') - } - else { - res.send('Vielen Dank für Ihre Anfrage. Eine Kopie Ihrer Anfrage wurde an ' + emailAddress + ' versandt.') - } - }) - } - }) - // ============= NEW USERS REGISTRATION =========================== app.get('/registration', function(req, res) { res.render(lang+'/account/registration') -- GitLab