Skip to content

Commit

Permalink
V6
Browse files Browse the repository at this point in the history
  • Loading branch information
Pastor committed Oct 25, 2024
1 parent 38c2f94 commit 5d4572c
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 90 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ target
1000000000.csv
*.iml
logs
users.json
12 changes: 12 additions & 0 deletions vol6/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,16 @@
<artifactId>vol6</artifactId>
<name>vol6</name>
<description>Модуль №6</description>

<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>
17 changes: 10 additions & 7 deletions vol6/src/main/java/ru/mifi/practice/vol6/Authentication.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
package ru.mifi.practice.vol6;

import ru.mifi.practice.vol6.repository.UserRepository;
import com.google.common.hash.Hashing;
import ru.mifi.practice.vol6.model.User;
import ru.mifi.practice.vol6.repository.Repository;

import java.nio.charset.StandardCharsets;
import java.util.Optional;

public interface Authentication extends Security.Hash {

Optional<Context> authenticate(String username, String password);

interface Context {
static Context of(UserRepository.User user) {
static Context of(User user) {
return new SimpleContext(user);
}

UserRepository.User user();
User user();
}

record SimpleContext(UserRepository.User user) implements Context {
record SimpleContext(User user) implements Context {
}

final class Default implements Authentication {
private final UserRepository repository;
private final Repository<User, String> repository;

public Default(UserRepository repository) {
public Default(Repository<User, String> repository) {
this.repository = repository;
}

Expand All @@ -35,7 +38,7 @@ public Optional<Context> authenticate(String username, String password) {

@Override
public String hash(String password) {
return password;
return Hashing.sha256().hashString(password, StandardCharsets.UTF_8).toString();
}
}
}
25 changes: 14 additions & 11 deletions vol6/src/main/java/ru/mifi/practice/vol6/Main.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package ru.mifi.practice.vol6;

import ru.mifi.practice.vol6.repository.UserRepository;
import ru.mifi.practice.vol6.model.User;
import ru.mifi.practice.vol6.repository.Repository;
import ru.mifi.practice.vol6.repository.UserRepositoryInMemory;
import ru.mifi.practice.vol6.storege.FileStorage;
import ru.mifi.practice.vol6.storege.Storage;

import java.util.Optional;

public abstract class Main {
public static void main(String[] args) throws Exception {
Menu root = Menu.root();
Storage storage = new Storage.Empty();
Storage storage = new FileStorage();
Runnable onExit = prepare(root, storage);
try (Menu.Context context = Menu.defaultContext(onExit)) {
root.select(context);
}
}

private static Runnable prepare(Menu root, Storage storage) {
UserRepository repository = new UserRepository.Memory();
Repository.Mutant<User, String> repository = storage.read(new UserRepositoryInMemory());
Authentication authentication = new Authentication.Default(repository);

root.addSub("Аутентификация", context -> {
Expand All @@ -25,29 +29,28 @@ private static Runnable prepare(Menu root, Storage storage) {
sc.ifPresent(context::putContext);
if (sc.isEmpty()) {
context.clearContext();
context.error("Не удалось авторизоваться под пользователем '%s'", login);
context.errorln("Не удалось авторизоваться под пользователем '%s'", login);
}
});
root.addSub("Регистрация", context -> {
String login = context.select("Введите логин");
Optional<UserRepository.User> search = repository.search(login);
Optional<User> search = repository.search(login);
if (search.isEmpty()) {
String password = context.select("Введите пароль");
String confirm = context.select("Подтвердите пароль");
if (password.equals(confirm)) {
context.clearContext();
password = authentication.hash(password);
UserRepository.User user = new UserRepository.User(login, password);
repository.register(user);
User user = new User(login, password);
repository.add(user);
context.putContext(Authentication.Context.of(user));
} else {
context.error("Пароль не совпадает");
context.errorln("Пароль не совпадает");
}
} else {
context.error("Пользователь с именем '%s' уже существует", login);
context.errorln("Пользователь с именем '%s' уже существует", login);
}
});
storage.read(repository);
return () -> repository.store(storage);
return () -> storage.write(repository);
}
}
2 changes: 1 addition & 1 deletion vol6/src/main/java/ru/mifi/practice/vol6/Menu.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public void error(String format, Object... args) {
}

public String select(String text) {
output.println(text);
output.print(text);
output.print("> ");
return input.inputString();
}
Expand Down
23 changes: 0 additions & 23 deletions vol6/src/main/java/ru/mifi/practice/vol6/Storage.java

This file was deleted.

14 changes: 14 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/model/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.mifi.practice.vol6.model;

import com.google.gson.annotations.SerializedName;
import ru.mifi.practice.vol6.Security;

import java.io.Serializable;

public record User(@SerializedName("username") String username,
@SerializedName("password") String secret) implements Serializable {

public boolean equalsSecret(String password, Security.Hash hash) {
return secret.equals(hash.hash(password));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package ru.mifi.practice.vol6.repository;

import ru.mifi.practice.vol6.Storage;

import java.util.List;
import java.util.Optional;

public interface Repository<T, I> {

List<T> findAll();

Optional<T> search(I id);

void store(Storage storage);
interface Mutant<T, I> extends Repository<T, I> {

void add(T item);

void delete(I key);

void addAll(List<T> items);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ru.mifi.practice.vol6.repository;

import ru.mifi.practice.vol6.model.User;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public final class UserRepositoryInMemory implements Repository.Mutant<User, String> {
private final Map<String, User> users = new HashMap<>();

@Override
public Optional<User> search(String id) {
return Optional.ofNullable(users.get(id));
}

@Override
public void add(User user) {
if (users.containsKey(user.username())) {
throw new IllegalArgumentException("User already exists");
}
users.put(user.username(), user);
}

@Override
public void delete(String key) {
users.remove(key);
}

@Override
public void addAll(List<User> items) {
items.forEach(this::add);
}

@Override
public List<User> findAll() {
return new ArrayList<>(users.values());
}
}
44 changes: 44 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/storege/FileStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ru.mifi.practice.vol6.storege;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import ru.mifi.practice.vol6.model.User;
import ru.mifi.practice.vol6.repository.Repository;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;

public final class FileStorage implements Storage {
private static final Type LIST_OF_USERS = new TypeToken<ArrayList<User>>() {
}.getType();
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private final Path users = Path.of("users.json");

@Override
public void write(Repository.Mutant<User, String> repository) {
try {
Files.writeString(users, gson.toJson(repository.findAll()),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public Repository.Mutant<User, String> read(Repository.Mutant<User, String> repository) {
try {
List<User> list = gson.fromJson(Files.readString(users, StandardCharsets.UTF_8), LIST_OF_USERS);
repository.addAll(list);
} catch (IOException e) {
//Ignore
}
return repository;
}
}
25 changes: 25 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/storege/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.mifi.practice.vol6.storege;

import ru.mifi.practice.vol6.model.User;
import ru.mifi.practice.vol6.repository.Repository;

public interface Storage {

void write(Repository.Mutant<User, String> repository);

Repository.Mutant<User, String> read(Repository.Mutant<User, String> repository);

final class Empty implements Storage {

@Override
public void write(Repository.Mutant<User, String> repository) {
System.err.println("запись для users не реализована");
}

@Override
public Repository.Mutant<User, String> read(Repository.Mutant<User, String> repository) {
System.err.println("загрузка для users не реализована");
return repository;
}
}
}

0 comments on commit 5d4572c

Please sign in to comment.