Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: audit workflow split apart #1397

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
806e591
Add static builds, audit and php build, lighthouse,
tchalvak Jan 29, 2023
90e2b86
Package.json updates for build and serve static.
tchalvak Jan 29, 2023
3550781
Format code with php-cs-fixer
deepsource-autofix[bot] Jan 29, 2023
8db1263
Provide check for database connection.
tchalvak Jan 29, 2023
5831a51
Update format of class static data.
tchalvak Jan 29, 2023
a1ae584
Format code with php-cs-fixer
deepsource-autofix[bot] Jan 29, 2023
30a7898
Simplify gitkeep nonremoval while running make clean.
tchalvak Jan 29, 2023
061fff6
Fix deprecated use of filter constant.
tchalvak Jan 29, 2023
2d77451
Test filtering fixes.
tchalvak Jan 29, 2023
4efbcb9
Format code with php-cs-fixer
deepsource-autofix[bot] Jan 29, 2023
ae97673
Update the build to split out the configure step first.
tchalvak Jan 30, 2023
2b68b16
Make changes to php 8.2.
tchalvak Jan 30, 2023
2e722ff
Fix configure not overriding.
tchalvak Jan 30, 2023
78ec3bf
Deprecation issue fixes,
tchalvak Jan 30, 2023
0596ff5
Composer updates.
tchalvak Jan 30, 2023
4d225b5
One more special property on DAO base class.
tchalvak Jan 30, 2023
d22cdbe
Change message for clarity.
tchalvak Jan 30, 2023
0f7744b
Minor comment for php workflow todo for github token.
tchalvak Jan 30, 2023
a5a08ea
makefile cleanup continued.
tchalvak Jan 30, 2023
845e010
Rollback composer.lock to master.
tchalvak Jan 30, 2023
31726e2
Add game log to build script, again.
tchalvak Mar 3, 2023
c9313a6
Format code with php-cs-fixer
deepsource-autofix[bot] Mar 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Audit

on: [pull_request]

env:
WEBAPP_NAME: ninjawars # set this to your application's name
WEBAPP_PACKAGE_PATH: "." # set this to the path to your web app project, defaults to the repository root
NODE_VERSION: "16.13.1" # set this to the node version to use
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_READ_TOKEN }}
CI: false
jobs:
lighthouseci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
#always-auth: true
#registry-url: "https://npm.pkg.github.com"
- name: Yarn packages audit
run: yarn npm audit
continue-on-error: true
- name: Install, configure, install the lighthouse auditor
run: |
# Check the node version
node --version
corepack enable
yarn install --immutable
# I guess this is still required?
# corepack enable should have made this unnecessary
# Install the project, then...
# yarn workspaces run init-project
yarn init-project
- name: Build
run: |
# Stop eslint from failing the build
rm .eslintrc.json
yarn build
- name: Audit URLs using Lighthouse
uses: treosh/lighthouse-ci-action@v8
with:
urls: |
http://localhost:7474/
http://localhost:7474/intro
budgetPath: ./.budget.json # test performance budgets
uploadArtifacts: true # save results as an action artifacts
temporaryPublicStorage: true # upload lighthouse report to the temporary storage
10 changes: 8 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:

- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: ./composer.phar install --prefer-dist --no-progress --no-suggest
run: |
./composer.phar install --prefer-dist --no-progress
echo "todo put github access token in here"

- name: Create autoload file if necessary
if: steps.composer-cache.outputs.cache-hit == 'true'
Expand All @@ -56,7 +58,11 @@ jobs:
# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md

- name: Run test suite
- name: Run build
run: |
ln -s ./resources.build.php ./deploy/resources.php
make build

