From d27fa84ab437a446690b4f20067acf41e36f0764 Mon Sep 17 00:00:00 2001 From: MatMasIt <34745996+MatMasIt@users.noreply.github.com> Date: Thu, 17 Jun 2021 01:47:29 +0200 Subject: [PATCH] Add files via upload --- README.md | 25 ++ WallPost/WallPost.iml | 11 + WallPost/src/HeaderNotFoundException.java | 5 + WallPost/src/Post.java | 35 +++ WallPost/src/PostList.java | 5 + WallPost/src/ServerConnection.java | 230 +++++++++++++++++ WallPost/src/ServerErrorException.java | 13 + WallPost/src/Window.java | 231 ++++++++++++++++++ WallPostServer/WallPostServer.iml | 11 + .../WallPostServer_jar/WallPostServer.jar | Bin 0 -> 10052 bytes .../WallPostServer/META-INF/MANIFEST.MF | 3 + .../src/HeaderNotFoundException.java | 5 + WallPostServer/src/META-INF/MANIFEST.MF | 3 + WallPostServer/src/PermanentSorage.java | 73 ++++++ WallPostServer/src/Post.java | 37 +++ WallPostServer/src/PostList.java | 18 ++ WallPostServer/src/SaveContainer.java | 27 ++ WallPostServer/src/ServerThread.java | 201 +++++++++++++++ WallPostServer/src/User.java | 25 ++ WallPostServer/src/UserList.java | 24 ++ WallPostServer/src/WallPostServer.java | 34 +++ 21 files changed, 1016 insertions(+) create mode 100644 README.md create mode 100644 WallPost/WallPost.iml create mode 100644 WallPost/src/HeaderNotFoundException.java create mode 100644 WallPost/src/Post.java create mode 100644 WallPost/src/PostList.java create mode 100644 WallPost/src/ServerConnection.java create mode 100644 WallPost/src/ServerErrorException.java create mode 100644 WallPost/src/Window.java create mode 100644 WallPostServer/WallPostServer.iml create mode 100644 WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar create mode 100644 WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF create mode 100644 WallPostServer/src/HeaderNotFoundException.java create mode 100644 WallPostServer/src/META-INF/MANIFEST.MF create mode 100644 WallPostServer/src/PermanentSorage.java create mode 100644 WallPostServer/src/Post.java create mode 100644 WallPostServer/src/PostList.java create mode 100644 WallPostServer/src/SaveContainer.java create mode 100644 WallPostServer/src/ServerThread.java create mode 100644 WallPostServer/src/User.java create mode 100644 WallPostServer/src/UserList.java create mode 100644 WallPostServer/src/WallPostServer.java diff --git a/README.md b/README.md new file mode 100644 index 0000000..60d2c8b --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# WallPost + +A Java Swing application which allows to post articles on a remote "wall" + +Includes: + +* SignUp/SignIn +* Posting stories +* Reading stories +* Multi-threaded server +* State persistence + +Employs a custom protocol in communication ("FOLLOWS protocol" to exchange variables) + + + +> **Notice** +> This is just a demonstrative application +> It lacks basic functionalities as editing and upvoting, and relies on terrible storage and authentication, in fact it does not even use SSL or TLS +> Be aware of this + + + +* WallPost: The client +* WallPostServer: The server \ No newline at end of file diff --git a/WallPost/WallPost.iml b/WallPost/WallPost.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/WallPost/WallPost.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/WallPost/src/HeaderNotFoundException.java b/WallPost/src/HeaderNotFoundException.java new file mode 100644 index 0000000..07c7fa6 --- /dev/null +++ b/WallPost/src/HeaderNotFoundException.java @@ -0,0 +1,5 @@ +public class HeaderNotFoundException extends Exception{ + public HeaderNotFoundException(){ + super("Header not found"); + } +} diff --git a/WallPost/src/Post.java b/WallPost/src/Post.java new file mode 100644 index 0000000..e499584 --- /dev/null +++ b/WallPost/src/Post.java @@ -0,0 +1,35 @@ +public class Post { + public String getTitle() { + return title; + } + + public String getBody() { + return body; + } + + public String getAuthor() { + return author; + } + + public String getDate() { + return date; + } + + public int getId() { + return id; + } + + private String title, body,author, date; + private int id; + public void setBody(String body) { + this.body = body; + } + + public Post(String title, String body, String author, String date, int id){ + this.title=title; + this.body=body; + this.author=author; + this.date=date; + this.id=id; + } +} diff --git a/WallPost/src/PostList.java b/WallPost/src/PostList.java new file mode 100644 index 0000000..24bed3b --- /dev/null +++ b/WallPost/src/PostList.java @@ -0,0 +1,5 @@ +import java.util.ArrayList; + +public class PostList extends ArrayList{ + +} diff --git a/WallPost/src/ServerConnection.java b/WallPost/src/ServerConnection.java new file mode 100644 index 0000000..6a63b45 --- /dev/null +++ b/WallPost/src/ServerConnection.java @@ -0,0 +1,230 @@ +import javax.swing.*; +import java.io.*; +import java.lang.reflect.Array; +import java.net.Socket; +import java.rmi.ServerError; +import java.util.ArrayList; + +public class ServerConnection { + private Socket socket; + private InputStreamReader i; + private BufferedReader in; + private OutputStreamWriter osw; + private BufferedWriter bw; + private PrintWriter out; + private ArrayList headers=new ArrayList(); + private ArrayList values=new ArrayList(); + private JFrame window; + public ServerConnection(JFrame window) throws IOException { + this.window=window; + socket= new Socket("mascmt.ddns.net",70); + i= new InputStreamReader(socket.getInputStream()); + in = new BufferedReader(i); + osw= new OutputStreamWriter(socket.getOutputStream()); + bw =new BufferedWriter(osw); + out= new PrintWriter(bw, true); + out.println("HELLO"); + } + public ArrayList> sendData(String action) throws IOException, ServerErrorException {//lenght of Arralist[] is 2 as in headers, values + ArrayList> hv=new ArrayList>(); + hv.add(new ArrayList()); + hv.add(new ArrayList()); + out.println("HELLO AGAIN"); + out.println("ACTION " + action); + for (int c = 0; c < headers.size(); c++) { + out.println("FOLLOWS " + headers.get(c).replaceAll("FOLLOWS","follows").replaceAll("END","end")); + out.println(values.get(c).replaceAll("FOLLOWS","follows").replaceAll("END","end")); + } + out.println("END"); + String line="",temp=""; + if(in.readLine().equals("ERROR")){ + while(true){ + line=in.readLine(); + if(line.equals("END")){ + String title=in.readLine(); + String type=in.readLine(); + + if(in.readLine().equals("QUIT")){ + throw new ServerErrorException(title,temp,in.readLine(),true); + } + else{ + throw new ServerErrorException(title,temp,in.readLine(),false); + } + } + else{ + + temp+=line; + } + } + } + int flNum=0; + do{ + line=in.readLine(); + if(line.startsWith("FOLLOWS")){ + hv.get(0).add(line.split(" ",2)[1]); + if(flNum!=0){ + hv.get(1).add(temp); + } + temp=""; + flNum++; + } + else if(line.equals("END")){ + hv.get(1).add(temp); + } + else{ + temp+=line; + } + + }while (!line.equals("END")); + return hv; + } + public void init(){ + headers.clear(); + values.clear(); + } + public void bindParam(String h,String v){ + headers.add(h); + values.add(v); + } + + public ArrayList> handledGetData(String action){ + ArrayList> s=new ArrayList>(2); + try { + s=this.sendData(action); + } catch (IOException e) { + JOptionPane.showMessageDialog(window, + "Connection error", + "Could not connect to the server", + JOptionPane.ERROR_MESSAGE); + } catch (ServerErrorException e) { + handleServerErrorInGUI(e.title,e.message,e.errorType,e.mustQuit); + } + System.out.println(s.toString()); + return s; + } + + public void handleServerErrorInGUI(String title, String text, String type, boolean mustQuit){ + if(type.equals("INFO")){ + JOptionPane.showMessageDialog(this.window, title, text,JOptionPane.INFORMATION_MESSAGE); + + } + else if(type.equals("WARNING")){ + JOptionPane.showMessageDialog(this.window, + title, + text, + JOptionPane.WARNING_MESSAGE); + + + } + else if(type.equals("PLAIN")){ + JOptionPane.showMessageDialog(this.window, + title, + text, + JOptionPane.PLAIN_MESSAGE); + + + } + else{//ERROR + JOptionPane.showMessageDialog(this.window, + title, + text, + JOptionPane.ERROR_MESSAGE); + + } + if(mustQuit) { + System.exit(1); + } + } + public String valueByHeader(ArrayList> resp,String header) throws HeaderNotFoundException { + for(int i=0;i> li= this.handledGetData("signIn"); + try { + return this.valueByHeader(li,"status").trim().equals("OK"); + } catch (HeaderNotFoundException e) { + return false; + } + } + public boolean signUp(String username, String password){ + this.init(); + this.bindParam("username",username); + this.bindParam("password",password); + ArrayList> li= this.handledGetData("signUp"); + + try { + return this.valueByHeader(li,"status").trim().equals("OK"); + } catch (HeaderNotFoundException e) { + return false; + } + } + public PostList fetchPostsFromServer(){ + this.init(); + ArrayList> li =this.handledGetData("listPosts"); + PostList p= new PostList(); + int count=0; + for(int i=0; i> li=this.handledGetData("getPostBody"); + String body=""; + try { + body=this.valueByHeader(li,"body"); + } catch (HeaderNotFoundException e) { + body="An error occurred while loading the post"; + } + a.setBody(body); + list.set(index,a); + } + return a; + } + public void publishPost(String title,String body){ + this.init(); + this.bindParam("POST-Title",title); + this.bindParam("POST-Body",body); + this.handledGetData("sendPost"); + } + /* + NOT SUPPORTED BY SERVER + @Deprecated + public Post getPost(int Id) throws HeaderNotFoundException { + this.init(); + this.bindParam("POST-Id",String.valueOf(Id)); + ArrayList> li=this.handledGetData("getPost"); + Post p= new Post(this.valueByHeader(li,"POST-Title"),this.valueByHeader(li,"POST-Body"),this.valueByHeader(li,"POST-Author"),this.valueByHeader(li,"POST-Date"),Integer.parseInt(this.valueByHeader(li,"POST-Id"))); + return p; + } + + */ + +} diff --git a/WallPost/src/ServerErrorException.java b/WallPost/src/ServerErrorException.java new file mode 100644 index 0000000..596078a --- /dev/null +++ b/WallPost/src/ServerErrorException.java @@ -0,0 +1,13 @@ +import javax.swing.*; + +public class ServerErrorException extends Exception{ + public String message,errorType, title; + public boolean mustQuit; + public ServerErrorException(String title, String message, String errorType, boolean mustQuit){ + super("The server issued an error"); + this.message=message; + this.title=title; + this.errorType = errorType; + this.mustQuit=mustQuit; + } +} diff --git a/WallPost/src/Window.java b/WallPost/src/Window.java new file mode 100644 index 0000000..2a877d9 --- /dev/null +++ b/WallPost/src/Window.java @@ -0,0 +1,231 @@ +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.io.IOException; + +public class Window extends JFrame implements ActionListener { + private JPanel auth, list, viewOne, mine; + private JLabel labelUsername, labelPassword, postHeader; + private JTextField username, titleField; + private JPasswordField password; + private JButton signIn, signUp, make, send, backList,backList2; + private JScrollPane TablePane, textViewPane, textEditPane,postHeaderPane; + private JTable table; + private JTextArea view, write; + private DefaultTableModel tb; + private ServerConnection server; + private PostList PL; + private Post CP; + public Window() throws IOException { + initComponents(); + server= new ServerConnection(this); + PL=null; + } + public void initComponents(){ + + auth=new JPanel(); + labelUsername= new JLabel("Username"); + labelPassword=new JLabel("Password"); + username = new JTextField(15); + password = new JPasswordField(15); + signIn=new JButton("Sign In"); + signUp=new JButton("Sign Up"); + auth.setLayout(new GridLayout(3,2)); + + + auth.add(labelUsername); + auth.add(username); + + auth.add(labelPassword); + auth.add(password); + + auth.add(signIn); + + auth.add(signUp); + + + list=new JPanel(); + Object[][] data = {}; + String[] columnNames = {"User","Title","Date"}; + tb=new DefaultTableModel(data,columnNames); + table = new JTable(tb); + TablePane= new JScrollPane(table); + make=new JButton("Write"); + + list.setLayout(new GridLayout(2,1)); + + list.add(TablePane); + list.add(make); + + send= new JButton("Send"); + + this.setLayout(new FlowLayout()); + //this.add(list,new GridBagConstraints()); + viewOne= new JPanel(); + view= new JTextArea(15,50); + backList2= new JButton("Back To list"); + textViewPane= new JScrollPane(view); + postHeader=new JLabel("Title, details"); + postHeaderPane=new JScrollPane(postHeader, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + viewOne.setLayout(new GridLayout(3,1)); + + viewOne.add(postHeaderPane); + viewOne.add(textViewPane); + viewOne.add(backList2); + + mine=new JPanel(); + titleField=new JTextField(15); + titleField.setForeground(Color.GRAY); + titleField.setText("Title"); + titleField.setForeground(Color.GRAY); + titleField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + if (titleField.getText().equals("Title")) { + titleField.setText(""); + titleField.setForeground(Color.BLACK); + } + } + @Override + public void focusLost(FocusEvent e) { + if (titleField.getText().isEmpty()) { + titleField.setForeground(Color.GRAY); + titleField.setText("Title"); + } + } + }); + write=new JTextArea(15,50); + write.setForeground(Color.GRAY); + write.setText("Body"); + write.setForeground(Color.GRAY); + write.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + if (write.getText().equals("Body")) { + write.setText(""); + write.setForeground(Color.BLACK); + } + } + @Override + public void focusLost(FocusEvent e) { + if (write.getText().isEmpty()) { + write.setForeground(Color.GRAY); + write.setText("Body"); + } + } + }); + + textEditPane= new JScrollPane(write); + + backList= new JButton("Back To list"); + mine.setLayout(new GridLayout(4,1)); + mine.add(titleField); + mine.add(textEditPane); + mine.add(send); + mine.add(backList); + + + signIn.addActionListener(this); + signUp.addActionListener(this); + make.addActionListener(this); + backList.addActionListener(this); + backList2.addActionListener(this); + send.addActionListener(this); + + this.add(auth); + this.add(list); + this.add(viewOne); + this.add(mine); + list.setVisible(false); + viewOne.setVisible(false); + mine.setVisible(false); + //this.add(auth,new GridBagConstraints()); + table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ + public void valueChanged(ListSelectionEvent event) { + // do some actions here, for example + // print first column value from selected row + CP=server.fetchPostBodyIfEmpty(PL,table.getSelectedRow()); + if (CP!= null) { + + + postHeader.setText(CP.getTitle() + ", written by " + CP.getAuthor() + " at " + CP.getDate()); + view.setText(CP.getBody()); + list.setVisible(false); + viewOne.setVisible(true); + } + } + }); + } + public static void main(String args[]) throws IOException { + Window window= new Window(); + window.setSize(600,1000); + window.setTitle("WallPost"); + window.setVisible(true); + } + + public void updateTable(PostList a) { + tb.setRowCount(0);//Imposta il numero di righe a 0 eliminando tutte le righe presenti + for (int i = 0; i < a.size(); i++) { + Object[] row = {a.get(i).getAuthor(),a.get(i).getTitle(), a.get(i).getDate()};//Crea riga temporanea + tb.addRow(row);//aggiungi riga + } + } + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource().equals(signIn)){ + if(server.signIn(username.getText(),new String(password.getPassword()))) { + PL=server.fetchPostsFromServer(); + this.updateTable(PL); + auth.setVisible(false); + list.setVisible(true); + } + else{ + JOptionPane.showMessageDialog(this, + "Wrong credentials", + "Cannot sign in", + JOptionPane.WARNING_MESSAGE); + } + } + else if(e.getSource().equals(signUp)){ + if(server.signUp(username.getText(),new String(password.getPassword()))) { + updt(); + auth.setVisible(false); + list.setVisible(true); + } + else{ + JOptionPane.showMessageDialog(this, + "User Taken", + "Cannot sign up", + JOptionPane.WARNING_MESSAGE); + } + } + else if(e.getSource().equals(make)){ + list.setVisible(false); + mine.setVisible(true); + } + else if(e.getSource().equals(backList)||e.getSource().equals(backList2)){ + updt(); + viewOne.setVisible(false); + mine.setVisible(false); + list.setVisible(true); + } + else if(e.getSource().equals(send)){ + server.publishPost(titleField.getText(),write.getText()); + updt(); + mine.setVisible(false); + list.setVisible(true); + } + } + + public void updt(){ + PL=server.fetchPostsFromServer(); + this.updateTable(PL); + } +} + diff --git a/WallPostServer/WallPostServer.iml b/WallPostServer/WallPostServer.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/WallPostServer/WallPostServer.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar b/WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar new file mode 100644 index 0000000000000000000000000000000000000000..c251101f50703bf426d2537930d357a2677ed159 GIT binary patch literal 10052 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 literal 0 HcmV?d00001 diff --git a/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF b/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF new file mode 100644 index 0000000..836f72b --- /dev/null +++ b/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: WallPostServer + diff --git a/WallPostServer/src/HeaderNotFoundException.java b/WallPostServer/src/HeaderNotFoundException.java new file mode 100644 index 0000000..07c7fa6 --- /dev/null +++ b/WallPostServer/src/HeaderNotFoundException.java @@ -0,0 +1,5 @@ +public class HeaderNotFoundException extends Exception{ + public HeaderNotFoundException(){ + super("Header not found"); + } +} diff --git a/WallPostServer/src/META-INF/MANIFEST.MF b/WallPostServer/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..836f72b --- /dev/null +++ b/WallPostServer/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: WallPostServer + diff --git a/WallPostServer/src/PermanentSorage.java b/WallPostServer/src/PermanentSorage.java new file mode 100644 index 0000000..0a20b1e --- /dev/null +++ b/WallPostServer/src/PermanentSorage.java @@ -0,0 +1,73 @@ +import java.io.*; +import java.net.Socket; +import java.util.ArrayList; + +public class PermanentSorage extends Thread{ + public UserList getUList() { + return UList; + } + + public PostList getPList() { + return PList; + } + + private UserList UList; + private PostList PList; + private FileInputStream FIn=null; + private ObjectInputStream ObjIn=null; + private boolean firstTime; + public PermanentSorage(UserList UList, PostList PList) { + this.UList=UList; + this.PList=PList; + try { + File f = new File("SAVE.DAT"); + if(!f.exists()) { + this.firstTime= f.createNewFile(); + } + else { + FIn = new FileInputStream(f); + ObjIn = new ObjectInputStream(FIn); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void loadFromDisk(){ + try { + if(!firstTime) { + SaveContainer c = (SaveContainer) ObjIn.readObject(); + this.UList = c.getUl(); + this.PList = c.getPl(); + ObjIn.close(); + FIn.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public void run(){ + while(true) { + try { + System.out.println("STARTING SAVE"); + FileOutputStream FOut= new FileOutputStream(new File("SAVE.DAT")); + ObjectOutputStream ObjOut= new ObjectOutputStream(FOut); + ObjOut.writeObject(new SaveContainer(UList,PList)); + FOut.close(); + Thread.sleep(60000);//10 sec + System.out.println("END SAVE"); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } +} diff --git a/WallPostServer/src/Post.java b/WallPostServer/src/Post.java new file mode 100644 index 0000000..8b6e65f --- /dev/null +++ b/WallPostServer/src/Post.java @@ -0,0 +1,37 @@ +import java.io.Serializable; + +public class Post implements Serializable { + public String getTitle() { + return title; + } + + public String getBody() { + return body; + } + + public String getAuthor() { + return author; + } + + public String getDate() { + return date; + } + + public int getId() { + return id; + } + + private String title, body,author, date; + private int id; + public void setBody(String body) { + this.body = body; + } + + public Post(String title, String body, String author, String date, int id){ + this.title=title; + this.body=body; + this.author=author; + this.date=date; + this.id=id; + } +} diff --git a/WallPostServer/src/PostList.java b/WallPostServer/src/PostList.java new file mode 100644 index 0000000..34b1453 --- /dev/null +++ b/WallPostServer/src/PostList.java @@ -0,0 +1,18 @@ +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Random; + +public class PostList extends ArrayList implements Serializable { + public int getNewId(){ + int u; + Random r = new Random(); + u=r.nextInt(); + for(int i=0;i headers, values; + public ServerThread(Socket clientSocket,UserList UList,PostList PList) { + this.socket = clientSocket; + this.UList=UList; + this.PList=PList; + } + /* + + ERROR + TITLE + END + TEXT + END + END + END + + + ERROR + TITLE + END + TEXT + END + QUIT + QUIT + + */ + private String sanitize(String a){ + return a.replaceAll("FOLLOWS","follows").replaceAll("END","END"); + } + private synchronized UserList accessUserList(){ + return this.UList; + } + private synchronized PostList accessPostList(){ + return this.PList; + } + public String valueByHeader(String header) throws HeaderNotFoundException { + for(int i=0;i(); + values= new ArrayList(); + while (true) { + try { + line = in.readLine(); + if ((line == null) || line.equalsIgnoreCase("QUIT")) { + socket.close(); + return; + } else { + if(line.startsWith("ACTION")) { + headers.clear(); + values.clear(); + action=line.split(" ", 2)[1]; + while(!line.equals("END")){ + if(line.startsWith("FOLLOWS")){ + headers.add(line.split(" ", 2)[1]); + } + else{ + if(!line.startsWith("ACTION")) { + values.add(line); + } + } + line=in.readLine(); + } + } + if(line.equals("END")){ + if(action.equals("signIn")){ + UserList u=accessUserList(); + boolean access= u.signIn(new User(valueByHeader("username"),valueByHeader("password"))); + out.writeBytes("OK\n"); + out.writeBytes("FOLLOWS status\n"); + if(access){ + out.writeBytes("OK\n"); + out.writeBytes("END\n"); + name=valueByHeader("username"); + } + else{ + out.writeBytes("NO\n"); + out.writeBytes("END\n"); + + } + } + else if(action.equals("signUp")){ + UserList u=accessUserList(); + boolean access= u.signUp(new User(valueByHeader("username"),valueByHeader("password"))); + out.writeBytes("OK\n"); + out.writeBytes("FOLLOWS status\n"); + if(access){ + out.writeBytes("OK\n"); + out.writeBytes("END\n"); + name=valueByHeader("username"); + } + else{ + out.writeBytes("NO\n"); + out.writeBytes("END\n"); + + } + } + else if(name.equals("DEFAULT")){ + out.writeBytes("ERROR\n" + + "Authentication Error\n" + + "END\n" + + "You must log in" + + "END\n" + + "QUIT\n" + + "QUIT\n"); + } + else if(action.equals("listPosts")){ + + PostList p= accessPostList(); + out.writeBytes("OK\n"); + for(int i=0;i implements Serializable{ + public boolean signUp(User a){ + for(int i=0;i