Skip to content

Commit 9e33e65

Browse files
authored
Merge pull request #2 from loukie-pressable/plugin/github-actions
Introduced automated GitHub Actions workflow for packaging and releasing plugin updates. Added Ruby script to streamline release creation and asset uploads. Improved multisite compatibility and login redirection reliability. Enhanced security for logout functionality with nonce verification and safer credential handling. Added exclusion for specific API and XML-RPC endpoints to bypass Basic Authentication.
2 parents 78fac21 + 6c94757 commit 9e33e65

7 files changed

Lines changed: 276 additions & 2 deletions

File tree

.gitattributes

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto
3+
4+
# Directories
5+
/.git export-ignore
6+
/.wordpress-org export-ignore
7+
/.github export-ignore
8+
/vendor export-ignore
9+
/dev export-ignore
10+
11+
# Files
12+
/.gitattributes export-ignore
13+
/.gitignore export-ignore
14+
/README.md export-ignore
15+
/composer.json export-ignore
16+
/composer.lock export-ignore
17+
/.DS_Store export-ignore

.github/workflows/build.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'octokit'
4+
5+
puts "Getting version from #{ENV['VERSION_FILE_PATH']}"
6+
7+
begin
8+
version_line = File.foreach(ENV['VERSION_FILE_PATH']).grep(/Version:\s*(\d+\.\d+\.\d+(?:-\w+)?)/i)
9+
version = version_line.empty? ? nil : version_line.first.match(/Version:\s*(\d+\.\d+\.\d+(?:-\w+)?)/i)[1]
10+
11+
puts "Version: #{version}"
12+
13+
raise 'Version not found in main PHP file' if version.nil? || version.empty?
14+
rescue => e
15+
puts "Error extracting version: #{e.message}"
16+
exit 1
17+
end
18+
19+
if ENV['GITHUB_TOKEN'].nil? || ENV['GITHUB_TOKEN'].empty?
20+
puts "Error: GITHUB_TOKEN environment variable not set to empty"
21+
exit 1
22+
end
23+
24+
client = Octokit::Client.new(access_token: ENV['GITHUB_TOKEN'])
25+
26+
release_name = "Release #{version}"
27+
tag_name = version.to_s
28+
29+
puts "Creating tagged release: #{release_name}"
30+
31+
begin
32+
release = client.create_release(
33+
ENV['REPO_NAME'],
34+
tag_name,
35+
{
36+
name: release_name,
37+
target_commitish: ENV['REPO_SHA'],
38+
draft: false,
39+
prerelease: false
40+
}
41+
)
42+
puts 'Done creating tagged release'
43+
rescue Octokit::Error => e
44+
puts "GitHub API error: #{e.message}"
45+
exit 1
46+
end
47+
48+
begin
49+
if !File.exist?(ENV['ZIP_FILE_NAME'])
50+
puts "Error: ZIP file #{ENV['ZIP_FILE_NAME']} not found"
51+
exit 1
52+
end
53+
54+
client.upload_asset(
55+
release[:url],
56+
ENV['ZIP_FILE_NAME'],
57+
{
58+
content_type: 'application/zip',
59+
name: ENV['PROJECT_ZIP_NAME']
60+
}
61+
)
62+
puts 'Done uploading zip to assets'
63+
rescue => e
64+
puts "Error uploading asset: #{e.message}"
65+
exit 1
66+
end

.github/workflows/main.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: PressableBasicAuthReleaseCI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
env:
9+
PROJECT_NAME: pressable-basic-authentication
10+
VERSION_FILE_PATH: './pressable-basic-authentication.php'
11+
12+
jobs:
13+
build:
14+
name: Package Release Project
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v3
20+
21+
- name: Install Ruby
22+
uses: ruby/setup-ruby@v1
23+
with:
24+
ruby-version: '3.1.3'
25+
bundler-cache: true
26+
27+
- name: Create ZIP Archive
28+
run: git archive --format zip --output ${{ env.PROJECT_NAME }}.zip --prefix ${{ env.PROJECT_NAME }}/ main -0
29+
30+
- name: Install Octokit Gem
31+
run: gem install octokit
32+
33+
- name: Run Release Script
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
REPO_NAME: ${{ github.repository }}
37+
REPO_SHA: ${{ github.sha }}
38+
VERSION_FILE_PATH: ${{ env.VERSION_FILE_PATH }}
39+
ZIP_FILE_NAME: ${{ env.PROJECT_NAME }}.zip
40+
PROJECT_ZIP_NAME: ${{ env.PROJECT_NAME }}.zip
41+
run: ruby ./.github/workflows/build.rb

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
vendor
2+
vendor/**
3+
.vscode/**
4+
.DS_Store
5+
*.zip
6+
*.swp
7+
release
8+
release/**
9+
.idea/**

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Hosting Basic Authentication
2+
3+
A WordPress plugin that forces all users to authenticate using Basic Authentication before accessing any page on the site.
4+
5+
## Description
6+
7+
This plugin implements server-level Basic Authentication for your WordPress site, requiring valid credentials before any page can be accessed. It's particularly useful for:
8+
9+
- Sites that should not be publicly accessible
10+
- Sites under maintenance
11+
- Sites that need an additional layer of security before the WordPress login
12+
13+
Key features:
14+
- Forces Basic Authentication for all requests (except AJAX, CRON, and CLI)
15+
- Integrates with WordPress user database for authentication
16+
- Handles logout functionality properly
17+
- Prevents caching of authentication requests
18+
- Logs failed authentication attempts
19+
- Bypasses authentication for Super Admins in multisite installations
20+
- Redirects authenticated users away from wp-login.php
21+
22+
## Requirements
23+
24+
- WordPress 6.7 or higher
25+
- PHP 8.1 or higher
26+
- Server must support PHP_AUTH_USER and PHP_AUTH_PW server variables (most standard hosting environments do)
27+
28+
## Frequently Asked Questions
29+
30+
### Why am I getting constant authentication prompts?
31+
32+
This typically means:
33+
1. Your credentials are incorrect - verify your WordPress username and password
34+
2. Your server is stripping authentication headers - contact your hosting provider
35+
3. There may be a caching layer interfering - try clearing all caches
36+
37+
### Can I bypass Basic Authentication for certain users?
38+
39+
In a multisite installation, Super Admins can bypass the authentication. For single site installations, you would need to modify the plugin code.
40+
41+
### How do I disable the plugin if I'm locked out?
42+
43+
1. Access your site via FTP/SFTP or file manager
44+
2. Rename or delete the `hosting-basic-authentication` folder in `/wp-content/plugins/`
45+
3. This will deactivate the plugin
46+
47+
## Changelog
48+
49+
## License
50+
51+
This plugin is licensed under the GPL2 license. See the [LICENSE](LICENSE) file for details.

pressable-basic-authentication.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/*
99
Plugin Name: Hosting Basic Authentication
1010
Description: Forces all users to authenticate using Basic Authentication before accessing any page.
11-
Version: 1.0.0
11+
Version: 1.0.1
1212
License: GPL2
1313
Text Domain: hosting-basic-authentication
1414
*/
@@ -56,6 +56,11 @@ public function init() {
5656
return;
5757
}
5858