- name: Run test suite
run: |
./composer.phar run-script unit-test
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ deploy/model/orm/*
!deploy/model/orm/.gitkeep
!deploy/sql/.gitkeep

# Static build result files
deploy/www/index.html
deploy/www/intro.html
deploy/www/signup.html
deploy/www/login.html

#ignore developer specific GNU make configuration for this project
CONFIG

Expand Down
47 changes: 47 additions & 0 deletions .lighthouserc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module.exports = {
ci: {
collect: {
staticDistDir: 'deploy/www',
isSinglePageApplication: true,
numberOfRuns: 1
},
upload: {
// target: 'filesystem'
target: 'temporary-public-storage'
},
assert: {
"preset": "lighthouse:no-pwa", // Change this to "lighthouse:recommended" when we move to a PWA in the future
assertions: {
"maskable-icon": "off",
"service-worker": "off",
"tap-targets": "off",
"apple-touch-icon": "off",
"first-contentful-paint": ['warn', { minScore: 0.9 }],
"interactive": ['warn', { minScore: 0.9 }],
"last-contentful-paint": ['warn'],
"largest-contentful-paint": ['warn'],
"first-meaningful-paint": ['warn'],
"label": ['warn'],
"max-potential-fid": ['warn', { minScore: 0.9 }],
//"render-blocking-resources": ['warn', { minScore: 0.4 }],
"speed-index": ['warn', { minScore: 0.9 }],
"mainthread-work-breakdown": ['warn', { minScore: 0.9 }],
"legacy-javascript": ['warn', { auditRan: 1 }],
"duplicated-javascript": ['warn'],
"unused-javascript": ['warn', { maxLength: 4 }],
"unminified-javascript": ['warn'],
"uses-long-cache-ttl": ['warn', { maxLength: 13 }],
"uses-rel-preconnect": ['warn'],
"render-blocking-resources": ['error', { maxLength: 2 }],
"font-size": ['warn'],
"bootup-time": ['warn', { minScore: 0.65 }],
"button-name": ['warn', { minScore: 0.65 }],
"link-name": ['warn', { minScore: 0.65 }],
"color-contrast": ['warn', { minScore: 0.65 }],
"robots-txt": ['warn'],
"first-cpu-idle": ['warn', { minScore: 0.85 }],
"meta-description": ['warn'],
}
},
}
}
37 changes: 23 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,50 @@ ifndef TESTFILE
TESTFILE=
endif

build: dep create-structure link-deps

create-structure:
create-directories:
@echo "Do this with sudo due to permissions"
mkdir -p $(JS)
rm -rf ./deploy/templates/compiled/* ./deploy/templates/cache/*
mkdir -p ./deploy/templates/compiled ./deploy/templates/cache ./deploy/resources/logs/
chmod -R ugo+rwX ./deploy/templates/compiled ./deploy/templates/cache
touch ./deploy/resources/logs/deity.log
touch ./deploy/resources/logs/emails.log

conf-resources:
cp -upn ./deploy/resources.build.php ./deploy/resources.php || true
echo "Note that this does not overwrite existing resources.php"

link-deps:
build: conf-resources dep check-base
@echo " ====== Continuing app-specific parts of the build ===="
@echo "Building the deps, linking the components, and building static .html"
@ln -sf "$(RELATIVE_COMPONENTS)jquery/jquery.min.js" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery/jquery.min.map" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery-timeago/jquery.timeago.js" "$(JS)"
@ln -sf "$(RELATIVE_COMPONENTS)jquery-linkify/jquery.linkify.js" "$(JS)"
@ln -sf "$(RELATIVE_VENDOR)twbs/bootstrap/dist/css/bootstrap.min.css" "$(CSS)"
@ln -sf "$(RELATIVE_VENDOR)twbs/bootstrap/dist/js/bootstrap.min.js" "$(JS)"

php deploy/www/intro-controller.php > deploy/www/intro.html
php deploy/www/front-controller.php > deploy/www/index.html
php deploy/www/login-controller.php > deploy/www/login.html
php deploy/www/signup-controller.php > deploy/www/signup.html
@echo "Built front controller to static deploy/www/index.html file, as well as intro.html, login.html, and signup.html"
@echo "This is not a full install, just the build, so check make install and make note-system"

dep:
@$(COMPOSER) install


check: pre-test

check-base:
php deploy/checkbase.php

js-deps:
node -v
corepack enable
echo "corepack enable DONE. Totally sidesteps having to install a yarn version"
yarn -v
corepack enable
yarn install --immutable

preconfig:
preconfig:
cp -u -p ./deploy/resources.build.php ./deploy/resources.php

postcheck:
Expand All @@ -69,7 +78,7 @@ postcheck:
php ./deploy/check.php
echo "Check that the webserver user has permissions to the script!"

install: preconfig build postcheck
install: conf-resources preconfig create-directories build postcheck

install-admin: preconfig build start-chat writable postcheck

Expand Down Expand Up @@ -115,6 +124,7 @@ install-database-client:
start-chat:
touch ./deploy/resources/logs/ninjawars.chat-server.log
chown ${WEBUSER} ./deploy/resources/logs/ninjawars.chat-server.log
chmod ugo+w ./deploy/resources/logs/ninjawars.chat-server.log
nohup php bin/chat-server.php > ./deploy/resources/logs/ninjawars.chat-server.log 2>&1 &

browse:
Expand Down Expand Up @@ -155,7 +165,6 @@ check-for-syntax-errors:
@find "./deploy/www/" -name "*.php" -exec php -l {} \;|grep -v "No syntax errors" || true

test-unit: check-for-syntax-errors

@$(TEST_RUNNER) $(CC_FLAG) --testsuite Unit

test-quick: check-for-syntax-errors
Expand Down Expand Up @@ -201,7 +210,7 @@ clean:
@rm -f "$(JS)jquery.linkify.js"
@rm -f "$(JS)jquery-linkify.min.js"
@rm -f "/tmp/nw"
@cd ./deploy/templates/cache && rm -v ./(".gitkeep") && cd -
@rm -rf ./deploy/templates/cache/* && touch ./deploy/templates/cache/.gitkeep
@rm -rf ./deploy/templates/compiled ./deploy/resources/logs/deity.log ./deploy/resources/logs/emails.log
@rm -rf ./deploy/www/index.html ./deploy/www/intro.html ./deploy/www/login.html ./deploy/www/signup.html
@echo "Cleaned up"
Expand Down Expand Up @@ -274,14 +283,14 @@ web-reload:
ps waux | grep nginx

restart-webserver:
sudo service nginx reload
sudo service nginx restart
sleep 0.5
ps waux | grep nginx

ci-pre-configure:
# Set php version
# Versions available: https://documentation.codeship.com/basic/languages-frameworks/php/#versions-and-setup
phpenv local 8.0
phpenv local 8.2
@echo "Removing xdebug on CI, by default."
rm -f /home/rof/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
ln -s `pwd` /tmp/root
Expand Down
27 changes: 5 additions & 22 deletions deploy/check.php
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
<?php

require_once(realpath(__DIR__).'/resources.php');
// This file is very raw to be about as simple as possible of an app status check
ob_start();
assert(defined('WEB_ROOT'));
assert(defined('DEBUG'));
assert(defined('ROOT'));
assert(defined('SERVER_ROOT'));
assert(defined('DATABASE_PASSWORD'));
assert('' !== WEB_ROOT);
assert('http:///' !== WEB_ROOT);

// Check for webserver root configuration
$out = ob_get_contents();
ob_end_clean();
echo $out;

require(SERVER_ROOT.'lib/base.inc.php');
require_once(VENDOR_ROOT.'autoload.php');
require_once(realpath(__DIR__) . '/checkbase.php');

// Check for database
$connected = (bool) query_item('select 1 from players limit 1');
$is_superuser = (bool) query_item('select usesuper from pg_user where usename = CURRENT_USER;') === true;

function passfail($passed, $pass, $fail) {
function passfailB($passed, $pass, $fail) {
$messaging = ($passed ? '[PASSING]: Reason '.$pass : '[FAILING]: Reason '.$fail);
echo "$messaging\n";
return $passed;
}

// Executing and outputing checks, to try to run all before final return
$outcomes = [
passfail(empty($out), 'WEB ROOT was configured as '.WEB_ROOT, 'No web root seems to be configured '.WEB_ROOT),
passfail($connected, 'Able to connect and list a player from the players table of the database', 'Unable to select from players table of the database'),
passfail(!$is_superuser, 'Connected to database as appropriate user level', 'Connected as database superuser, you want to connect as a lower permission role')
passfailB($connected, 'Able to connect and list a player from the players table of the database', 'Unable to select from players table of the database'),
passfailB(!$is_superuser, 'Connected to database as appropriate user level', 'Connected as database superuser, you want to connect as a lower permission role')
];

return (($outcomes[0] && $outcomes[1] && $outcomes[2]) ? 0 : 1); // Reversed logic due to linux script return values expected
return (($outcomes[0] && $outcomes[1]) ? 0 : 1); // Reversed logic due to linux script return values expected
33 changes: 33 additions & 0 deletions deploy/checkbase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

require_once(realpath(__DIR__) . '/resources.php');
// This file is very raw to be about as simple as possible of an app status check
ob_start();
assert(defined('WEB_ROOT'));
assert(defined('DEBUG'));
assert(defined('ROOT'));
assert(defined('SERVER_ROOT'));
assert(defined('DATABASE_PASSWORD'));
assert('' !== WEB_ROOT);
assert('http:///' !== WEB_ROOT);

// Check for webserver root configuration
$out = ob_get_contents();
ob_end_clean();
echo $out;

require(SERVER_ROOT . 'lib/base.inc.php');
require_once(VENDOR_ROOT . 'autoload.php');

function passfail($passed, $pass, $fail) {
$messaging = ($passed ? '[PASSING]: Reason ' . $pass : '[FAILING]: Reason ' . $fail);
echo "$messaging\n";
return $passed;
}

// Executing and outputing checks, to try to run all before final return
$outcomes = [
passfail(empty($out), 'WEB ROOT was configured as ' . WEB_ROOT, 'No web root seems to be configured ' . WEB_ROOT),
];

return (($outcomes[0]) ? 0 : 1); // Reversed logic due to linux script return values expected
23 changes: 14 additions & 9 deletions deploy/lib/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@ public static function toInt($dirty) {
// Cast anything that can be non-destructively cast.
}

/**
* Strip low and high ascii characters, leave standard keyboard characters
*/
public static function toSimple($dirty) {
return filter_var(
str_replace(['"', '\''], '', $dirty),
FILTER_SANITIZE_STRING,
FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH
);
public static function toAlphaNumeric($dirty) {
return preg_replace('/[^a-zA-Z0-9]/', '', $dirty);
}

public static function toAllowableUsername($dirty) {
return preg_replace('/[^a-zA-Z0-9_-]/', '', $dirty);
}

public static function toEmail($dirty) {
return filter_var($dirty, FILTER_SANITIZE_EMAIL);
}

public static function stripHighUtf8($dirty) {
return filter_var($dirty, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW);
}
}
20 changes: 15 additions & 5 deletions deploy/lib/control/SignupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ private function validateSignupRequest($p_request) {
throw new \RuntimeException('Phase 1 Incomplete: You did not correctly fill out all the necessary information.', 0);
}

