This commit is contained in:
kashiuno 2025-03-20 21:11:23 +03:00
parent deb18f48c0
commit b797aed073
11 changed files with 35 additions and 25 deletions

View File

@ -38,7 +38,7 @@ public class ClientView extends VerticalLayout {
addButton.addClickListener(e -> editClient(new ClientEntity())); addButton.addClickListener(e -> editClient(new ClientEntity()));
grid.setHeight("200px"); grid.setHeight("600px");
grid.asSingleSelect().addValueChangeListener(e -> editClient(e.getValue())); grid.asSingleSelect().addValueChangeListener(e -> editClient(e.getValue()));
refreshClientGrid(); refreshClientGrid();

View File

@ -1,9 +1,12 @@
package ru.vyatsu.qr_access_admin.common.config; package ru.vyatsu.qr_access_admin.common.config;
import com.vaadin.flow.spring.security.VaadinWebSecurity; import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -14,4 +17,9 @@ public class SecurityConfiguration extends VaadinWebSecurity {
super.configure(http); super.configure(http);
http.oauth2Login(c -> c.loginProcessingUrl("/login/oauth2/code/own")); http.oauth2Login(c -> c.loginProcessingUrl("/login/oauth2/code/own"));
} }
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
} }

View File

@ -8,6 +8,7 @@ import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.BigDecimalField;
import com.vaadin.flow.component.textfield.IntegerField; import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.BeanValidationBinder; import com.vaadin.flow.data.binder.BeanValidationBinder;
@ -170,7 +171,7 @@ public class DoorEditor extends Composite<HorizontalLayout> {
unitField.setItemLabelGenerator(UnitComboBoxModel::clientName); unitField.setItemLabelGenerator(UnitComboBoxModel::clientName);
IntegerField countField = new IntegerField("Количество мест"); IntegerField countField = new IntegerField("Количество мест");
TextField descriptionField = new TextField("Описание"); TextField descriptionField = new TextField("Описание");
BigDecimalField price = new BigDecimalField("Цена за час");
var save = new Button("Сохранить", VaadinIcon.CHECK.create()); var save = new Button("Сохранить", VaadinIcon.CHECK.create());
var cancel = new Button("Отмена"); var cancel = new Button("Отмена");
@ -180,6 +181,7 @@ public class DoorEditor extends Composite<HorizontalLayout> {
.withConverter(UnitComboBoxModel::clientId, units::get, "Invalid value") .withConverter(UnitComboBoxModel::clientId, units::get, "Invalid value")
.bind("unitId"); .bind("unitId");
binder.forField(countField).bind("count"); binder.forField(countField).bind("count");
binder.forField(price).bind("price");
binder.forField(descriptionField).bind("description"); binder.forField(descriptionField).bind("description");
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
@ -203,7 +205,7 @@ public class DoorEditor extends Composite<HorizontalLayout> {
cancel.addClickListener(e -> cancelListener.onCancel()); cancel.addClickListener(e -> cancelListener.onCancel());
VerticalLayout mainForm = new VerticalLayout(); VerticalLayout mainForm = new VerticalLayout();
mainForm.add(unitField, countField, descriptionField, scheduleEditor, new HorizontalLayout(save, cancel, delete)); mainForm.add(unitField, countField, descriptionField, price, scheduleEditor, new HorizontalLayout(save, cancel, delete));
getContent().add(mainForm, additionalDoorsEditor); getContent().add(mainForm, additionalDoorsEditor);
} }

View File

@ -4,6 +4,8 @@ import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.math.BigDecimal;
@Entity @Entity
@Table(name = "doors") @Table(name = "doors")
@Getter @Getter
@ -23,6 +25,9 @@ public class DoorEntity {
@Column @Column
private int count; private int count;
@Column
private BigDecimal price;
@Column @Column
private String parentDoorIds; private String parentDoorIds;
} }

View File

@ -52,8 +52,7 @@ public class DoorView extends VerticalLayout {
addButton.addClickListener(e -> editDoor(new DoorEntity())); addButton.addClickListener(e -> editDoor(new DoorEntity()));
grid.setHeight("200px"); grid.setHeight("600px");
grid.asSingleSelect().addValueChangeListener(e -> editDoor(e.getValue())); grid.asSingleSelect().addValueChangeListener(e -> editDoor(e.getValue()));
refreshDoorsGrid(); refreshDoorsGrid();

View File

@ -38,7 +38,7 @@ public class PartnerView extends VerticalLayout {
addButton.addClickListener(e -> editPartner(new PartnerEntity())); addButton.addClickListener(e -> editPartner(new PartnerEntity()));
grid.setHeight("200px"); grid.setHeight("600px");
grid.asSingleSelect().addValueChangeListener(e -> editPartner(e.getValue())); grid.asSingleSelect().addValueChangeListener(e -> editPartner(e.getValue()));
refreshPartnerGrid(); refreshPartnerGrid();

View File

@ -10,7 +10,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
@Table(name = "rent") @Table(name = "rents")
@Entity @Entity
@Getter @Getter
@Setter @Setter

View File

@ -40,7 +40,7 @@ public class RentView extends VerticalLayout {
addButton.addClickListener(e -> editRent(new RentEntity())); addButton.addClickListener(e -> editRent(new RentEntity()));
grid.setHeight("200px"); grid.setHeight("600px");
grid.asSingleSelect().addValueChangeListener(e -> editRent(e.getValue())); grid.asSingleSelect().addValueChangeListener(e -> editRent(e.getValue()));
refreshRentGrid(); refreshRentGrid();

View File

@ -1,10 +1,7 @@
package ru.vyatsu.qr_access_admin.unit.mapper; package ru.vyatsu.qr_access_admin.unit.mapper;
import ru.vyatsu.qr_access_admin.unit.model.UnitComboBoxModel;
import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity; import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity;
import ru.vyatsu.qr_access_admin.unit.model.UnitComboBoxModel;
import java.util.Collection;
import java.util.List;
public class UnitEntityUnitComboBoxModelMapper { public class UnitEntityUnitComboBoxModelMapper {
@ -14,10 +11,4 @@ public class UnitEntityUnitComboBoxModelMapper {
} }
return new UnitComboBoxModel(entity.getClientId(), entity.getClientName()); return new UnitComboBoxModel(entity.getClientId(), entity.getClientName());
} }
public List<UnitComboBoxModel> toModels(Collection<UnitEntity> entities) {
return entities.stream()
.map(this::toModel)
.toList();
}
} }

