Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • stackspin/user-panel
1 result
Show changes
Commits on Source (27)
...@@ -3,37 +3,45 @@ include: ...@@ -3,37 +3,45 @@ include:
stages: stages:
- build - build
- test - build-testimages
- test-unittest
- test-e2e
- npm
backend: backend:
stage: build stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --context ${CI_PROJECT_DIR}/backend/ --dockerfile ${CI_PROJECT_DIR}/backend/Dockerfile --destination $CI_REGISTRY_IMAGE/backend:${CI_COMMIT_REF_NAME}
extends: .kaniko_build extends: .kaniko_build
variables:
KANIKO_CONTEXT: $CI_JOB_NAME
KANIKO_BUILD_IMAGENAME: $CI_JOB_NAME
only: only:
changes: changes:
- backend/**/* - backend/**/*
- .gitlab-ci.yml
frontend: frontend:
stage: build stage: build
image: extends: .kaniko_build
name: gcr.io/kaniko-project/executor:debug variables:
entrypoint: [""] KANIKO_CONTEXT: $CI_JOB_NAME
script: KANIKO_BUILD_IMAGENAME: $CI_JOB_NAME
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --context ${CI_PROJECT_DIR}/frontend/ --dockerfile ${CI_PROJECT_DIR}/frontend/Dockerfile --destination $CI_REGISTRY_IMAGE/frontend:${CI_COMMIT_REF_NAME}
only: only:
changes: changes:
- frontend/**/* - frontend/**/*
- .gitlab-ci.yml - .gitlab-ci.yml
frontend-test:
stage: build-testimages
extends: .kaniko_build
variables:
KANIKO_CONTEXT: "frontend/test"
KANIKO_BUILD_IMAGENAME: "frontend_test"
only:
changes:
- frontend/test/Dockerfile
- .gitlab-ci.yml
backend-unittests: backend-unittests:
stage: test stage: test-unittest
variables: variables:
DATABASE_USER: postgres DATABASE_USER: postgres
DATABASE_PASSWORD: secret DATABASE_PASSWORD: secret
...@@ -49,5 +57,166 @@ backend-unittests: ...@@ -49,5 +57,166 @@ backend-unittests:
- python3 -m unittest discover - python3 -m unittest discover
only: only:
changes: changes:
- login_provider/**/* - backend/**/*
- .gitlab-ci.yml - .gitlab-ci.yml
frontend-e2etest:
stage: test-e2e
image: ${CI_REGISTRY_IMAGE}/frontend_test:${CI_COMMIT_REF_NAME}
services:
- name: postgres:latest
alias: postgres
- name: open.greenhost.net:4567/openappstack/single-sign-on/login_provider:master
alias: login
- name: open.greenhost.net:4567/openappstack/single-sign-on/consent_provider:master
alias: consent
- name: docker.io/oryd/hydra:v1.8
alias: hydra
command:
- serve
- all
- --dangerous-force-http
- --dangerous-allow-insecure-redirect-urls
- http://localhost:3000/callback
- name: ${CI_REGISTRY_IMAGE}/backend:${CI_COMMIT_REF_NAME}
alias: backend
variables:
# ENV vars GitLab
# Feature Flag FF_NETWORK_PER_BUILD Enables creation of a docker network per build
# with the docker executor of the gitlab-runner. This is required for service
# interconnection. Requires gitlab-runner v12.9.0
FF_NETWORK_PER_BUILD: 1
GIT_SUBMODULE_STRATEGY: "recursive"
# ENV vars user-panel
BASE_URL: "http://localhost:3000"
HYDRA_BASE_URL: "http://hydra:4444"
HYDRA_ADMIN_URL: "http://hydra:4445"
ACCESS_TOKEN: "http://hydra:4444/oauth2/token"
AUTHORIZE_URL: "http://hydra:4444/oauth2/auth"
USERINFO_URL: "http://hydra:4444/userinfo"
BACKEND_API_URL: "http://backend:5000/graphql"
OAUTH_CLIENT_ID: "user-panel"
OAUTH_CLIENT_SECRET: "secret"
REDIRECT_URL: "http://localhost:3000/callback"
# ENV vars backend
DATABASE_HOST: "postgres"
DATABASE_USER: postgres
DATABASE_PASSWORD: secret
DATABASE_NAME: postgres
HYDRA_ADMIN_URL: "http://hydra:4445"
# ENV vars POSTGRES
POSTGRES_PASSWORD: secret
POSTGRES_USER: postgres
POSTGRES_DB: postgres
# ENV vars hydra
URLS_LOGIN: "http://login:5000/login"
URLS_LOGOUT: "http://login:5000/logout"
URLS_POST_LOGOUT_REDIRECT: "http://login:5000/"
URLS_CONSENT: "http://consent:5001/consent"
URLS_SELF_ISSUER: "http://hydra:4444/"
DSN: "memory"
SECRETS_SYSTEM: "youReallyNeedToChangeThis"
# ENV vars login/consent
GRAPHQL_URL: "http://backend:5000/graphql"
HYDRA_ADMIN_URL: "http://hydra:4445"
# ENV vars for testing
ADMIN_USERNAME: "admin"
ADMIN_PASSWORD: "adminadmin"
ADMIN_EMAIL: "admin@example.com"
TESTUSER_USERNAME: "testuser"
TESTUSER2_USERNAME: "testuser2"
TESTUSER_PASSWORD: "testtest"
TESTUSER_EMAIL: "testuser@example.net"
TESTUSER2_EMAIL: "testuser2@example.net"
cache:
key:
files:
- frontend/package.json
paths:
- frontend/node_modules/**/*
script:
- cd frontend
- npm install
# wait for hydradmin to be ready
- TIMER=0
- while [[ $HYDRAADMINSTATUS -ne "200" && 60 -ge $TIMER ]]; do HYDRAADMINSTATUS=`curl http://hydra:4445/health/ready -o /dev/null -w "%{http_code}"` || TIMER=$TIMER+5 && sleep 5 ; done
# create oauth client
- ./test/create-hydra-client.sh $OAUTH_CLIENT_ID $OAUTH_CLIENT_SECRET $BASE_URL hydra:4445
# create test users
- cd ../backend/utils
- ./create-role.bash admin backend:5000
- ./create-user.bash $ADMIN_USERNAME $ADMIN_PASSWORD $ADMIN_EMAIL backend:5000
- ./create-user.bash $TESTUSER_USERNAME $TESTUSER_PASSWORD $TESTUSER_EMAIL backend:5000
- ./create-user.bash $TESTUSER2_USERNAME $TESTUSER_PASSWORD $TESTUSER2_EMAIL backend:5000
- ./create-application.bash user-panel "This is the userpanel" backend:5000
- ./assign-role.bash $ADMIN_USERNAME admin backend:5000
- ./grant-access.bash $ADMIN_USERNAME user-panel backend:5000
- ./grant-access.bash $TESTUSER_USERNAME user-panel backend:5000
# wait for hydra sso endpoint to be ready
- TIMER=0
- while [[ $HYDRASTATUS -ne "200" && 60 -ge $TIMER ]]; do HYDRASTATUS=`curl http://hydra:4444/health/ready -o /dev/null -w "%{http_code}"` || TIMER=$TIMER+5 && sleep 5 ; done
# run the tests
- cd ../../frontend/
- npm run test
artifacts:
paths:
- frontend/test/screenshots/
expire_in: 1 month
when: on_failure
audit:
stage: npm
image: node:13-alpine
cache:
key:
files:
- frontend/package.json
paths:
- frontend/node_modules/**/*
script:
- cd frontend
- npm install
- npm audit --audit-level=low
allow_failure: true
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
upgrade:
stage: npm
extends: frontend-e2etest
before_script:
- cd frontend
- apk add git
- npm install -g npm-check-updates
- ncu -u
- npm install
- git diff
- cd ..
allow_failure: true
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
apply:
stage: npm
image: node:13-alpine
script:
- cd frontend
- apk add git
- BRANCH_NAME=npm-update-$(date +%s)
- npm install -g npm-check-updates
- ncu -u
- git config user.name "$GIT_USERNAME"
- git config user.email "$GIT_EMAIL"
- git remote set-url origin https://$GIT_USERNAME:$GIT_ACCESS_TOKEN@open.greenhost.net/openappstack/user-panel
- git checkout -b $BRANCH_NAME
- git commit -a -m "build(npm) update packages"
- git push origin $BRANCH_NAME -o merge_request.create -o merge_request.target=master
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
when: manual
FROM python:3.7-alpine FROM python:3.9-alpine
WORKDIR /usr/src/app WORKDIR /usr/src/app
RUN apk add postgresql-dev libffi-dev libc-dev gcc bash RUN apk add postgresql-dev libffi-dev libc-dev gcc bash curl g++
COPY requirements.txt ./ COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
......
...@@ -10,3 +10,4 @@ bcrypt ...@@ -10,3 +10,4 @@ bcrypt
graphqlclient graphqlclient
hydra-client hydra-client
alembic alembic
email-validator
...@@ -29,7 +29,7 @@ Usage ...@@ -29,7 +29,7 @@ Usage
----- -----
When you first go to the application URL, you will see a "Login" button. This When you first go to the application URL, you will see a "Login" button. This
button opens redirects to you the login screen. On the login screen, you can button redirects to you the login screen. On the login screen, you can
find another button that will redirect you to your single sign-on's login find another button that will redirect you to your single sign-on's login
process. Log in by entering your credentials there. process. Log in by entering your credentials there.
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
"@nuxtjs/axios": "^5.6.0", "@nuxtjs/axios": "^5.6.0",
"bootstrap-vue": "^2.0.3", "bootstrap-vue": "^2.0.3",
"cookie-parser": "^1.4.4", "cookie-parser": "^1.4.4",
"express": "^4.17.1",
"lokka": "^1.7.0", "lokka": "^1.7.0",
"lokka-transport-http": "^1.6.1", "lokka-transport-http": "^1.6.1",
"nuxt": "^2.10.2", "nuxt": "^2.10.2",
"openid-client": "^3.7.3" "openid-client": "^3.7.3"
}, },
"devDependencies": { "devDependencies": {
"chromedriver": "^77.0.0",
"nightwatch": "^1.2.4" "nightwatch": "^1.2.4"
} }
} }
FROM node:13-alpine
RUN apk add --no-cache \
curl \
bash \
chromium \
chromium-chromedriver
#!/bin/bash
KEY=$1
SECRET=$2
BASE_URI=$3
REDIRECT_URI=$BASE_URI/callback
LOGO_URI=$BASE_URI/favicon.ico
HOST=$4
SCOPES="openid profile email openappstack_roles"
curl --header "Content-Type: application/json" \
--request POST \
--data "{\"client_id\": \"$KEY\", \"client_name\": \"$KEY\", \"client_uri\": \"$BASE_URI\",\"client_secret\": \"$SECRET\", \"logo_uri\": \"$LOGO_URI\", \"redirect_uris\": [\"$REDIRECT_URI\"], \"scope\": \"$SCOPES\", \"grant_types\": [\"implicit\"], \"response_types\": [\"token\"], \"token_endpoint_auth_method\": \"client_secret_basic\"}" \
http://$HOST/clients
...@@ -51,7 +51,6 @@ module.exports = { ...@@ -51,7 +51,6 @@ module.exports = {
.verify.strictEqual(adminUserRows.result.value.length, 1, "Testing if there is 1 admin user to edit") .verify.strictEqual(adminUserRows.result.value.length, 1, "Testing if there is 1 admin user to edit")
editUsers editUsers
.assert.containsText("@username", browser.globals.adminUsername ) .assert.containsText("@username", browser.globals.adminUsername )
.assert.containsText("@roles", "admin")
// Test if the add user component is present // Test if the add user component is present
// Submit a username but don't save the user yet // Submit a username but don't save the user yet
addUser addUser
...@@ -74,20 +73,14 @@ module.exports = { ...@@ -74,20 +73,14 @@ module.exports = {
.assert.containsText("@header", "Username") .assert.containsText("@header", "Username")
.assert.containsText("@header", "Password") .assert.containsText("@header", "Password")
.assert.containsText("@header", "Email") .assert.containsText("@header", "Email")
.assert.containsText("@header", "Roles")
.assert.containsText("@header", "Applications")
.assert.visible("@rows") .assert.visible("@rows")
// Test if the user fields are visible // Test if the user fields are visible
editUsers editUsers
.assert.visible("@username") .assert.visible("@username")
.assert.visible("@password") .assert.visible("@password")
.assert.visible("@email") .assert.visible("@email")
.assert.visible("@roles")
.assert.visible("@applications")
// Test if the all the buttons present to edit the user // Test if the all the buttons present to edit the user
editUsers editUsers
.assert.visible("@addRole")
.assert.visible("@addApp")
.assert.visible("@delete") .assert.visible("@delete")
.assert.hidden("@save") .assert.hidden("@save")
editUsers.setValue("@email", "trigger@change.event") editUsers.setValue("@email", "trigger@change.event")
...@@ -116,84 +109,5 @@ module.exports = { ...@@ -116,84 +109,5 @@ module.exports = {
newTestUser.click("@delete") newTestUser.click("@delete")
roles roles
.verify.containsText('@userCount', '3') .verify.containsText('@userCount', '3')
},
'Create user-panel admin user' : async function(browser){
const users = browser.page.users();
const roles = users.section.leftSidebar;
const editUsers = users.section.editUsers;
const newUsername = "newTestUser"
const newPassword = "newTestUser"
const newEmail = "test42@example.net"
users.createUser(newUsername, newPassword, newEmail)
const newTestUser = editUsers.section.newTestUser;
roles
.verify.containsText('@userCount', '4')
.verify.containsText('@adminCount', '1')
newTestUser
.click("@addRole")
.waitForElementVisible("@addRoleInput")
.setValue("@addRoleInput", "admin")
.submitForm("@addRoleInput")
.waitForElementVisible("@save")
.click("@save")
roles
.verify.containsText('@userCount', '4')
.verify.containsText('@adminCount', '2')
browser.refresh()
roles
.verify.containsText('@userCount', '4')
.verify.containsText('@adminCount', '2')
newTestUser
.click("@addApp")
.waitForElementVisible("@addAppInput")
.setValue("@addAppInput", "user-panel")
.submitForm("@addAppInput")
.waitForElementVisible("@save")
.click("@save")
},
'Log in with new admin user' : async function(browser){
const users = browser.page.users();
const editUsers = users.section.editUsers;
const newUsername = "newTestUser"
const newPassword = "newTestUser"
const newEmail = "test42@example.net"
const newTestUser = editUsers.section.newTestUser;
const index = browser.page.index();
const navbar = index.section.navbar;
const usermenu = navbar.section.usermenu;
const login = browser.page.login()
index
.navigate()
.waitForElementVisible('@logoutButton')
.click("@logoutButton")
.waitForElementVisible('@loginButton')
.click('@loginButton')
login
.waitForElementVisible('@loginButton')
.click("@loginButton")
.waitForElementVisible('input[name=username]')
.setValue('input[name=username]', newUsername)
.setValue('input[name=password]', newPassword)
.click('input[name=submit]')
navbar
.waitForElementVisible('@users')
.click("@users")
newTestUser
.waitForElementVisible('@delete')
.click("@delete")
index.navigate()
.click("@logoutButton")
.waitForElementVisible('@loginButton')
.click('@loginButton')
login
.navigate()
.waitForElementVisible('@loginButton')
.click("@loginButton")
.waitForElementVisible('input[name=username]')
.setValue('input[name=username]', newUsername)
.setValue('input[name=password]', newPassword)
.click('input[name=submit]')
index
.assert.containsText('body', 'Failed to login')
} }
}; };
...@@ -4,13 +4,22 @@ ...@@ -4,13 +4,22 @@
"globals_path": "nightwatch_globals.js", "globals_path": "nightwatch_globals.js",
"webdriver" : { "webdriver" : {
"start_process": true, "start_process": true,
"server_path": "node_modules/.bin/chromedriver", "server_path": "/usr/bin/chromedriver",
"port": 9515 "port": 9515
}, },
"test_settings" : { "test_settings" : {
"default" : { "default" : {
"desiredCapabilities": { "desiredCapabilities": {
"browserName": "chrome" "browserName": "chrome",
"chromeOptions": {
"args": ["--headless", "--no-sandbox"]
}
},
"screenshots": {
"enabled": true,
"on_failure": true,
"on_error": true,
"path": "./test/screenshots/"
}, },
"launch_url": "http://localhost:3000/" "launch_url": "http://localhost:3000/"
} }
......
...@@ -10,7 +10,7 @@ var nuxtIsBuild = false ...@@ -10,7 +10,7 @@ var nuxtIsBuild = false
module.exports = { module.exports = {
'default' : { 'default' : {
asyncHookTimeout: 20000, asyncHookTimeout: 120000,
nuxt: nuxt, nuxt: nuxt,
adminUsername: "admin", adminUsername: "admin",
adminPassword: "adminadmin", adminPassword: "adminadmin",
......