Added all EmployeeController requests, except registration.

Fixed Entities and database relations
Fixed door opening
This commit is contained in:
Индекс Зиро 2025-02-19 11:34:45 +03:00
parent 413d071443
commit 3edb2cf101
22 changed files with 220 additions and 93 deletions

View File

@ -4,7 +4,6 @@ import com.indexzero.finals.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
@ -31,6 +30,11 @@ public class SecurityConfig {
.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/api/employee/login").authenticated()
.requestMatchers("/api/employee/profile").authenticated()
.requestMatchers("/api/employee/{login}/delete").hasAuthority("ADMIN")
.requestMatchers("/api/employee/{login}/{state}").hasAuthority("ADMIN")
.requestMatchers("/api/employee/all").hasAuthority("ADMIN")
.requestMatchers("/api/employee/{login}").hasAuthority("ADMIN")
.requestMatchers("/swagger-ui/**").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults()).csrf(csrf -> csrf

View File

@ -0,0 +1,22 @@
package com.indexzero.finals.controller;
import com.indexzero.finals.entity.Entrance;
import com.indexzero.finals.repository.EntranceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/entrance")
public class CodeController {
@Autowired
EntranceRepository visitRepository;
@GetMapping
public List<Entrance> getVisits() {
return visitRepository.findAll();
}
}

View File

@ -1,15 +1,10 @@
package com.indexzero.finals.controller;
import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Code;
import com.indexzero.finals.entity.Employee;
import com.indexzero.finals.entity.Visit;
import com.indexzero.finals.repository.CodeRepository;
import com.indexzero.finals.repository.EmployeeRepository;
import com.indexzero.finals.repository.VisitRepository;
import com.indexzero.finals.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
@ -39,4 +34,24 @@ public class EmployeeController {
return employeeService.openTheDoor(code, SecurityContextHolder.getContext().getAuthentication());
}
@DeleteMapping("/{login}/delete")
public ResponseEntity<HttpStatusCode> delete(@PathVariable String login) {
return employeeService.deleteEmployee(login);
}
@PatchMapping("/{login}/{state}")
public ResponseEntity<HttpStatusCode> changeState(@PathVariable String login, @PathVariable String state) {
return employeeService.changeState(login, state);
}
@GetMapping("/all")
public ResponseEntity<List<EmployeeDTO>> getAll() {
return employeeService.getAllEmployees();
}
@GetMapping("/{login}")
public ResponseEntity<EmployeeDTO> getEmployeeByLogin(@PathVariable String login) {
return employeeService.getEmployeeByLogin(login);
}
}

View File

@ -20,6 +20,6 @@ public class Code {
@Column(name = "value")
private long value;
@Column(name = "is_active")
boolean isActive;
@Column(name = "name")
String name;
}

View File

@ -7,8 +7,6 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
@ -38,14 +36,22 @@ public class Employee implements UserDetails {
@Column(name = "photo_url")
private String photoUrl;
@Column(name = "is_enabled")
Boolean isEmpEnabled;
@ManyToMany(fetch = FetchType.EAGER)
Set<Authority> authorities;
@OneToMany(mappedBy = "id")
List<Visit> visits;
@OneToMany(mappedBy = "id", cascade = CascadeType.ALL)
List<Entrance> entrances;
@Override
public String getUsername() {
return this.login;
}
@Override
public boolean isEnabled() {
return isEmpEnabled;
}
}

View File

@ -0,0 +1,34 @@
package com.indexzero.finals.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "employee_entrances")
public class Entrance {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "visit_time")
private LocalDateTime visitTime;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employee_id", referencedColumnName = "id")
private Employee employee;
// @OneToOne
// @JoinColumn(name = "employee_id", referencedColumnName = "id")
// private Employee employee;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reader", referencedColumnName = "id")
private Code reader;
@Column(name = "type")
private String type;
}

View File

@ -1,25 +0,0 @@
package com.indexzero.finals.entity;
import jakarta.persistence.*;
import lombok.Data;
import org.apache.catalina.User;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@Data
@Entity
@Table(name = "employee_visits")
public class Visit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "visit_time")
private LocalDateTime visitTime;
@Column(name = "type")
private String type;
}

View File

@ -0,0 +1,7 @@
package com.indexzero.finals.repository;
import com.indexzero.finals.entity.Entrance;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EntranceRepository extends JpaRepository<Entrance, Long> {
}

View File

@ -1,7 +0,0 @@
package com.indexzero.finals.repository;
import com.indexzero.finals.entity.Visit;
import org.springframework.data.jpa.repository.JpaRepository;
public interface VisitRepository extends JpaRepository<Visit, Long> {
}

