· 5 years ago · Sep 24, 2020, 12:58 PM
1package ru.savadevel.service;
2
3import ru.savadevel.exceptions.AccountException;
4import ru.savadevel.module.Account;
5
6import java.sql.*;
7
8// сервис для аутентификации пользователя на основе таблицы accounts
9// Сервис должен содержать метод для аутентификации по логину и паролю
10// В случае если пользователь существует в
11// таблице account (с таким username и password) метод должен возвращать значение true
12public class AccountService implements AutoCloseable {
13 private Connection _connection = null;
14 // запрос на проверку / создание (при отсутствии таблицы accounts)
15 private static final String _CREATE_TABLE_ACCOUNTS = "create table if not exists accounts (" +
16 " user_id serial PRIMARY KEY," +
17 " username VARCHAR ( 50 ) UNIQUE NOT NULL," +
18 " password VARCHAR ( 50 ) NOT NULL," +
19 " email VARCHAR ( 255 ) UNIQUE NOT NULL," +
20 " created_on TIMESTAMP NOT NULL," +
21 " last_login TIMESTAMP)";
22 // шаблон запроса на аутентификацию пользователя, пароль в БД храниться в MD5
23 private static final String _CHK_AUTHENTICATION = "select count(*) cnt_users from public.accounts a where " +
24 "a.username = ? and a.\"password\" = md5(?)";
25 // шаблон запроса на добавление пользователя, пароль в БД храниться в MD5
26 private static final String _ADD_ACCOUNT = "insert into public.accounts (username, \"password\", email, created_on ) " +
27 "values (?, md5(?), ?, now())";
28
29 private AccountService() {
30 }
31
32 // создать сервис можно только через данный конструктор, в котором выполняется подключение к БД для работы с
33 // учетными записями пользователей
34 // создает таблицу account если ее нет
35 // при ошибке генерирует исключение AccountException
36 public AccountService(String strConnectionString, String strConnectionLogin, String strConnectionPassword)
37 throws AccountException {
38 this._createConnection(strConnectionString, strConnectionLogin, strConnectionPassword);
39 this._checkAndCreateTableAccounts();
40 }
41
42 // добавляет пользователя в таблицу account и возвращает объект
43 // при ошибке генерирует исключение AccountAddException
44 public Account addAccount(Account account) {
45 throw new UnsupportedOperationException();
46 }
47
48 // выгружает пользователя из таблицы account и возвращает объект
49 // при ошибке генерирует исключение AccountGetException
50 public Account getAccountById(int iId) {
51 throw new UnsupportedOperationException();
52 }
53
54 // удаляет пользователя из таблицы account и возвращает объект
55 // при ошибке генерирует исключение AccountDelException
56 public Account delAccountById(int iId) {
57 throw new UnsupportedOperationException();
58 }
59
60 // аутентификация пользователя по таблице account и возвращает true,
61 // при успешной авторизации (пароль соответствует пользователю)
62 // использует перегруженный метод
63 public boolean authentication (Account account) throws AccountException {
64 return this.authentication (account.getUserName(), account.getPassword());
65 }
66
67 // аутентификация пользователя по таблице account и возвращает true,
68 // при успешной авторизации (пароль соответствует пользователю)
69 public boolean authentication (String strUserName, String strPassword) throws AccountException {
70 boolean bRet = false;
71
72 try (PreparedStatement statement = _connection.prepareStatement(_CHK_AUTHENTICATION)){
73
74 statement.setString(1, strUserName);
75 statement.setString(2, strPassword);
76
77 try (ResultSet resultSet = statement.executeQuery()) {
78
79 if (resultSet.next() && 1 == resultSet.getLong(1))
80 bRet = true;
81 }
82
83 } catch (SQLException throwables) {
84 throw new AccountException(throwables, "Can't authentication account '%s'", strUserName);
85 }
86
87
88 return bRet;
89 }
90
91 // создание подключения к БД
92 private void _createConnection(String strConnectionString, String strConnectionLogin, String strConnectionPassword)
93 throws AccountException {
94 try {
95 this._connection = DriverManager.getConnection(strConnectionString, strConnectionLogin, strConnectionPassword);
96 } catch (SQLException throwables) {
97 throw new AccountException(throwables, "Can't create connection for connection string '%s' with login '%s'",
98 strConnectionString, strConnectionLogin);
99 }
100 }
101
102 // проверка наличие и создание таблицы accounts, при ее отсутствии в БД
103 private void _checkAndCreateTableAccounts() throws AccountException {
104 try (PreparedStatement statement = _connection.prepareStatement(_CREATE_TABLE_ACCOUNTS)){
105
106 statement.execute();
107
108 } catch (SQLException throwables) {
109 throw new AccountException(throwables, "Can't create table accounts");
110 }
111 }
112
113 @Override
114 public void close() throws Exception {
115 if (_connection != null && false == _connection.isClosed())
116 _connection.close();
117 }
118}
119