From b9762f6460d3916213c55bcc8d084517253ff17a Mon Sep 17 00:00:00 2001
From: kasperdt <45585490+kasperdt@users.noreply.github.com>
Date: Fri, 23 Oct 2020 23:51:40 +0200
Subject: [PATCH] test

---
 pom.xml                                       |  6 +++
 src/main/java/inf226/inchat/Account.java      | 16 ++++---
 .../java/inf226/inchat/AccountStorage.java    |  4 +-
 src/main/java/inf226/inchat/Handler.java      | 46 ++++++++++---------
 src/main/java/inf226/inchat/Password.java     | 33 +++++++++++++
 src/main/java/inf226/inchat/UserName.java     | 10 ++++
 6 files changed, 86 insertions(+), 29 deletions(-)
 create mode 100644 src/main/java/inf226/inchat/Password.java
 create mode 100644 src/main/java/inf226/inchat/UserName.java

diff --git a/pom.xml b/pom.xml
index 715d327..d553508 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,12 @@
         <artifactId>scrypt</artifactId>
         <version>1.4.0</version>
     </dependency>
+    <!-- https://mvnrepository.com/artifact/org.owasp.encoder/encoder -->
+    <dependency>
+        <groupId>org.owasp.encoder</groupId>
+        <artifactId>encoder</artifactId>
+        <version>1.2.2</version>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/src/main/java/inf226/inchat/Account.java b/src/main/java/inf226/inchat/Account.java
index 9bf2f4f..c3279ae 100644
--- a/src/main/java/inf226/inchat/Account.java
+++ b/src/main/java/inf226/inchat/Account.java
@@ -1,9 +1,11 @@
 package inf226.inchat;
+import com.lambdaworks.crypto.SCryptUtil;
 import inf226.util.immutable.List;
 import inf226.util.Pair;
 
 
 import inf226.storage.*;
+import org.eclipse.jetty.util.security.Password;
 
 /**
  * The Account class holds all information private to
@@ -18,11 +20,14 @@ public final class Account {
      */
     public final Stored<User> user;
     public final List<Pair<String,Stored<Channel>>> channels;
