Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6b80186
JPA + Auth + slf4j2 logger
owpk Aug 8, 2020
4eff185
auth fix
owpk Aug 8, 2020
57adba8
minor fix
owpk Aug 8, 2020
312fac2
auth fix
owpk Aug 9, 2020
fb6fbfe
auth exception rework
owpk Aug 9, 2020
4964d2d
Test user for auth
owpk Aug 9, 2020
6c9207f
Merge branch 'feature'
owpk Aug 9, 2020
b10277b
Bump tika-core from 1.18 to 1.22
dependabot[bot] Aug 9, 2020
927f0f3
fix
owpk Aug 9, 2020
c895ca1
Merge remote-tracking branch 'origin/dependabot/maven/org.apache.tika…
owpk Aug 9, 2020
f57da7f
tika 1.18
owpk Aug 9, 2020
cbe1fc3
minor fix
owpk Aug 10, 2020
6f433f9
Merge branch 'master' into feature
owpk Aug 10, 2020
abf0dc6
sign feature
owpk Aug 11, 2020
9c11979
Merge branch 'master' into feature
owpk Aug 11, 2020
70002ca
minor fixes
owpk Aug 11, 2020
4e68e4b
Upload refactor
owpk Aug 11, 2020
2764ec8
Download refactor
owpk Aug 11, 2020
8aae736
Merge branch 'master' into feature
owpk Aug 11, 2020
0ec449a
sign up rework
owpk Aug 11, 2020
64335ca
IONetwork handlers pipeline
owpk Aug 11, 2020
8514989
Merge branch 'feature'
owpk Aug 11, 2020
4fdd99c
fix
owpk Aug 11, 2020
60b541e
fix
owpk Aug 11, 2020
83a1455
Merge branch 'feature'
owpk Aug 11, 2020
28326e3
fix
owpk Aug 11, 2020
cf8a109
sign up fix
owpk Aug 12, 2020
6a1a155
Merge branch 'feature'
owpk Aug 12, 2020
12d5050
fix class description
owpk Aug 12, 2020
081c09f
Merge branch 'feature'
owpk Aug 12, 2020
32c04f4
Delete option, readme
owpk Aug 21, 2020
a9c085f
Merge branch 'feature'
owpk Aug 21, 2020
e9f3671
readme upd
owpk Aug 21, 2020
9f8c5a1
mvn package
owpk Aug 24, 2020
0e06ddf
read me update
owpk Aug 24, 2020
25b107f
readme upd
owpk Aug 24, 2020
045b1d4
rdm upd
owpk Aug 24, 2020
641a14f
readme upd
owpk Aug 24, 2020
563991e
readme
owpk Aug 24, 2020
dfb40a3
readme
owpk Aug 24, 2020
93f8e5a
docker support
owpk Aug 24, 2020
ec10955
Merge branch 'master' into feature
owpk Aug 24, 2020
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
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
.idea
/client/target
#/server/client_folder/
#/client/downloads/
/server/clients_folders/
/client/Cloud Storage downloads/
/server/target
/network/target
/server/out
*.iml
/server/log/
*.iml
*.log
Binary file added .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM maven:3.6-alpine as DEPS

WORKDIR /opt/app
COPY server.properties server.properties
COPY server/pom.xml server/pom.xml
COPY network/pom.xml network/pom.xml
COPY client/pom.xml client/pom.xml

COPY pom.xml .

FROM maven:3.6-alpine as BUILDER
WORKDIR /opt/app
COPY --from=deps /opt/app/ /opt/app
COPY server/src /opt/app/server/src
COPY network/src /opt/app/network/src
COPY client/src /opt/app/client/src

RUN mvn -pl .,network,server clean package -Dhttps.protocols=TLSv1.2

FROM openjdk:8-jre-alpine
WORKDIR /opt/app
COPY --from=builder /opt/app/server/target/server-1.0-jar-with-dependencies.jar .
COPY --from=builder /opt/app/server/target/server.properties .
EXPOSE 8190
CMD [ "java", "-jar", "server-1.0-jar-with-dependencies.jar" ]

44 changes: 43 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,43 @@
CloudStorage
# Simple Cloud Storage App

An example of a simple file manager with the ability to exchange files between a remote server and a client. Supports drag-and-drop actions, simple authorization and sing up functions.
The server implements the netty framework 4.1.51.

* See client.properties and server.properties files to configure the app

<a><img src="https://github.com/vzvz4/Test/blob/master/sc.jpg" width="500"/></a>

## Building

#### Prerequisites:

1. Java (JDK) 8.

#### Build

```sh
You can use Maven to build the app:
From the project root, run ./mvnw clean install.
```
**Open client/target and server/target folder and run "jar-with-dependencies.jar" files by using console.**

**You should see "[main] INFO org.owpk.core.Server - Server started at : 8190" message from the server and "connected : localhost/127.0.0.1:8190" message from the client if everything is ok.**

* By default, server creates a "clients_folders" directory in server root as default users files storage. Client creates a "Cloud Storage downloads" directory in client root as default download directory.
* If you want to customize some properties like port address, download dirs etc, look at client.properties and server.properties files, you can find it in project root or in target folder if you have already built the app.
* The server uses MySQL connection to authorize and add a new user, in project root you can find a DDL script to build your own database server, connection properties described in /server/src/resources/META-INF/persistence.xml file.
* You can also connect to the server with "test user" login and password.

##Docker
* You can run the server in docker
- Install Docker on the machine you want to run it.
- Go to project root and run the commands below by using console
```sh
$docker build -t java-app:cloud .
$docker run java-app:cloud

Or just pull it from repository
$docker pull vzvz4/cloud:cloud
```


