Implement JWT, registration, login and comment posting
This is still a demo, to learn the framework. Most of this will probably we rewritten more elengantly.
This commit is contained in:
parent
c0d8243016
commit
855bf817e1
5
pom.xml
5
pom.xml
@ -40,6 +40,11 @@
|
||||
<artifactId>pippo-jetty</artifactId>
|
||||
<version>1.13.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>3.10.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.mindoverflow.comments;
|
||||
|
||||
import net.mindoverflow.comments.webapp.WebServer;
|
||||
import ro.pippo.core.Pippo;
|
||||
|
||||
public class CommentingServer
|
||||
|
@ -1,63 +0,0 @@
|
||||
package net.mindoverflow.comments;
|
||||
|
||||
import ro.pippo.core.Application;
|
||||
import ro.pippo.core.route.TrailingSlashHandler;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
public class WebServer extends Application
|
||||
{
|
||||
|
||||
String username = "lollo";
|
||||
String userpass = "password";
|
||||
|
||||
@Override
|
||||
public void onInit()
|
||||
{
|
||||
|
||||
POST("/login", routeContext -> {
|
||||
System.out.println("POST");
|
||||
|
||||
String name = routeContext.getParameter("username").toString();
|
||||
System.out.println(name);
|
||||
|
||||
String password = routeContext.getParameter("password").toString();
|
||||
System.out.println(password);
|
||||
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
|
||||
if(name.isEmpty())
|
||||
{
|
||||
model.put("errorMessage", "Empty username!");
|
||||
}
|
||||
else if (password.isEmpty())
|
||||
{
|
||||
model.put("errorMessage", "Empty password!");
|
||||
}
|
||||
else if(!name.equals(username) || !password.equals(userpass))
|
||||
{
|
||||
model.put("errorMessage", "Wrong username or password!");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
model.put("errorMessage", "Logged in!");
|
||||
}
|
||||
|
||||
|
||||
routeContext.render("login", model);
|
||||
|
||||
});
|
||||
|
||||
GET("/login", routeContext ->
|
||||
{
|
||||
System.out.println("GET");
|
||||
|
||||
routeContext.render("login");
|
||||
});
|
||||
|
||||
ANY("/.*", new TrailingSlashHandler(false)); // remove trailing slash
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package net.mindoverflow.comments.utils;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
public class SecurityUtil
|
||||
{
|
||||
public static final int JWT_EXPIRY_MINUTES = 60;
|
||||
|
||||
public static String generateJWT(String claimName, String claimValue, Date expiry)
|
||||
{
|
||||
|
||||
Algorithm algorithm = Algorithm.HMAC256("minafewnf0928f392".getBytes(StandardCharsets.UTF_8));
|
||||
return JWT.create()
|
||||
.withIssuer("CommentingServer")
|
||||
.withClaim(claimName, claimValue)
|
||||
.withExpiresAt(expiry)
|
||||
.sign(algorithm);
|
||||
}
|
||||
|
||||
public static String generateJWT(String claimName, String claimValue)
|
||||
{
|
||||
Date expiry = Date.from(ZonedDateTime.now().plusMinutes(JWT_EXPIRY_MINUTES).toInstant());
|
||||
return generateJWT(claimName, claimValue, expiry);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package net.mindoverflow.comments.webapp;
|
||||
|
||||
import net.mindoverflow.comments.webapp.controllers.CommentController;
|
||||
import net.mindoverflow.comments.webapp.controllers.CommentsController;
|
||||
import net.mindoverflow.comments.webapp.controllers.LoginController;
|
||||
import net.mindoverflow.comments.webapp.controllers.RegisterController;
|
||||
import ro.pippo.controller.ControllerApplication;
|
||||
import ro.pippo.core.route.TrailingSlashHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WebServer extends ControllerApplication
|
||||
{
|
||||
|
||||
public static final HashMap<String, String> userAndPassword = new HashMap<>();
|
||||
public static final HashMap<String, String> jwtAndUser = new HashMap<>();
|
||||
public static final HashMap<String, String> userAndComment = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onInit()
|
||||
{
|
||||
|
||||
addControllers(new LoginController(), new RegisterController(), new CommentsController(), new CommentController());
|
||||
|
||||
ANY("/.*", new TrailingSlashHandler(false)); // remove trailing slash
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package net.mindoverflow.comments.webapp.controllers;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import net.mindoverflow.comments.webapp.WebServer;
|
||||
import ro.pippo.controller.Controller;
|
||||
import ro.pippo.controller.GET;
|
||||
import ro.pippo.controller.POST;
|
||||
import ro.pippo.controller.Path;
|
||||
import ro.pippo.controller.extractor.Param;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/comment")
|
||||
public class CommentController extends Controller
|
||||
{
|
||||
|
||||
@GET
|
||||
public void getCommentPage()
|
||||
{
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
getRouteContext().render("comment", model);
|
||||
}
|
||||
|
||||
@POST
|
||||
public void addComment(@Param("comment") String comment, @Param("commentbtn") String commentbtn)
|
||||
{
|
||||
Cookie session = getRequest().getCookie("session");
|
||||
if(session == null)
|
||||
{
|
||||
System.out.println("null cookie");
|
||||
return;
|
||||
}
|
||||
|
||||
String jwtFromCookie = session.getValue();
|
||||
if(jwtFromCookie == null)
|
||||
{
|
||||
System.out.println("null jwt");
|
||||
return;
|
||||
}
|
||||
|
||||
String username = WebServer.jwtAndUser.get(jwtFromCookie);
|
||||
if(username == null)
|
||||
{
|
||||
System.out.println("null user");
|
||||
return;
|
||||
}
|
||||
|
||||
// check if jwt is null, if saved in hashmap, and finally verify it with JWT.verify()
|
||||
|
||||
if(commentbtn != null)
|
||||
{
|
||||
WebServer.userAndComment.put(username, comment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package net.mindoverflow.comments.webapp.controllers;
|
||||
|
||||
import net.mindoverflow.comments.webapp.WebServer;
|
||||
import ro.pippo.controller.Controller;
|
||||
import ro.pippo.controller.GET;
|
||||
import ro.pippo.controller.Path;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/comments")
|
||||
public class CommentsController extends Controller
|
||||
{
|
||||
|
||||
@GET
|
||||
public void getComments()
|
||||
{
|
||||
List<String> lines = new ArrayList<>();
|
||||
lines.add("Comments:");
|
||||
|
||||
for(String user : WebServer.userAndComment.keySet())
|
||||
{
|
||||
String comment = WebServer.userAndComment.get(user);
|
||||
if(comment != null) lines.add(user + ": " + comment);
|
||||
}
|
||||
|
||||
getRouteContext().text().send(lines);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package net.mindoverflow.comments.webapp.controllers;
|
||||
|
||||
import net.mindoverflow.comments.utils.SecurityUtil;
|
||||
import net.mindoverflow.comments.webapp.WebServer;
|
||||
import ro.pippo.controller.Controller;
|
||||
import ro.pippo.controller.GET;
|
||||
import ro.pippo.controller.POST;
|
||||
import ro.pippo.controller.Path;
|
||||
import ro.pippo.controller.extractor.Param;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/login")
|
||||
public class LoginController extends Controller
|
||||
{
|
||||
|
||||
@GET
|
||||
public void getLogin()
|
||||
{
|
||||
getRouteContext().render("login");
|
||||
}
|
||||
|
||||
@POST
|
||||
public void handleLogin(
|
||||
@Param("loginbtn") String loginbtn,
|
||||
@Param("username") String username,
|
||||
@Param("password") String password)
|
||||
{
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
|
||||
if(username == null || username.isEmpty())
|
||||
{
|
||||
model.put("message", "Empty username!");
|
||||
}
|
||||
else if (password == null || password.isEmpty())
|
||||
{
|
||||
model.put("message", "Empty password!");
|
||||
} else if(loginbtn != null)
|
||||
{
|
||||
System.out.println(loginbtn);
|
||||
|
||||
if(!WebServer.userAndPassword.containsKey(username))
|
||||
{
|
||||
model.put("message", "Unknown user!");
|
||||
}
|
||||
else
|
||||
{
|
||||
String gottenPass = WebServer.userAndPassword.get(username);
|
||||
if(!gottenPass.equals(password))
|
||||
{
|
||||
model.put("message", "Wrong password!");
|
||||
}
|
||||
else
|
||||
{
|
||||
model.put("message", "Valid data!");
|
||||
|
||||
// generate JWT
|
||||
String jwt = SecurityUtil.generateJWT("username", username);
|
||||
|
||||
// set JWT as cookie
|
||||
getResponse().cookie("session", jwt, SecurityUtil.JWT_EXPIRY_MINUTES * 60 /* in seconds */);
|
||||
|
||||
// store JWT in RAM
|
||||
WebServer.jwtAndUser.put(jwt, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("User: " + username);
|
||||
System.out.println("Pass: " + password);
|
||||
|
||||
getRouteContext().render("login", model);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.mindoverflow.comments.webapp.controllers;
|
||||
|
||||
import net.mindoverflow.comments.webapp.WebServer;
|
||||
import ro.pippo.controller.Controller;
|
||||
import ro.pippo.controller.GET;
|
||||
import ro.pippo.controller.POST;
|
||||
import ro.pippo.controller.Path;
|
||||
import ro.pippo.controller.extractor.Param;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/register")
|
||||
public class RegisterController extends Controller
|
||||
{
|
||||
|
||||
@GET
|
||||
public void getLogin()
|
||||
{
|
||||
getRouteContext().render("register");
|
||||
}
|
||||
|
||||
@POST
|
||||
public void handleLogin(
|
||||
@Param("registerbtn") String registerbtn,
|
||||
@Param("username") String username,
|
||||
@Param("password") String password)
|
||||
{
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
|
||||
if(username == null || username.isEmpty())
|
||||
{
|
||||
model.put("message", "Empty username!");
|
||||
}
|
||||
else if (password == null || password.isEmpty())
|
||||
{
|
||||
model.put("message", "Empty password!");
|
||||
}
|
||||
else if(registerbtn != null)
|
||||
{
|
||||
System.out.println(registerbtn);
|
||||
|
||||
if(WebServer.userAndPassword.containsKey(username))
|
||||
{
|
||||
model.put("message", "User already exists!");
|
||||
}
|
||||
else
|
||||
{
|
||||
WebServer.userAndPassword.put(username, password);
|
||||
model.put("message", "User created!");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("User: " + username);
|
||||
System.out.println("Pass: " + password);
|
||||
|
||||
|
||||
getRouteContext().render("register", model);
|
||||
}
|
||||
|
||||
}
|
12
src/main/resources/templates/comment.ftl
Normal file
12
src/main/resources/templates/comment.ftl
Normal file
@ -0,0 +1,12 @@
|
||||
<htmml>
|
||||
<head>
|
||||
<title>Send Comment</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Send Comment</h1>
|
||||
<form accept-charset="UTF-8" role="form" method="post" action="/comment">
|
||||
<input placeholder="Comment" name="comment">
|
||||
<input class="btn btn-success btn-block" type="submit" name="commentbtn" value="Comment">
|
||||
</form>
|
||||
</body>
|
||||
</htmml>
|
@ -4,11 +4,11 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>Login Form</h1>
|
||||
<div><#if errorMessage??>${errorMessage}</#if></div>
|
||||
<div><#if message??>${message}</#if></div>
|
||||
<form accept-charset="UTF-8" role="form" method="post" action="/login">
|
||||
<input placeholder="Username" name="username">
|
||||
<input placeholder="Password" name="password" type="password">
|
||||
<input class="btn btn-success btn-block" type="submit" value="Login">
|
||||
<input class="btn btn-success btn-block" type="submit" name="loginbtn" value="Login">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
14
src/main/resources/templates/register.ftl
Normal file
14
src/main/resources/templates/register.ftl
Normal file
@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Register</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Registration Form</h1>
|
||||
<div><#if message??>${message}</#if></div>
|
||||
<form accept-charset="UTF-8" role="form" method="post" action="/register">
|
||||
<input placeholder="Username" name="username">
|
||||
<input placeholder="Password" name="password" type="password">
|
||||
<input class="btn btn-success btn-block" type="submit" name="registerbtn" value="Register">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user