View File

@ -1,13 +1,19 @@
package com.indexzero.finals.service;
import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Employee;
import org.apache.catalina.User;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import java.util.List;
public interface EmployeeService {
ResponseEntity<Object> checkIfUserExists(String login);
ResponseEntity<EmployeeDTO> getUserInfo(Authentication auth);
ResponseEntity<Object> openTheDoor(Long code, Authentication auth);
ResponseEntity<HttpStatusCode> deleteEmployee(String login);
ResponseEntity<HttpStatusCode> changeState(String login, String state);
ResponseEntity<List<EmployeeDTO>> getAllEmployees();
ResponseEntity<EmployeeDTO> getEmployeeByLogin(String login);
}

View File

@ -2,20 +2,23 @@ package com.indexzero.finals.service.impl;
import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Employee;
import com.indexzero.finals.entity.Visit;
import com.indexzero.finals.entity.Entrance;
import com.indexzero.finals.repository.CodeRepository;
import com.indexzero.finals.repository.EmployeeRepository;
import com.indexzero.finals.repository.EntranceRepository;
import com.indexzero.finals.service.EmployeeService;
import com.indexzero.finals.util.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@ -24,6 +27,8 @@ public class EmployeeServiceImpl implements EmployeeService {
@Autowired
CodeRepository codeRepository;
@Autowired
private EntranceRepository entranceRepository;
public ResponseEntity<Object> checkIfUserExists(String login) {
try {
@ -46,34 +51,89 @@ public class EmployeeServiceImpl implements EmployeeService {
public ResponseEntity<Object> openTheDoor(Long code, Authentication auth) {
try {
if(codeRepository.findByValue(code).isActive()) {
if (codeRepository.existsByValue(Long.valueOf(code))) {
Employee employee = employeeRepository.findByLogin(auth.getName());
if (codeRepository.existsByValue(Long.valueOf(code))) {
Employee employee = employeeRepository.findByLogin(auth.getName());
Entrance entrance = new Entrance();
Visit visit = new Visit();
entrance.setVisitTime(LocalDateTime.now());
entrance.setReader(codeRepository.findByValue(code));
entrance.setType("smartphone");
entrance.setEmployee(employee);
LocalDateTime time = LocalDateTime.now();
visit.setVisitTime(LocalDateTime.now());
visit.setType("smartphone");
entranceRepository.save(entrance);
List<Visit> v = employee.getVisits();
v.add(visit);
// employeeRepository.save(employee);
employee.setVisits(v);
employeeRepository.save(employee);
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
catch(Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@Override
public ResponseEntity<HttpStatusCode> deleteEmployee(String login) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
if (Objects.equals(e.getAuthorities().iterator().next().getAuthority(), "ADMIN")) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
else {
employeeRepository.delete(e);
return new ResponseEntity<>(HttpStatus.OK);
}
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@Override
public ResponseEntity<HttpStatusCode> changeState(String login, String state) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
if (Objects.equals(e.getAuthorities().iterator().next().getAuthority(), "ADMIN")) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
else {
if(state.equals("active")) {
e.setIsEmpEnabled(true);
employeeRepository.save(e);
return new ResponseEntity<>(HttpStatus.OK);
}
else if(state.equals("blocked")) {
e.setIsEmpEnabled(false);
employeeRepository.save(e);
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@Override
public ResponseEntity<List<EmployeeDTO>> getAllEmployees() {
return new ResponseEntity<>(employeeRepository.findAll().stream().map(EmployeeMapper::convertToDTO).collect(Collectors.toList()), HttpStatus.OK);
}
@Override
public ResponseEntity<EmployeeDTO> getEmployeeByLogin(String login) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
return new ResponseEntity<>(EmployeeMapper.convertToDTO(e), HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}

View File

@ -23,7 +23,8 @@
<column name="value" type="bigint">
<constraints nullable="false"/>
</column>
<column name="is_active" type="bool">
<column name="name" type="VARCHAR(200)">
<constraints nullable="false"/>
</column>
</createTable>

View File

@ -38,6 +38,10 @@
</column>
<column name="photo_url" type="VARCHAR(100)">
<constraints nullable="true"/>
</column>
<column name="is_enabled" type="bool">
<constraints nullable="false"/>
</column>

View File

@ -5,19 +5,19 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0005-visits" author="okalugin">
<changeSet id="2025-02-19--0005-employee-entrances-02" author="okalugin">
<preConditions>
<not>
<tableExists tableName="employee_visits"/>
<tableExists tableName="employee_entrances"/>
</not>
</preConditions>
<createTable tableName="employee_visits">
<createTable tableName="employee_entrances">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="user_id" type="BIGINT">
<column name="employee_id" type="BIGINT">
<constraints nullable="false" foreignKeyName="fk_employeeauth_employee" referencedTableName="employee"
referencedColumnNames="id"/>
</column>

View File

@ -5,7 +5,7 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0004-employee-authorities-data" author="okalugin">
<changeSet id="2025-02-19--0004-employee-authorities-data" author="okalugin">
<loadData tableName="employee_authorities" file="db.changelog/data/csv/2025-02-18--0004-employee-authorities-data.csv"
separator=";"
quotchar='"'

View File

@ -5,8 +5,8 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0005-employee-visits-data" author="okalugin">
<loadData tableName="employee_visits" file="db.changelog/data/csv/2025-02-18--0005-employee-visits-data.csv"
<changeSet id="2025-02-18--0005-employee-entrances-data" author="okalugin">
<loadData tableName="employee_entrances" file="db.changelog/data/csv/2025-02-18--0005-employee-entrances-data.csv"
separator=";"
quotchar='"'
encoding="UTF-8"/>

View File

@ -1,6 +1,6 @@
id;value;is_active
1;1234567890123456789;true
2;9223372036854775807;true
3;1122334455667788990;false
4;998877665544332211;false
5;5566778899001122334;true
id;value;name
1;1234567890123456789;Главный Вход
2;9223372036854775807;Задний Вход
3;1122334455667788990;Вход с парковки
4;998877665544332211;Вход с улицы Колатушкина
5;5566778899001122334;Вход с улицы Пушкина
1 id value is_active name
2 1 1234567890123456789 true Главный Вход
3 2 9223372036854775807 true Задний Вход
4 3 1122334455667788990 false Вход с парковки
5 4 998877665544332211 false Вход с улицы Колатушкина
6 5 5566778899001122334 true Вход с улицы Пушкина

View File

@ -1,5 +1,5 @@
login;password;name;photo_url;position
pivanov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Иванов Петр Федорович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик
ipetrov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Петров Иван Константинович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Аналитик
asemenov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Семенов Анатолий Анатольевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик
afedorov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Федоров Александр Сергеевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Тестировщик
login;password;name;photo_url;position;is_enabled
pivanov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Иванов Петр Федорович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик;true
ipetrov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Петров Иван Константинович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Аналитик;false
asemenov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Семенов Анатолий Анатольевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик;true
afedorov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Федоров Александр Сергеевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Тестировщик;true
1 login password name photo_url position is_enabled
2 pivanov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Иванов Петр Федорович https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Разработчик true
3 ipetrov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Петров Иван Константинович https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Аналитик false
4 asemenov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Семенов Анатолий Анатольевич https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Разработчик true
5 afedorov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Федоров Александр Сергеевич https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Тестировщик true

View File

@ -1,5 +1,5 @@
employee_id;authorities_id
1;1
2;2
3;2
4;2
1;2
2;1
3;1
4;1
1 employee_id authorities_id
2 1 1 2
3 2 2 1
4 3 2 1
5 4 2 1

View File

@ -0,0 +1,2 @@
employee_id;visit_time;reader;type
1;2024-02-12T08:30:00;1;smartphone
1 employee_id visit_time reader type
2 1 2024-02-12T08:30:00 1 smartphone

View File

@ -1,2 +0,0 @@
user_id;visit_time;reader;type
1;2024-02-12T08:30:00;1;smartphone
1 user_id visit_time reader type
2 1 2024-02-12T08:30:00 1 smartphone

View File

@ -8,12 +8,12 @@
<include file="db.changelog/1.0/2024-10-20--0002-employee.xml"/>
<include file="db.changelog/1.0/2025-02-18--0003-authority.xml"/>
<include file="db.changelog/1.0/2025-02-18--0004-employee-authorities.xml"/>
<include file="/db.changelog/1.0/2025-02-18--0005-employee-visits.xml"/>
<include file="/db.changelog/1.0/2025-02-18--0005-employee-entrances.xml"/>
<include file="db.changelog/data/2024-10-20--0001-code-data.xml"/>
<include file="db.changelog/data/2024-10-20--0002-employee-data.xml"/>
<include file="db.changelog/data/2025-02-18--0003-authority-data.xml"/>
<include file="db.changelog/data/2025-02-18--0004-employee-authorities-data.xml"/>
<include file="/db.changelog/data/2025-02-18--0005-employee-visits-data.xml"/>
<include file="/db.changelog/data/2025-02-18--0005-employee-entrances-data.xml"/>
</databaseChangeLog>