if ($p_request->enteredPass !== Filter::toSimple($p_request->enteredPass)) {
if ($p_request->enteredPass !== Filter::stripHighUtf8($p_request->enteredPass)) {
throw new \RuntimeException("Sorry, there seem to be some very special non-standard characters in your password that we don't allow.");
}

Expand Down Expand Up @@ -191,12 +191,12 @@ private function validateSignupRequest($p_request) {
*/
private function buildSignupRequest($p_request) {
$signupRequest = new \stdClass();
$signupRequest->enteredName = Filter::toSimple(trim($p_request->get('send_name') ?? ''));
$signupRequest->enteredEmail = Filter::toSimple(trim($p_request->get('send_email') ?? ''));
$signupRequest->enteredName = Filter::toAllowableUsername(trim($p_request->get('send_name') ?? ''));
$signupRequest->enteredEmail = Filter::toEmail(trim($p_request->get('send_email') ?? ''));
$signupRequest->enteredClass = strtolower(trim($p_request->get('send_class') ?? ''));
$signupRequest->enteredReferral = trim($p_request->get('referred_by', $p_request->get('referrer')) ?? '');
$signupRequest->enteredPass = Filter::toSimple($p_request->get('key') ?? '');
$signupRequest->enteredCPass = Filter::toSimple($p_request->get('cpass') ?? '');
$signupRequest->enteredPass = Filter::stripHighUtf8($p_request->get('key') ?? '');
$signupRequest->enteredCPass = Filter::stripHighUtf8($p_request->get('cpass') ?? '');
$signupRequest->clientIP = $p_request->getClientIp();

// Fallback to key for class
Expand Down Expand Up @@ -237,6 +237,16 @@ private function renderException(\Exception $p_exception, $p_request) {
* @return String[][] An array of class attributes indexed by class key
*/
private function class_choices() {
// If there is not database connection
if (!db_check_connection()) {
// return static class data
return [
'viper' => ['name' => 'Viper', 'expertise' => 'Poison'],
'crane' => ['name' => 'Crane', 'expertise' => 'Speed'],
'dragon' => ['name' => 'Dragon', 'expertise' => 'Healing'],
'tiger' => ['name' => 'Tiger', 'expertise' => 'Strength'],
];
}
$activeClasses = query_array('SELECT identity, class_name, class_note AS expertise FROM class WHERE class_active');
$classes = [];

Expand Down
Loading