+    public final Password hashedPassword;
     
     public Account(Stored<User> user, 
-                   List<Pair<String,Stored<Channel>>> channels) {
+                   List<Pair<String,Stored<Channel>>> channels,
+                   Password hashedPassword) {
         this.user = user;
         this.channels = channels;
+        this.hashedPassword = hashedPassword;
     }
     
     /**
@@ -33,8 +38,8 @@ public final class Account {
      **/
     public static Account create(Stored<User> user,
                                  String password) {
-        // TODO: The password parameter is not used for anything.
-        return new Account(user,List.empty());
+        Password hashedPassword = new Password(SCryptUtil.scrypt(password,16384,8,1)); //
+        return new Account(user,List.empty(), hashedPassword);
     }
     
     /**
@@ -45,10 +50,7 @@ public final class Account {
     public Account joinChannel(String alias, Stored<Channel> channel) {
         Pair<String,Stored<Channel>> entry
             = new Pair<String,Stored<Channel>>(alias,channel);
-        return new Account
-                (user,
-                 List.cons(entry,
-                           channels));
+        return new Account(user, List.cons(entry, channels), hashedPassword);
     }
 
 
diff --git a/src/main/java/inf226/inchat/AccountStorage.java b/src/main/java/inf226/inchat/AccountStorage.java
index f90bdbf..6b20d47 100644
--- a/src/main/java/inf226/inchat/AccountStorage.java
+++ b/src/main/java/inf226/inchat/AccountStorage.java
@@ -11,6 +11,7 @@ import inf226.storage.*;
 
 import inf226.util.immutable.List;
 import inf226.util.*;
+import org.eclipse.jetty.util.security.Password;
 
 /**
  * This class stores accounts in the database.
@@ -149,6 +150,7 @@ public final class AccountStorage
             final Stored<User> user = userStore.get(userid);
             // Get all the channels associated with this account
             final List.Builder<Pair<String,Stored<Channel>>> channels = List.builder();
+            final String password = accountResult.getString("password");
             while(channelResult.next()) {
                 final UUID channelId = 
                     UUID.fromString(channelResult.getString("channel"));
@@ -157,7 +159,7 @@ public final class AccountStorage
                     new Pair<String,Stored<Channel>>(
                         alias,channelStore.get(channelId)));
             }
-            return (new Stored<Account>(new Account(user,channels.getList()),id,version));
+            return (new Stored<Account>(new Account(user,channels.getList(), new Password(password)),id,version));
         } else {
             throw new DeletedException();
         }
diff --git a/src/main/java/inf226/inchat/Handler.java b/src/main/java/inf226/inchat/Handler.java
index 45b4f6b..e5c456e 100644
--- a/src/main/java/inf226/inchat/Handler.java
+++ b/src/main/java/inf226/inchat/Handler.java
@@ -29,6 +29,10 @@ import inf226.storage.*;
 import inf226.inchat.*;
 import inf226.util.*;
 
+import org.owasp.encoder.Encode;
+
+
+
 /**
  * The Hanlder class handles all HTTP and HTML components.
  * Functions called display⋯ and print⋯ output HTML.
@@ -180,12 +184,12 @@ public class Handler extends AbstractHandler
                 
                 out.println("<!DOCTYPE html>");
                 out.println("<html lang=\"en-GB\">");
-                printStandardHead(out, "inChat: " + alias);
+                printStandardHead(out, "inChat: " + Encode.forHtml(alias));
                 out.println("<body>");
-                printStandardTop(out,  "inChat: " + alias);
+                printStandardTop(out,  "inChat: " + Encode.forHtml(alias));
                 out.println("<div class=\"main\">");
-                printChannelList(out, account.value, alias);
-                printChannel(out, channel, alias);
+                printChannelList(out, account.value, Encode.forHtml(alias));
+                printChannel(out, channel, Encode.forHtml(alias));
                 out.println("</div>");
                 out.println("</body>");
                 out.println("</html>");
@@ -215,7 +219,7 @@ public class Handler extends AbstractHandler
             if(target.equals("/joinChannel")) {
                 out.println("<!DOCTYPE html>");
                 out.println("<html lang=\"en-GB\">");
-                printStandardHead(out, "inChat: " + account.value.user.value.name);
+                printStandardHead(out, "inChat: " + Encode.forHtml(account.value.user.value.name));
                 out.println("<body>");
                 printStandardTop(out, "inChat – Join a channel!");
                 
@@ -243,11 +247,11 @@ public class Handler extends AbstractHandler
                 printStandardTop(out,  "inChat: Edit message");
                 out.println("<script src=\"/script.js\"></script>");
                 
-                out.println("<form class=\"entry\" action=\"/channel/" + alias + "\" method=\"post\">");
+                out.println("<form class=\"entry\" action=\"/channel/" + Encode.forHtml(alias) + "\" method=\"post\">");
                 out.println("  <div class=\"user\">You</div>");
                 out.println("  <input type=\"hidden\" name=\"editmessage\" value=\"Edit\">");
-                out.println("  <input type=\"hidden\" name=\"message\" value=\"" + messageid + "\">");
-                out.println("  <textarea id=\"messageInput\" class=\"messagebox\" placeholder=\"Post a message in this channel!\" name=\"content\">" + originalContent + "</textarea>");
+                out.println("  <input type=\"hidden\" name=\"message\" value=\"" + Encode.forHtml(messageid) + "\">");
+                out.println("  <textarea id=\"messageInput\" class=\"messagebox\" placeholder=\"Post a message in this channel!\" name=\"content\">" + Encode.forHtml(originalContent) + "</textarea>");
                 out.println("  <div class=\"controls\"><input style=\"float: right;\" type=\"submit\" name=\"edit\" value=\"Edit\"></div>");
                 out.println("</form>");
                 out.println("<script>");
@@ -346,9 +350,9 @@ public class Handler extends AbstractHandler
             if(target.equals("/")) {
                 out.println("<!DOCTYPE html>");
                 out.println("<html lang=\"en-GB\">");
-                printStandardHead(out, "inChat: " + account.value.user.value.name);
+                printStandardHead(out, "inChat: " + Encode.forHtml(account.value.user.value.name));
                 out.println("<body>");
-                printStandardTop(out, "inChat: " + account.value.user.value.name);
+                printStandardTop(out, "inChat: " + Encode.forHtml(account.value.user.value.name));
                 out.println("<div class=\"main\">");
                 printChannelList(out, account.value, "");
                 out.println("<div class=\"channel\">Hello!</div>");
@@ -395,7 +399,7 @@ public class Handler extends AbstractHandler
         out.println("<style type=\"text/css\">code{white-space: pre;}</style>");
         out.println("<link rel=\"stylesheet\" href=\"/style.css\">");
         
-        out.println("<title>" + title + "</title>");
+        out.println("<title>" + Encode.forHtml(title) + "</title>");
         out.println("</head>");
     }
 
@@ -403,7 +407,7 @@ public class Handler extends AbstractHandler
      * Print the standard top with actions.
      */
     private void printStandardTop(PrintWriter out, String topic) {
-        out.println("<h1 class=\"topic\"><a style=\"color: black;\" href=\"/\">"+ topic + "</a></h1>");
+        out.println("<h1 class=\"topic\"><a style=\"color: black;\" href=\"/\">"+ Encode.forHtml(topic) + "</a></h1>");
         out.println("<div class=\"actionbar\">");
         out.println("<a class=\"action\" href=\"/create\">Create a channel!</a>");
         out.println("<a class=\"action\" href=\"/joinChannel\">Join a channel!</a>");
@@ -419,7 +423,7 @@ public class Handler extends AbstractHandler
         out.println("<p>Your channels:</p>");
         out.println("<ul class=\"chanlist\">");
         account.channels.forEach( entry -> {
-            out.println("<li> <a href=\"/channel/" + entry.first + "\">" + entry.first + "</a></li>");
+            out.println("<li> <a href=\"/channel/" + Encode.forHtml(entry.first) + "\">" + Encode.forHtml(entry.first) + "</a></li>");
         });
         out.println("</ul>");
         out.println("</aside>");
@@ -437,7 +441,7 @@ public class Handler extends AbstractHandler
         out.println("<script src=\"/script.js\"></script>");
         out.println("<script>subscribe(\"" + channel.identity +"\",\"" + channel.version + "\");</script>");
         
-        out.println("<form class=\"entry\" action=\"/channel/" + alias + "\" method=\"post\">");
+        out.println("<form class=\"entry\" action=\"/channel/" + Encode.forHtml(alias) + "\" method=\"post\">");
         out.println("  <div class=\"user\">You</div>");
         out.println("  <input type=\"hidden\" name=\"newmessage\" value=\"Send\">");
         out.println("  <textarea id=\"messageInput\" class=\"messagebox\" placeholder=\"Post a message in this channel!\" name=\"message\"></textarea>");
@@ -454,7 +458,7 @@ public class Handler extends AbstractHandler
         out.println("<h4>Channel ID:</h4><br>" + channel.identity +"<br>");
         out.println("<p><a href=\"/join?channelid=" + channel.identity + "\">Join link</a></p>");
 
-        out.println("<h4>Set permissions</h4><form action=\"/channel/" + alias + "\" method=\"post\">");
+        out.println("<h4>Set permissions</h4><form action=\"/channel/" + Encode.forHtml(alias) + "\" method=\"post\">");
         out.println("<input style=\"width: 8em;\" type=\"text\" placeholder=\"User name\" name=\"username\">");
         out.println("<select name=\"role\" required=\"required\">");
         out.println("<option value=\"owner\">Owner</option>");
@@ -490,25 +494,25 @@ public class Handler extends AbstractHandler
             switch(e.value.type) {
                 case message:
                     out.println("<div class=\"entry\">");
-                    out.println("    <div class=\"user\">" + e.value.sender + "</div>");
-                    out.println("    <div class=\"text\">" + e.value.message);
+                    out.println("    <div class=\"user\">" + Encode.forHtml(e.value.sender)+ "</div>");
+                    out.println("    <div class=\"text\">" + Encode.forHtml(e.value.message));
                     out.println("    </div>");
                     out.println("    <div class=\"messagecontrols\">");
-                    out.println("        <form style=\"grid-area: delete;\" action=\"/channel/" + channel.value.name + "\" method=\"POST\">");
+                    out.println("        <form style=\"grid-area: delete;\" action=\"/channel/" + Encode.forHtml(channel.value.name) + "\" method=\"POST\">");
                     out.println("        <input type=\"hidden\" name=\"message\" value=\""+ e.identity + "\">");
                     out.println("        <input type=\"submit\" name=\"deletemessage\" value=\"Delete\">");
                     out.println("        </form><form style=\"grid-area: edit;\" action=\"/editMessage\" method=\"POST\">");
                     out.println("        ");
                     out.println("        <input type=\"hidden\" name=\"message\" value=\""+ e.identity + "\">");
-                    out.println("        <input type=\"hidden\" name=\"channelname\" value=\""+ channel.value.name + "\">");
-                    out.println("        <input type=\"hidden\" name=\"originalcontent\" value=\""+ e.value.message + "\">");
+                    out.println("        <input type=\"hidden\" name=\"channelname\" value=\""+ Encode.forHtml(channel.value.name) + "\">");
+                    out.println("        <input type=\"hidden\" name=\"originalcontent\" value=\""+ Encode.forHtml(e.value.message) + "\">");
                     out.println("        <input type=\"submit\" name=\"editmessage\" value=\"Edit\">");
                     out.println("        </form>");
                     out.println("    </div>");
                     out.println("</div>");
                     return;
                 case join:
-                    out.println("<p>" + formatter.format(e.value.time) + " " + e.value.sender + " has joined!</p>");
+                    out.println("<p>" + Encode.forHtml(formatter.format(e.value.time)) + " " + Encode.forHtml(e.value.sender) + " has joined!</p>");
                     return;
             }
         });