View File

@ -1,5 +1,9 @@
package ru.vyatsu.qr_access_admin.unit.mapper; package ru.vyatsu.qr_access_admin.unit.mapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity; import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity;
import ru.vyatsu.qr_access_admin.unit.model.UnitModel; import ru.vyatsu.qr_access_admin.unit.model.UnitModel;
@ -8,8 +12,11 @@ import java.util.Collection;
import java.util.List; import java.util.List;
@Component @Component
@RequiredArgsConstructor
public class UnitEntityUnitModelMapper { public class UnitEntityUnitModelMapper {
private final PasswordEncoder passwordEncoder;
public static final String DEFAULT_CLIENT_SETTINGS = "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-proof-key\":false,\"settings.client.require-authorization-consent\":false}"; public static final String DEFAULT_CLIENT_SETTINGS = "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-proof-key\":false,\"settings.client.require-authorization-consent\":false}";
private static final String DEFAULT_TOKEN_SETTINGS = """ private static final String DEFAULT_TOKEN_SETTINGS = """
{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.x509-certificate-bound-access-tokens":false,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",31540000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300.000000000]} {"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.x509-certificate-bound-access-tokens":false,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",31540000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300.000000000]}
@ -19,15 +26,12 @@ public class UnitEntityUnitModelMapper {
UnitEntity entity = new UnitEntity(); UnitEntity entity = new UnitEntity();
entity.setId(model.getId()); entity.setId(model.getId());
entity.setClientId(model.getClientId()); entity.setClientId(model.getClientId());
// TODO: Приделать PasswordEncoder когда заедет security entity.setClientSecret(passwordEncoder.encode(model.getClientSecret()));
entity.setClientSecret(model.getClientSecret());
entity.setClientSecretExpiresAt(model.getClientSecretExpiresAt()); entity.setClientSecretExpiresAt(model.getClientSecretExpiresAt());
entity.setClientName(model.getClientName()); entity.setClientName(model.getClientName());
entity.setScopes(""); entity.setScopes("");
// TODO: Использовать enum, когда заедет oauth2 entity.setAuthorizationGrantTypes(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue());
entity.setAuthorizationGrantTypes("client_credentials"); entity.setClientAuthenticationMethods(ClientAuthenticationMethod.CLIENT_SECRET_POST.getValue());
// TODO: Использовать enum, когда заедет oauth2
entity.setClientAuthenticationMethods("client_secret_post");
entity.setClientSettings(DEFAULT_CLIENT_SETTINGS); entity.setClientSettings(DEFAULT_CLIENT_SETTINGS);
entity.setTokenSettings(DEFAULT_TOKEN_SETTINGS); entity.setTokenSettings(DEFAULT_TOKEN_SETTINGS);
entity.setRedirectUris(""); entity.setRedirectUris("");

View File

@ -44,7 +44,7 @@ public class UnitView extends VerticalLayout {
addButton.addClickListener(e -> editUnit(new UnitModel())); addButton.addClickListener(e -> editUnit(new UnitModel()));
grid.setHeight("200px"); grid.setHeight("600px");
grid.asSingleSelect().addValueChangeListener(e -> editUnit(e.getValue())); grid.asSingleSelect().addValueChangeListener(e -> editUnit(e.getValue()));
refreshUnitsGrid(); refreshUnitsGrid();
@ -69,6 +69,7 @@ public class UnitView extends VerticalLayout {
editor.setVisible(false); editor.setVisible(false);
editor.setSaveListener(unit -> { editor.setSaveListener(unit -> {
// TODO: Сделать, чтобы секрет клиента при изменении не перехешировался, иначе станет не рабочим
UnitEntity entity = entityModelMapper.mapModelToEntity(unit); UnitEntity entity = entityModelMapper.mapModelToEntity(unit);
unitRepository.save(entity); unitRepository.save(entity);
refreshUnitsGrid(); refreshUnitsGrid();