10 changes: 5 additions & 5 deletions client.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#root_directory
#Fri Aug 07 22:50:37 YAKT 2020
default_server=localhost
download_directory=./client/downloads/
#last_directory
#Tue Aug 25 03:02:49 YAKT 2020
last_directory=C\:\\
download_directory=C\:\\Users\\vzvz4\\Desktop\\PAPKA\\cloudStorageProject\\engine\\CloudStorage\\.\\Cloud Storage downloads
port=8190
host=79.143.31.62
connect_on_startup=false
root_directory=C\:\\Users\\vzvz4\\Desktop\\PAPKA\\cloudStorageProject\\engine\\CloudStorage\\.\\client\\downloads
1 change: 0 additions & 1 deletion client/downloads/File_to_upload.txt

This file was deleted.

3 changes: 0 additions & 3 deletions client/downloads/Test_file.txt

This file was deleted.

73 changes: 65 additions & 8 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,71 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>client</artifactId>
<dependencies>
<dependency>
<groupId>org.owpk</groupId>
<artifactId>network</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<packaging>jar</packaging>

<properties>
<commos.codec.version>1.11</commos.codec.version>
</properties>

<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven.assembly.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.owpk.app.Client</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="../client.properties" tofile="${basedir}/target/client.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commos.codec.version}</version>
</dependency>

<dependency>
<groupId>org.owpk</groupId>
<artifactId>network</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
37 changes: 37 additions & 0 deletions client/src/main/java/org/owpk/IODataHandler/AbsHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.owpk.IODataHandler;

import io.netty.handler.codec.serialization.ObjectDecoderInputStream;
import io.netty.handler.codec.serialization.ObjectEncoderOutputStream;
import org.owpk.message.Message;
import org.owpk.network.IONetworkServiceImpl;

import java.io.IOException;

public abstract class AbsHandler {
private boolean handlerOver;

protected void initDataListener() throws IOException, ClassNotFoundException {
System.out.println("DataListener started : " + this.getClass().toString() + " : handler: " + handlerOver);
ObjectDecoderInputStream in = (ObjectDecoderInputStream) IONetworkServiceImpl.getService().getIn();
Message<?> msg;
while (!handlerOver) {
if (in.available() > 0) {
msg = (Message<?>) in.readObject();
listen(msg);
}
}
}

protected void writeMessage(Message<?> message) throws IOException {
((ObjectEncoderOutputStream) IONetworkServiceImpl
.getService()
.getOut())
.writeObject(message);
}

public void setHandlerOver(boolean handlerOver) {
this.handlerOver = handlerOver;
}
protected abstract void listen(Message<?> message) throws IOException;
public abstract void execute() throws InterruptedException, IOException, ClassNotFoundException;
}
115 changes: 115 additions & 0 deletions client/src/main/java/org/owpk/IODataHandler/AuthHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.owpk.IODataHandler;

import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.owpk.controller.UserDialog;
import org.owpk.message.Message;
import org.owpk.message.MessageType;
import org.owpk.message.UserInfo;
import org.owpk.network.IONetworkServiceImpl;

import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;

/**
* Отпарвляет форму с данными на сервер для аутентификации, слушает ответ
* @see #initDataListener()
* @see #listen(Message)
*/
@Getter
@Setter
public class AuthHandler extends AbsHandler {
private final Logger log = LogManager.getLogger(AuthHandler.class.getName());
private final CountDownLatch doneLatch = new CountDownLatch(1);

private String hash(String input) {
return DigestUtils.sha256Hex(input);
}

private void showDialog() {
Platform.runLater(() -> {
loginDialog();
doneLatch.countDown();
});
}

@Override
protected void listen(Message<?> msg) {
if (msg.getType() == MessageType.OK) {
setHandlerOver(true);
IONetworkServiceImpl.getService().addMainDataHandler();
} else if (msg.getType() == MessageType.ERROR) {
UserDialog.errorDialog((String) msg.getPayload());
IONetworkServiceImpl.getService().addHandlerToPipeline(new AuthHandler());
setHandlerOver(true);
}
}

//sync
@Override
public void execute() throws InterruptedException {
showDialog();
doneLatch.await();
}

private void loginDialog() {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.setTitle("Login");
dialog.setHeaderText("Authentication\nTest login: user\nTest password: 1234");

ButtonType loginButtonType = new ButtonType("Login", ButtonBar.ButtonData.OK_DONE);
ButtonType signUpButtonType = new ButtonType("Sign up");
ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);

dialog.getDialogPane().getButtonTypes().setAll(signUpButtonType, loginButtonType, buttonTypeCancel);

GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));

TextField username = new TextField();
username.setPromptText("Username");
PasswordField password = new PasswordField();
password.setPromptText("Password");

grid.add(new Label("Username:"), 0, 0);
grid.add(username, 1, 0);
grid.add(new Label("Password:"), 0, 1);
grid.add(password, 1, 1);

Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);

username.textProperty().addListener((observable, oldValue, newValue) -> loginButton.setDisable(newValue.trim().isEmpty()));

dialog.getDialogPane().setContent(grid);

Optional<ButtonType> result = dialog.showAndWait();
if (result.get() == loginButtonType) {
try {
writeMessage(new UserInfo(MessageType.AUTH, username.getText(), hash(password.getText())));
initDataListener();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
else if (result.get() == signUpButtonType) {
System.out.println("SIGN OPTION");
IONetworkServiceImpl.getService().addHandlerToPipeline(new SignHandler());
setHandlerOver(true);
} else {
IONetworkServiceImpl.getService().disconnect();
}
}

}
Loading