diff --git a/src/main/java/inf226/inchat/Password.java b/src/main/java/inf226/inchat/Password.java
new file mode 100644
index 0000000..3a6f073
--- /dev/null
+++ b/src/main/java/inf226/inchat/Password.java
@@ -0,0 +1,33 @@
+package inf226.inchat;
+
+public final class Password {
+
+    public final String password;
+
+    public Password(String password) {
+        this.password = password;
+    }
+
+    public boolean validPassword (String password) {
+        int hPLength = password.length();
+        if (hPLength >= 6 && hPLength <= 30) {
+            int digits, upperCases, lowerCases;
+            digits = upperCases = lowerCases = 0;
+            for (char c : password.toCharArray()) {
+                if (Character.isDigit(c)) {
+                    digits++;
+                }
+                if (Character.isUpperCase(c)) {
+                    upperCases++;
+                }
+                if (Character.isLowerCase(c)) {
+                    lowerCases++;
+                }
+            }
+            if (digits != 0 && upperCases != 0 && lowerCases != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/main/java/inf226/inchat/UserName.java b/src/main/java/inf226/inchat/UserName.java
new file mode 100644
index 0000000..041e7c8
--- /dev/null
+++ b/src/main/java/inf226/inchat/UserName.java
@@ -0,0 +1,10 @@
+package inf226.inchat;
+
+public final class UserName {
+
+    private final String username;
+
+    public UserName(String uName) {
+        this.username = uName;
+    }
+}
-- 
GitLab