Add settings view on web page (Read Only)

This commit is contained in:
Sebastien 2018-09-24 15:50:32 +03:00
parent dde0040847
commit e70fb4e266
16 changed files with 419 additions and 10 deletions

View File

@ -0,0 +1,30 @@
package net.Broken.RestApi.Data.Settings;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GetSettingsData {
public String name;
public String id;
public TYPE type;
public List<Value> values;
public String current;
public GetSettingsData() {
}
public GetSettingsData(String name, String id, TYPE type, List<Value> values, String current) {
this.name = name;
this.id = id;
this.type = type;
this.values = values;
this.current = current;
}
public enum TYPE{
BOOL,LIST,STRING
}
}

View File

@ -0,0 +1,14 @@
package net.Broken.RestApi.Data.Settings;
public class Value {
public String name;
public String id;
public Value() {
}
public Value(String name, String id) {
this.name = name;
this.id = id;
}
}

View File

@ -3,9 +3,12 @@ package net.Broken.RestApi.Data.UserManager;
public class GuildInfo { public class GuildInfo {
public String name; public String name;
public String id; public String id;
public boolean isAdmin;
public GuildInfo(String name, String id) { public GuildInfo(String name, String id, boolean isAdmin) {
this.name = name; this.name = name;
this.id = id; this.id = id;
this.isAdmin = isAdmin;
} }
} }

View File

@ -0,0 +1,52 @@
package net.Broken.RestApi;
import net.Broken.DB.Entity.GuildPreferenceEntity;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.GuildPreferenceRepository;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import net.Broken.RestApi.Data.Settings.GetSettingsData;
import net.Broken.RestApi.Data.Settings.Value;
import net.Broken.Tools.SettingsUtils;
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.RegEx;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api")
public class SettingAPIController {
private Logger logger = LogManager.getLogger();
@RequestMapping(value = "/settings", method = RequestMethod.GET)
public ResponseEntity<ArrayList<GetSettingsData>> getSettings(@CookieValue("token") String token, @CookieValue("guild") String guild){
SettingsUtils settingUtils = SettingsUtils.getInstance();
if(settingUtils.checkPermission(token, guild)){
Guild jdaGuild = MainBot.jda.getGuildById(guild);
return new ResponseEntity<>( settingUtils.extractSettings(jdaGuild), HttpStatus.OK);
}
else{
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
}

View File

@ -9,6 +9,7 @@ import net.Broken.RestApi.Data.UserManager.*;
import net.Broken.Tools.UserManager.Exceptions.*; import net.Broken.Tools.UserManager.Exceptions.*;
import net.Broken.Tools.UserManager.Oauth; import net.Broken.Tools.UserManager.Oauth;
import net.Broken.Tools.UserManager.UserUtils; import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.User; import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -108,7 +109,8 @@ public class UserManagerAPIController {
List<GuildInfo> temp = new ArrayList<>(); List<GuildInfo> temp = new ArrayList<>();
for (Guild guild : user.getMutualGuilds()){ for (Guild guild : user.getMutualGuilds()){
temp.add(new GuildInfo(guild.getName(), guild.getId()));
temp.add(new GuildInfo(guild.getName(), guild.getId(), guild.getMember(user).hasPermission(Permission.ADMINISTRATOR)));
} }
return new ResponseEntity<>(temp, HttpStatus.OK); return new ResponseEntity<>(temp, HttpStatus.OK);

View File

@ -0,0 +1,171 @@
package net.Broken.Tools;
import net.Broken.DB.Entity.GuildPreferenceEntity;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.GuildPreferenceRepository;
import net.Broken.DB.Repository.PendingPwdResetRepository;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import net.Broken.RestApi.Data.Settings.GetSettingsData;
import net.Broken.RestApi.Data.Settings.Value;
import net.Broken.SpringContext;
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.ArrayList;
import java.util.List;
public class SettingsUtils {
private static SettingsUtils INSTANCE;
Logger logger = LogManager.getLogger();
public static SettingsUtils getInstance(){
return (INSTANCE == null) ? new SettingsUtils() : INSTANCE;
}
GuildPreferenceRepository guildPreferenceRepository;
UserRepository userRepository;
private SettingsUtils() {
ApplicationContext context = SpringContext.getAppContext();
guildPreferenceRepository = (GuildPreferenceRepository) context.getBean("guildPreferenceRepository");
userRepository = (UserRepository) context.getBean("userRepository");
}
public ArrayList<GetSettingsData> extractSettings(Guild guild){
ArrayList<GetSettingsData> list = new ArrayList<>();
List<GuildPreferenceEntity> guildPrefList = guildPreferenceRepository.findByGuildId(guild.getId());
GuildPreferenceEntity guildPref;
if(guildPrefList.isEmpty()){
guildPref = GuildPreferenceEntity.getDefault(guild);
guildPreferenceRepository.save(guildPref);
}
else
guildPref = guildPrefList.get(0);
list.add(new GetSettingsData(
"Enable Welcome Message",
"welcome",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isWelcome())
));
list.add(new GetSettingsData(
"Welcome Message chanel",
"welcome_chanel_id",
GetSettingsData.TYPE.LIST,
getTextChannels(guild),
guildPref.getWelcomeChanelID()
));
list.add(new GetSettingsData(
"Welcome Message",
"welcome_message",
GetSettingsData.TYPE.STRING,
null,
guildPref.getWelcomeMessage()
));
list.add(new GetSettingsData(
"Enable Default Role",
"default_role",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isDefaultRole())
));
list.add(new GetSettingsData(
"Default Role",
"default_role_id",
GetSettingsData.TYPE.LIST,
getRoles(guild),
guildPref.getDefaultRoleId()
));
list.add(new GetSettingsData(
"Enable Anti Spam",
"anti_spam",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isAntiSpam())
));
list.add(new GetSettingsData(
"Enable Daily Madame Message",
"daily_madame",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isDailyMadame())
));
return list;
}
public boolean checkPermission(String token, String guild){
if(token == null || guild == null){
return false;
}
else{
try {
UserEntity user = UserUtils.getInstance().getUserWithApiToken(userRepository, token);
User jdaUser = MainBot.jda.getUserById(user.getJdaId());
Guild jdaGuild = MainBot.jda.getGuildById(guild);
if(jdaGuild == null){
return false;
}
if(!jdaGuild.getMember(jdaUser).hasPermission(Permission.ADMINISTRATOR)){
return false;
}
return true;
} catch (Exception e) {
logger.warn("Unknown Token! " + token);
return false;
}
}
}
private List<Value> getTextChannels(Guild guild){
List<Value> channels = new ArrayList<>();
for(TextChannel channel : guild.getTextChannels()){
channels.add(new Value(channel.getName(), channel.getId()));
}
return channels;
}
private List<Value> getRoles(Guild guild){
List<Value> roles = new ArrayList<>();
for(Role role : guild.getRoles()){
roles.add(new Value(role.getName(), role.getId()));
}
return roles;
}
}