59+
// Skip requests to excluded endpoints
60+
if ($this->should_skip_auth()) {
61+
return;
62+
}
63+
5964
// Handle logout request.
6065
if ( isset( $_GET['basic-auth-logout'] ) ) {
6166
$this->handle_basic_auth_logout();
@@ -124,6 +129,48 @@ private function log_failed_auth( $message ) {
124129
);
125130
}
126131

132+
/**
133+
* Check if the current request should skip authentication
134+
*
135+
* @return bool
136+
*/
137+
private function should_skip_auth() {
138+
// List of endpoints to exclude from Basic Auth
139+
$excluded_endpoints = array(
140+
'xmlrpc.php',
141+
'wp-json/jetpack',
142+
'wp-json/wp/v2',
143+
'wp-json/wp/v3'
144+
);
145+
146+
// Get current request details
147+
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
148+
$script_name = $_SERVER['SCRIPT_NAME'] ?? '';
149+
150+
// Check if this is a direct xmlrpc.php request
151+
if (basename($script_name) === 'xmlrpc.php') {
152+
return true;
153+
}
154+
155+
// Check all excluded endpoints
156+
foreach ($excluded_endpoints as $endpoint) {
157+
if (strpos($request_uri, $endpoint) !== false) {
158+
return true;
159+
}
160+
}
161+
162+
// Check WordPress constants
163+
if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) {
164+
return true;
165+
}
166+
167+
if (defined('REST_REQUEST') && REST_REQUEST) {
168+
return true;
169+
}
170+
171+
return false;
172+
}
173+
127174
/**
128175
* Sends authentication headers.
129176
*/
@@ -291,4 +338,4 @@ private function is_cli_request() {
291338
}
292339

293340
// Initialize the plugin.
294-
new Pressable_Basic_Auth();
341+
new Pressable_Basic_Auth();

readme.txt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
=== Pressable Basic Authentication ===
2+
Contributors: pressable
3+
Tags: pressable, basic auth, authentication, security
4+
Requires at least: 6.7
5+
Tested up to: 6.8
6+
Requires PHP: 8.1
7+
Stable tag: 1.0.1
8+
License: GPLv2 or later
9+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10+
11+
== Description ==
12+
13+
The Pressable Basic Authentication plugin enforces HTTP Basic Authentication across your WordPress site, requiring users to authenticate before accessing any page. This is particularly useful for development environments, ensuring that only authorized users can view or interact with the site during development or testing phases.​
14+
15+
== FEATURES ==​
16+
17+
* Enforces HTTP Basic Authentication on all front-end and back-end pages.
18+
* Installed on sites to restrict public access.
19+
* Allows super administrators to bypass authentication for seamless management.
20+
* Integrates with WordPress's authentication system for user verification.
21+
* Provides a mechanism to log out of Basic Authentication sessions.​
22+
23+
== Frequently Asked Questions ==​
24+
25+
= How do I use this plugin? =​
26+
27+
No manual configuration is required. When accessing a protected site, you'll be prompted to enter your WordPress credentials.​
28+
29+
= Can I disable Basic Authentication on my site? =​
30+
31+
Basic Authentication is enforced on sites to protect your site during development. To remove this protection, you can promote your site to a live environment through the MyPressable Control Panel.​
32+
33+
= What credentials should I use to authenticate? =​
34+
35+
Use your WordPress username and password associated with the site. Ensure that your user account has the necessary permissions to access the site.​
36+
37+
== Installation ==​
38+
39+
No manual installation is necessary.​
40+
41+
== Screenshots ==​
42+
43+
* Initial release​

0 commit comments

Comments
 (0)