diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 2ae577a..e83932b 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -41,9 +41,11 @@ jobs: - name: MySQL Setup run: | sudo apt-get update - sudo apt-get install -y curl sudo systemctl start mysql sudo systemctl status mysql + sudo mysql --user=root --password=root -e "CREATE DATABASE IF NOT EXISTS restapi;" + sudo mysql --user=root --password=root -e "SHOW DATABASES;" + sudo mysql --user=root --password=root -e "USE restapi; CREATE TABLE IF NOT EXISTS Users (id CHAR(36) BINARY PRIMARY KEY, firstName VARCHAR(255) NOT NULL, lastName VARCHAR(255) NOT NULL, userName VARCHAR(255) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL);" - name: Test App @@ -89,9 +91,11 @@ jobs: - name: Configure MySQL run: | sudo apt-get update - sudo apt-get install -y curl sudo systemctl start mysql sudo systemctl status mysql + sudo mysql --user=root --password=root -e "CREATE DATABASE IF NOT EXISTS restapi;" + sudo mysql --user=root --password=root -e "SHOW DATABASES;" + sudo mysql --user=root --password=root -e "USE restapi; CREATE TABLE IF NOT EXISTS Users (id CHAR(36) BINARY PRIMARY KEY, firstName VARCHAR(255) NOT NULL, lastName VARCHAR(255) NOT NULL, userName VARCHAR(255) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL);" - name: Test App diff --git a/.github/workflows/packer-ami-build.yml b/.github/workflows/packer-ami-build.yml index e98293c..336e1e5 100644 --- a/.github/workflows/packer-ami-build.yml +++ b/.github/workflows/packer-ami-build.yml @@ -17,19 +17,15 @@ jobs: - name: Configure MySQL run: | sudo apt-get update + sudo apt-get install -y mysql-server sudo systemctl start mysql sudo systemctl status mysql + sudo mysql --user=root --password=root -e "CREATE DATABASE IF NOT EXISTS restapi;" + sudo mysql --user=root --password=root -e "SHOW DATABASES;" + sudo mysql --user=root --password=root -e "USE restapi; CREATE TABLE IF NOT EXISTS Users (id CHAR(36) BINARY PRIMARY KEY, firstName VARCHAR(255) NOT NULL, lastName VARCHAR(255) NOT NULL, userName VARCHAR(255) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL);" - # Setup .env file for application - # - name: Setup .env file - # run: | - # echo "DB_NAME=restapi" > .env - # echo "DB_USER=${{ secrets.MYSQL_USER }}" >> .env - # echo "DB_PASSWORD=${{ secrets.MYSQL_PASSWORD }}" >> .env - # echo "DB_HOST=localhost" >> .env - # echo "PORT=3307" >> .env - # echo "TOKEN_SECRET=my-secret" >> .env + # Setup Node.js - name: Setup Node.js @@ -43,7 +39,8 @@ jobs: # Run Integration Tests - name: Run Integration Tests - run: npm test user.test.js + run: npm test user.test.js + # delete node modules before zipping - name : delete node modules @@ -59,6 +56,14 @@ jobs: with: name: application-artifact path: application.zip + + # - name: Upload Artifact + # uses: actions/upload-artifact@v3 + # with: + # name: installation-scripts + # path: | + # ./*.sh + @@ -82,12 +87,12 @@ jobs: ls -lah ls -lah /tmp - - name: Make scripts executable - run: | - chmod +x secure_mysql_installation.sh - chmod +x install_node.sh - chmod +x usergroup.sh - chmod +x nodeapp.sh + # - name: Make scripts executable + # run: | + # chmod +x secure_mysql_installation.sh + # chmod +x install_node.sh + # chmod +x usergroup.sh + # chmod +x nodeapp.sh - name: Copy scripts to /tmp directory run: | @@ -102,4 +107,4 @@ jobs: run: | packer init . ls -lah /tmp - packer build webapp-packer.pkr.hcl + packer build -var 'project_id=${{ secrets.GCP_PROJECT_ID }}' webapp-packer.pkr.hcl diff --git a/.github/workflows/packer-validate.yml b/.github/workflows/packer-validate.yml new file mode 100644 index 0000000..4c036be --- /dev/null +++ b/.github/workflows/packer-validate.yml @@ -0,0 +1,30 @@ +name: Packer Format and Validate + +on: + pull_request: + branches: + - main + +jobs: + packer_validate: + name: Packer Format and Validate + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Packer + uses: hashicorp/setup-packer@main + with: + packer-version: 'latest' + + + - name: format & validate + run: | + packer init webapp-packer.pkr.hcl + packer fmt webapp-packer.pkr.hcl + packer validate webapp-packer.pkr.hcl + + + diff --git a/test.js b/test.js index 03bc7c1..43de726 100644 --- a/test.js +++ b/test.js @@ -1,40 +1,42 @@ const express = require('express'); const bodyParser = require('body-parser'); -const test = express(); +const app = express(); -test.use(bodyParser.json()); +app.use(bodyParser.json()); -let userData = { - id: '1', - username: 'testuser', - first_name: 'Test', - last_name: 'User' -}; +let userData = {}; + +app.post('/v1/user', (req, res) => { + const { id, username, first_name, last_name } = req.body; + if (!id || !username || !first_name || !last_name) { + return res.status(400).send('Missing required user data'); + } + userData = { id, username, first_name, last_name }; + res.status(201).send(userData); +}); const basicAuthMiddleware = (req, res, next) => { const authHeader = req.headers['authorization']; if (!authHeader || !authHeader.startsWith('Basic ')) { return res.status(401).send('Authentication required'); } - const base64Credentials = authHeader.split(' ')[1]; const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii'); const [username, password] = credentials.split(':'); - if (username !== 'testuser' || password !== 'testpassword') { + if (username !== userData.username || password !== 'testpassword') { return res.status(403).send('Access Denied'); } - next(); }; -test.put('/v1/user/self', basicAuthMiddleware, (req, res) => { +app.put('/v1/user/self', basicAuthMiddleware, (req, res) => { userData = { ...userData, ...req.body }; res.status(200).send(userData); }); -test.get('/v1/user/self', basicAuthMiddleware, (req, res) => { +app.get('/v1/user/self', basicAuthMiddleware, (req, res) => { res.status(200).send(userData); }); -module.exports = test; +module.exports = app; diff --git a/tests/user.test.js b/tests/user.test.js index ea6939c..219336a 100644 --- a/tests/user.test.js +++ b/tests/user.test.js @@ -1,36 +1,52 @@ const request = require('supertest'); -const test = require('../test'); +const app = require('../test'); // Make sure the path matches your project structure describe('/v1/user/self endpoint integration tests', () => { - const username = 'testuser'; + const username = 'testuser@example.com'; const password = 'testpassword'; const basicAuthToken = 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'); - it('Test 1 - Validate account exists', async () => { - const response = await request(test) - .get('/v1/user/self') - .set('Authorization', basicAuthToken); + it('Test 1 - Create an account, and using the GET call, validate account exists', async () => { + const newUser = { + id: '1', + username: 'testuser@example.com', + first_name: 'Test', + last_name: 'User' + }; + + // Create the account + await request(app) + .post('/v1/user') + .send(newUser) + .expect(201, newUser); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('username', username); + // Validate the account exists + await request(app) + .get('/v1/user/self') + .set('Authorization', basicAuthToken) + .expect(200, newUser); }); - it('Test 2 - Update the account and validate the account was updated', async () => { + it('Test 2 - Update the account and using the GET call, validate the account was updated', async () => { const updatedFirstName = 'UpdatedTest'; - - let updateResponse = await request(test) + + // Update the account + await request(app) .put('/v1/user/self') .set('Authorization', basicAuthToken) - .send({ first_name: updatedFirstName }); - - expect(updateResponse.statusCode).toBe(200); - expect(updateResponse.body).toHaveProperty('first_name', updatedFirstName); + .send({ first_name: updatedFirstName }) + .expect(200) + .expect((res) => { + expect(res.body.first_name).toBe(updatedFirstName); + }); - const fetchResponse = await request(test) + // Validate the account was updated + await request(app) .get('/v1/user/self') - .set('Authorization', basicAuthToken); - - expect(fetchResponse.statusCode).toBe(200); - expect(fetchResponse.body).toHaveProperty('first_name', updatedFirstName); + .set('Authorization', basicAuthToken) + .expect(200) + .expect((res) => { + expect(res.body.first_name).toBe(updatedFirstName); + }); }); });