View File

@ -6,13 +6,17 @@ import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.UserRepository; import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.RestApi.Commands.Play; import net.Broken.RestApi.Commands.Play;
import net.Broken.Tools.SettingsUtils;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -23,15 +27,20 @@ import java.util.List;
@Controller @Controller
public class GeneralWebView { public class GeneralWebView {
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {}
@RequestMapping("/") @RequestMapping("/")
public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId){ public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "") String token){
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null) if(guild != null)
model.addAttribute("guild_name", guild.getName()); model.addAttribute("guild_name", guild.getName());
else else
model.addAttribute("guild_name", ""); model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("index"); return CheckPage.getPageIfReady("index");
@ -51,6 +60,28 @@ public class GeneralWebView {
return "oauthCallback"; return "oauthCallback";
} }
@RequestMapping("/settings")
public String settings(Model model, @CookieValue(value = "guild", defaultValue = "") String guildId, @CookieValue(value = "token", defaultValue = "") String token){
SettingsUtils settingsUtils = SettingsUtils.getInstance();
if(settingsUtils.checkPermission(token, guildId)){
Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null)
model.addAttribute("guild_name", guild.getName());
else
model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("settings", SettingsUtils.getInstance().extractSettings(guild));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("settings");
}
else
throw new ForbiddenException();
}

View File

@ -1,6 +1,7 @@
package net.Broken.webView; package net.Broken.webView;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.Tools.SettingsUtils;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -13,14 +14,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
@Controller @Controller
public class MusicWebView { public class MusicWebView {
@RequestMapping("/music") @RequestMapping("/music")
public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId){ public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "1") String token){
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null) if(guild != null)
model.addAttribute("guild_name", guild.getName()); model.addAttribute("guild_name", guild.getName());
else else
model.addAttribute("guild_name", ""); model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("music"); return CheckPage.getPageIfReady("music");
} }

View File

@ -15,6 +15,8 @@ public class RegisterWebView {
public String music(@RequestParam(value="id", required = true, defaultValue = "") String id, Model model){ public String music(@RequestParam(value="id", required = true, defaultValue = "") String id, Model model){
model.addAttribute("id", id); model.addAttribute("id", id);
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin",false);
return CheckPage.getPageIfReady("register"); return CheckPage.getPageIfReady("register");
} }
} }

