Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,25 @@
<version>1.15</version>
<scope>compile</scope>
</dependency>
<!-- OAuth2 and JWT Dependencies -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.43.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>9.37.3</version>
<scope>compile</scope>
</dependency>
<!-- HTTP Client for OAuth2 requests -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
31 changes: 31 additions & 0 deletions resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,37 @@ log:
punishment: true
info: true

# OAuth2 Configuration
oauth2:
# OAuth2 provider settings
client_id: "your_client_id"
client_secret: "your_client_secret"

# OAuth2 endpoints
authorization_url: "https://your-provider.com/oauth2/authorize"
token_url: "https://your-provider.com/oauth2/token"
user_info_url: "https://your-provider.com/oauth2/userinfo"

# OAuth2 scopes to request
scopes: "openid profile groups"

# Redirect URI (should match your web server URL + /oauth2/callback)
redirect_uri: "http://localhost:8080/oauth2/callback"

# Group mapping from OAuth2 claims to local groups
# Maps OAuth2 group names to local group numbers
group_mapping:
"moderators": 1
"admins": 2
"superadmins": 3
"default": 1 # Default group for users not in any mapped group

# JWT claim field that contains user groups (e.g., "groups", "roles", "teams")
groups_claim: "groups"

# JWT claim field that contains username (e.g., "preferred_username", "sub", "email")
username_claim: "preferred_username"

# Permissions for each group
permissions:
group1: # moderator
Expand Down
28 changes: 28 additions & 0 deletions resources/web/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -682,3 +682,31 @@ input[type="submit"]:hover, .btn:hover {
font-size:16px;
}
}

/* OAuth2 Login Button Styles */
.oauth2-btn {
display: inline-block;
padding: 12px 24px;
background-color: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
font-size: 16px;
font-weight: bold;
transition: background-color 0.3s;
}

.oauth2-btn:hover {
background-color: #45a049;
text-decoration: none;
color: white;
}

.oauth2-login {
text-align: center;
}

.oauth2-login p {
margin: 20px 0;
color: #666;
}
56 changes: 9 additions & 47 deletions resources/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ <h1>BungeeWeb</h1>
</header>

<div class="dropdown container">
<div>
<a href="/settings" data-lang="settings.title" data-permission="settings.users.list"></a>
<a href="/account" data-lang="account.title" data-permission="settings.password"></a>
<a href="/logout" data-lang="general.logout"></a>
</div>
<div>
<a href="/logout" data-lang="general.logout"></a>
</div>
</div>

<div class="client">
Expand Down Expand Up @@ -109,54 +107,20 @@ <h1 data-lang="logs.latestlogs"></h1>
</form>
</div>

<div id="settings" class="container">
<h1 data-lang="settings.manageusers"></h1>
<div class="userlist">
<a class="btn" id="createbtn" data-lang="settings.createuser"></a>
<ul class="log"></ul>
</div>

<div class="useredit">
<form>
<input type="hidden" name="id" id="id" value="0" />
<div><label for="user" data-lang="general.username">:</label><input type="text" name="user" id="user" maxlength="16" /></div>
<div><label for="pass" data-lang="general.password">:</label><input type="password" name="pass" id="pass" /></div>
<div><label for="group" data-lang="general.group">:</label><select name="group" id="group"></select></div>
<div class="btngroup">
<input type="submit" class="langval" data-lang="settings.submit" />
<a class="delete btn btnsub" data-lang="settings.delete"></a>
<a class="cancel btn btnsub" data-lang="settings.cancel"></a>
</div>
</form>
</div>
</div>

<div id="account" class="container">
<h1 data-lang="account.changepassword"></h1>
<form class="password">
<div><label for="currentpass" data-lang="account.current">:</label><input type="password" name="currentpass" id="currentpass" /></div>
<div><label for="newpass" data-lang="account.new">:</label><input type="password" name="newpass" id="newpass" /></div>
<div><label for="confirmpass" data-lang="account.confirm">:</label><input type="password" name="confirmpass" id="confirmpass" /></div>
<input type="submit" class="langval" data-lang="account.submit" />
</form>
</div>

<footer><p class="footer">Powered by BungeeWeb - &copy; 2014 Dead-i</p></footer>
</div>

<div class="login">
<div class="main">
<h1>BungeeWeb</h1>
<form>
<div class="oauth2-login">
<div class="error" data-lang="error.auth"></div>
<label for="user" data-lang="general.username">:</label>
<input type="text" name="user" />

<label for="pass" data-lang="general.password">:</label>
<input type="password" name="pass" />

<div class="center"><input type="submit" class="langval" data-lang="general.login" /></div>
</form>
<p>Please log in using OAuth2</p>
<div class="center">
<a href="/login" class="oauth2-btn">Login with OAuth2</a>
</div>
</div>
</div>
</div>

Expand All @@ -168,7 +132,5 @@ <h1>BungeeWeb</h1>
<script src="js/client.dashboard.js"></script>
<script src="js/client.logs.js"></script>
<script src="js/client.players.js"></script>
<script src="js/client.account.js"></script>
<script src="js/client.settings.js"></script>
</body>
</html>
22 changes: 0 additions & 22 deletions resources/web/js/client.account.js

This file was deleted.

31 changes: 18 additions & 13 deletions resources/web/js/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,25 @@ $(document).ready(function () {
});
});

// Login handler
$('.login form').submit(function (e) {
e.preventDefault();
hide($('.login .error'));
$.post('login', $(this).serialize()).done(function (data) {
var data = parse(data);
if (data.status == 1) {
updateSession(function () {
hide($('.login'), loadClient);
});
} else {
$('.login .error').slideDown(200);
// OAuth2 error handler
$(document).ready(function() {
var urlParams = new URLSearchParams(window.location.search);
var error = urlParams.get('error');
if (error) {
var errorMessage = 'Authentication failed';
switch(error) {
case 'oauth_failed':
errorMessage = 'OAuth2 authentication failed';
break;
case 'oauth_exchange_failed':
errorMessage = 'Failed to exchange OAuth2 code';
break;
case 'missing_code':
errorMessage = 'Missing authorization code';
break;
}
});
$('.login .error').text(errorMessage).show();
}
});

// Session updater
Expand Down
105 changes: 0 additions & 105 deletions resources/web/js/client.settings.js

This file was deleted.

6 changes: 5 additions & 1 deletion src/io/github/dead_i/bungeeweb/APICommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ public boolean hasPermission(HttpServletRequest req, String i) {
if (group == null) {
group = 0;
}

// Check if user is authenticated via OAuth2
String oauth2User = (String) req.getSession().getAttribute("oauth2_user");
boolean isAuthenticated = oauth2User != null;

return group > 0 && (i == null || i.isEmpty() || BungeeWeb.getGroupPermissions(group).contains(permission));
return isAuthenticated && group > 0 && (i == null || i.isEmpty() || BungeeWeb.getGroupPermissions(group).contains(permission));
}

public abstract void execute(Plugin plugin, HttpServletRequest req, HttpServletResponse res, String[] args) throws IOException, SQLException;
Expand Down
Loading