View File

@ -0,0 +1,3 @@
$(document).ready(function(){
$('select').formSelect();
});

View File

@ -12,7 +12,7 @@
<!-- LOGIN --> <!-- LOGIN -->
<!--__________________________________________________________--> <!--__________________________________________________________-->
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/> <link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<div th:fragment="header (page, guild_name, redirect_url)"> <div th:fragment="header (page, guild_name, redirect_url, isAdmin)">
<nav class="blue-grey darken-4 z-depth-3" role="navigation" > <nav class="blue-grey darken-4 z-depth-3" role="navigation" >
<div class="nav-wrapper container"> <div class="nav-wrapper container">
<a id="logo-container" href="/" class="brand-logo" style="white-space: nowrap">Claptrap Bot</a> <a id="logo-container" href="/" class="brand-logo" style="white-space: nowrap">Claptrap Bot</a>
@ -56,8 +56,12 @@
<a class="waves-effect waves-light" href="/music">Music Control</a> <a class="waves-effect waves-light" href="/music">Music Control</a>
</li> </li>
<li><div class="divider"></div></li> <li><div class="divider"></div></li>
<li><a class="center nav-change-guild">Change Guild</a></li> <li><a class="center nav-change-guild">Change Guild</a></li>
<li class="center bot-settings" th:classappend="(${page} == 'settings')? 'active' : ''" th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
<a class="waves-effect waves-light" href="/settings">Bot Settings</a>
</li>
<li> <li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a> <a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li> </li>
@ -82,6 +86,9 @@
</li> </li>
<li class="divider"></li> <li class="divider"></li>
<li><a class="center nav-change-guild" >Change Guild</a></li> <li><a class="center nav-change-guild" >Change Guild</a></li>
<li class="bot-settings" th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
<a class=" center waves-effect waves-light " href="/settings" >Bot Settings</a>
</li>
<li> <li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a> <a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li> </li>

View File

@ -20,7 +20,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('home',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="center center-align"> <div class="center center-align">

View File

@ -19,7 +19,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('music',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('music',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="row"> <div class="row">

View File

@ -19,7 +19,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('home',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="row center" > <div class="row center" >

View File

@ -16,7 +16,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('','',${redirect_url})">...</div> <div th:replace="header :: header ('','',${redirect_url},${isAdmin})">...</div>

View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Claptrap Bot</title>
<link rel="icon"
type="image/x-icon"
href="/favicon.png"/>
<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link rel="manifest" href="/manifest.json"/>
<meta name="theme-color" content="#263238"/>
</head>
<body class="blue-grey lighten-5" >
<!--/*@thymesVar id="guild_name" type="java.lang.String"*/-->
<!--/*@thymesVar id="redirect_url" type="java.lang.String"*/-->
<!--/*@thymesVar id="settings" type="java.util.ArrayList<net.Broken.RestApi.Data.Settings.GetSettingsData>"*/-->
<!--/*@thymesVar id="isAdmin" type="java.lang.Boolean"*/-->
<div th:replace="header :: header ('settings',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<div th:each="setting : ${settings}">
<div class="section row">
<div class="col l6 offset-l3 m10 offset-m1 s10 offset-s1">
<h5 th:text="${setting.name}" style="font-weight: bold"></h5>
<div class="switch" th:if="${setting.type.toString() == 'BOOL'}">
<label>
Off
<input type="checkbox" th:checked="${setting.current}"/>
<span class="lever"></span>
On
</label>
</div>
<div class="input-field col l12 m12 s12" th:if="${setting.type.toString() == 'LIST'}">
<select>
<option disabled="disabled" th:selected="${setting.current} == ' '" value="" >Choose your option</option>
<option th:each="val : ${setting.values}" th:value="${val.id}" th:text="${#strings.capitalize(val.name)}" th:selected="${setting.current} == ${val.id}"></option>
</select>
</div>
<div class="input-field col l12 m12 s12" th:if="${setting.type.toString() == 'STRING'}">
<input placeholder="Use @name variable" th:value="${setting.current}" id="first_name" type="text" class="validate"/>
</div>
</div>
</div>
<div class="row">
<div class="divider col l6 offset-l3"></div>
</div>
</div>
</div>
<script>
var needLogin = true;
</script>
<!-- Scripts-->
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
<script th:src="@{/js/materialize.js}"></script>
<script th:src="@{/js/navabar.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script th:src="@{/js/settings.js}"></script>
<script src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" crossorigin="anonymous"></script>
<script th:src="@{/js/workerRegister.js}"></script>
</body>
</html>