Compare commits

...

4 Commits

58 changed files with 1846 additions and 105 deletions

View File

@ -30,6 +30,12 @@ dependencies {
implementation 'org.webjars:bootstrap:5.1.3'
implementation 'org.webjars:jquery:3.6.0'
implementation 'org.webjars:font-awesome:6.1.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
implementation 'com.auth0:java-jwt:4.4.0'
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
}
tasks.named('test') {

Binary file not shown.

View File

@ -5074,3 +5074,635 @@ SELECT * FROM Product p WHERE p.store_fk == null [42001-210]
org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT * FROM Product p WHERE p.store_fk =[*]= null"; ожидалось "ALL, ANY, SOME"
Syntax error in SQL statement "SELECT * FROM Product p WHERE p.store_fk =[*]= null"; expected "ALL, ANY, SOME"; SQL statement:
SELECT * FROM Product p WHERE p.store_fk == null [42001-210]
2023-05-15 22:40:22 database: flush
org.h2.message.DbException: Внутренняя ошибка: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]"
General error: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]" [50000-199]
at org.h2.message.DbException.get(DbException.java:194)
at org.h2.message.DbException.convert(DbException.java:347)
at org.h2.mvstore.db.MVTableEngine$1.uncaughtException(MVTableEngine.java:90)
at org.h2.mvstore.MVStore.handleException(MVStore.java:2787)
at org.h2.mvstore.MVStore.panic(MVStore.java:441)
at org.h2.mvstore.MVStore.<init>(MVStore.java:404)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
at org.h2.engine.Database.getPageStore(Database.java:2739)
at org.h2.engine.Database.open(Database.java:769)
at org.h2.engine.Database.openDatabase(Database.java:319)
at org.h2.engine.Database.<init>(Database.java:313)
at org.h2.engine.Engine.openSession(Engine.java:69)
at org.h2.engine.Engine.openSession(Engine.java:201)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
at org.h2.engine.Engine.createSession(Engine.java:161)
at org.h2.engine.Engine.createSession(Engine.java:31)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
at org.h2.Driver.connect(Driver.java:69)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$1(JDBCDataSource.java:241)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$0(JDBCDataSource.java:254)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:273)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:143)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]"
General error: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]" [50000-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
... 51 more
Caused by: java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]
at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:705)
at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
... 45 more
2023-05-15 22:40:22 database: opening D:/IP Labs/Лабораторная 1/backend/ipLab/data
org.h2.message.DbException: Файл поврежден при чтении строки: null. Возможные решения: используйте утилиту восстановления (recovery tool)
File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
at org.h2.message.DbException.get(DbException.java:194)
at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:205)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:173)
at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
at org.h2.engine.Database.getPageStore(Database.java:2739)
at org.h2.engine.Database.open(Database.java:769)
at org.h2.engine.Database.openDatabase(Database.java:319)
at org.h2.engine.Database.<init>(Database.java:313)
at org.h2.engine.Engine.openSession(Engine.java:69)
at org.h2.engine.Engine.openSession(Engine.java:201)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
at org.h2.engine.Engine.createSession(Engine.java:161)
at org.h2.engine.Engine.createSession(Engine.java:31)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
at org.h2.Driver.connect(Driver.java:69)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$1(JDBCDataSource.java:241)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$0(JDBCDataSource.java:254)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:273)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:143)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Файл поврежден при чтении строки: null. Возможные решения: используйте утилиту восстановления (recovery tool)
File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
... 46 more
Caused by: java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]
at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:705)
at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
... 43 more
2023-05-15 22:40:33 database: flush
org.h2.message.DbException: Внутренняя ошибка: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]"
General error: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]" [50000-199]
at org.h2.message.DbException.get(DbException.java:194)
at org.h2.message.DbException.convert(DbException.java:347)
at org.h2.mvstore.db.MVTableEngine$1.uncaughtException(MVTableEngine.java:90)
at org.h2.mvstore.MVStore.handleException(MVStore.java:2787)
at org.h2.mvstore.MVStore.panic(MVStore.java:441)
at org.h2.mvstore.MVStore.<init>(MVStore.java:404)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
at org.h2.engine.Database.getPageStore(Database.java:2739)
at org.h2.engine.Database.open(Database.java:769)
at org.h2.engine.Database.openDatabase(Database.java:319)
at org.h2.engine.Database.<init>(Database.java:313)
at org.h2.engine.Engine.openSession(Engine.java:69)
at org.h2.engine.Engine.openSession(Engine.java:201)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
at org.h2.engine.Engine.createSession(Engine.java:161)
at org.h2.engine.Engine.createSession(Engine.java:31)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
at org.h2.Driver.connect(Driver.java:69)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$1(JDBCDataSource.java:241)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$0(JDBCDataSource.java:254)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:273)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:143)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]"
General error: "java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]" [50000-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
... 51 more
Caused by: java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]
at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:705)
at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
... 45 more
2023-05-15 22:40:33 database: opening D:/IP Labs/Лабораторная 1/backend/ipLab/data
org.h2.message.DbException: Файл поврежден при чтении строки: null. Возможные решения: используйте утилиту восстановления (recovery tool)
File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
at org.h2.message.DbException.get(DbException.java:194)
at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:205)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:173)
at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:95)
at org.h2.engine.Database.getPageStore(Database.java:2739)
at org.h2.engine.Database.open(Database.java:769)
at org.h2.engine.Database.openDatabase(Database.java:319)
at org.h2.engine.Database.<init>(Database.java:313)
at org.h2.engine.Engine.openSession(Engine.java:69)
at org.h2.engine.Engine.openSession(Engine.java:201)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
at org.h2.engine.Engine.createSession(Engine.java:161)
at org.h2.engine.Engine.createSession(Engine.java:31)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:336)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
at org.h2.Driver.connect(Driver.java:69)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$1(JDBCDataSource.java:241)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$0(JDBCDataSource.java:254)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:273)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:143)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Файл поврежден при чтении строки: null. Возможные решения: используйте утилиту восстановления (recovery tool)
File corrupted while reading record: null. Possible solution: use the recovery tool [90030-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
... 46 more
Caused by: java.lang.IllegalStateException: The write format 2 is larger than the supported format 1, and the file was not opened in read-only mode [1.4.199/5]
at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:705)
at org.h2.mvstore.MVStore.<init>(MVStore.java:401)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
... 43 more
2023-05-15 22:42:22 database: wrong user or password; user: "SE"
org.h2.message.DbException: Неверное имя пользователя или пароль
Wrong user name or password [28000-210]
at org.h2.message.DbException.get(DbException.java:227)
at org.h2.message.DbException.get(DbException.java:203)
at org.h2.message.DbException.get(DbException.java:192)
at org.h2.engine.Engine.openSession(Engine.java:154)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$1(JDBCDataSource.java:241)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.lambda$0(JDBCDataSource.java:254)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:273)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:143)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Неверное имя пользователя или пароль
Wrong user name or password [28000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:529)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 38 more
2023-05-15 22:43:16 jdbc[3]: exception
java.sql.SQLClientInfoException: Client info name 'ApplicationName' not supported.
at org.h2.jdbc.JdbcConnection.setClientInfo(JdbcConnection.java:1573)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.populateClientAppName(GenericDataSource.java:183)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:146)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.openConnection(H2DataSource.java:74)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:103)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:102)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:128)
at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:109)
at org.jkiss.dbeaver.ext.h2.model.H2DataSource.<init>(H2DataSource.java:43)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createDataSourceImpl(H2MetaModel.java:55)
at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:106)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1205)
at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1070)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:70)
at org.jkiss.dbeaver.runtime.jobs.ConnectJob.runSync(ConnectJob.java:97)
at org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler.connectToDataSource(DataSourceHandler.java:115)
at org.jkiss.dbeaver.ui.actions.datasource.UIServiceConnectionsImpl.initConnection(UIServiceConnectionsImpl.java:87)
at org.jkiss.dbeaver.model.navigator.DBNDataSource.initializeNode(DBNDataSource.java:158)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:225)
at org.jkiss.dbeaver.model.navigator.DBNDatabaseNode.getChildren(DBNDatabaseNode.java:1)
at org.jkiss.dbeaver.model.navigator.DBNUtils.getNodeChildrenFiltered(DBNUtils.java:80)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:49)
at org.jkiss.dbeaver.ui.navigator.database.load.TreeLoadService.evaluate(TreeLoadService.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
2023-05-15 22:43:44 jdbc[3]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Столбец "KEY_SEQ" не найден
Column "KEY_SEQ" not found [42122-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:521)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
at org.h2.message.DbException.get(DbException.java:227)
at org.h2.message.DbException.get(DbException.java:203)
at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3492)
at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:337)
at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCResultSetImpl.getInt(JDBCResultSetImpl.java:500)
at org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils.safeGetInt(JDBCUtils.java:110)
at org.jkiss.dbeaver.ext.generic.model.GenericUtils.safeGetInt(GenericUtils.java:84)
at org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaModel.createConstraintColumnsImpl(GenericMetaModel.java:819)
at org.jkiss.dbeaver.ext.h2.model.H2MetaModel.createConstraintColumnsImpl(H2MetaModel.java:178)
at org.jkiss.dbeaver.ext.generic.model.ConstraintKeysCache.fetchObjectRow(ConstraintKeysCache.java:98)
at org.jkiss.dbeaver.ext.generic.model.ConstraintKeysCache.fetchObjectRow(ConstraintKeysCache.java:1)
at org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCCompositeCache.loadObjects(JDBCCompositeCache.java:360)
at org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCCompositeCache.getObjects(JDBCCompositeCache.java:120)
at org.jkiss.dbeaver.ext.generic.model.GenericTableBase.getConstraints(GenericTableBase.java:222)
at org.jkiss.dbeaver.ext.generic.model.GenericTableBase.getConstraints(GenericTableBase.java:1)
at org.jkiss.dbeaver.model.virtual.DBVUtils.getAllConstraints(DBVUtils.java:310)
at org.jkiss.dbeaver.erd.model.ERDContentProviderDefault.fillEntityFromObject(ERDContentProviderDefault.java:76)
at org.jkiss.dbeaver.erd.ui.model.ERDContentProviderDecorated.fillEntityFromObject(ERDContentProviderDecorated.java:58)
at org.jkiss.dbeaver.erd.model.ERDUtils.makeEntityFromObject(ERDUtils.java:132)
at org.jkiss.dbeaver.erd.model.ERDDiagram.fillEntities(ERDDiagram.java:288)
at org.jkiss.dbeaver.erd.ui.editor.ERDEditorEmbedded.loadFromDatabase(ERDEditorEmbedded.java:225)
at org.jkiss.dbeaver.erd.ui.editor.ERDEditorEmbedded$1.evaluate(ERDEditorEmbedded.java:172)
at org.jkiss.dbeaver.erd.ui.editor.ERDEditorEmbedded$1.evaluate(ERDEditorEmbedded.java:1)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:88)
at org.jkiss.dbeaver.ui.LoadingJob.run(LoadingJob.java:72)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
2023-05-15 22:45:44 database: flush
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.get(DbException.java:216)
at org.h2.message.DbException.convert(DbException.java:414)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
at org.h2.mvstore.db.Store.<init>(Store.java:129)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.getConnectionUrl(H2ConsoleAutoConfiguration.java:94)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:86)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$h2Console$0(H2ConsoleAutoConfiguration.java:69)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.withThreadContextClassLoader(H2ConsoleAutoConfiguration.java:78)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:69)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:645)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:208)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:199)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:94)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:85)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:261)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:235)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:52)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5144)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:886)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:252)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:926)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:486)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:210)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
at com.example.ipLab.IpLabApplication.main(IpLabApplication.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 103 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:163)
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
... 97 more
2023-05-15 22:45:46 database: flush
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.get(DbException.java:216)
at org.h2.message.DbException.convert(DbException.java:414)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
at org.h2.mvstore.db.Store.<init>(Store.java:129)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:177)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:36)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:255)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:230)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:44)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:218)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:138)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
at com.example.ipLab.IpLabApplication.main(IpLabApplication.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 64 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:163)
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
... 58 more
2023-05-15 22:45:48 database: flush
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.get(DbException.java:216)
at org.h2.message.DbException.convert(DbException.java:414)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
at org.h2.mvstore.db.Store.<init>(Store.java:129)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:41)
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:63)
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:70)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processTableResultSet(InformationExtractorJdbcDatabaseMetaDataImpl.java:64)
at org.hibernate.tool.schema.extract.internal.AbstractInformationExtractorImpl.getTables(AbstractInformationExtractorImpl.java:564)
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:122)
at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:71)
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:225)
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:126)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:284)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143)
at java.base/java.util.HashMap.forEach(HashMap.java:1421)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:140)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:336)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:415)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1425)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
at com.example.ipLab.IpLabApplication.main(IpLabApplication.java:12)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]"
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]" [50000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 68 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/IP Labs/Лабораторная 1/backend/ipLab/data.mv.db [2.1.210/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:163)
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
... 62 more

View File

@ -0,0 +1,14 @@
package com.example.ipLab.StoreDataBase.Configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEncoderConfiguration {
@Bean
public PasswordEncoder createPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,91 @@
package com.example.ipLab.StoreDataBase.Configurations;
import com.example.ipLab.StoreDataBase.Configurations.jwt.JwtFilter;
import com.example.ipLab.StoreDataBase.Controllers.UserController;
import com.example.ipLab.StoreDataBase.MVC.UserLoginMVCController;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfiguration {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private static final String LOGIN_URL = "/login";
public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
private UserService userService;
private JwtFilter jwtFilter;
public SecurityConfiguration(UserService userService) {
this.userService = userService;
this.jwtFilter = new JwtFilter(userService);
createAdminOnStartup();
createTestUsersOnStartup();
}
private void createAdminOnStartup() {
final String admin = "admin";
if (userService.getUserByLogin(admin) == null) {
log.info("Admin user successfully created");
userService.addUser(admin, admin, admin, UserRole.ADMIN, 2L);
}
}
private void createTestUsersOnStartup() {
final String[] userNames = {"user1", "user2", "user3"};
final Long[] userId = {19052L, 19053L, 20652L};
int cnt = 0;
for (String user : userNames) {
if (userService.getUserByLogin(user) == null) {
userService.addUser(user, user, user, UserRole.USER, userId[cnt]);
}
cnt++;
}
}
@Bean
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
http.cors()
.and()
.csrf().disable()
.authorizeHttpRequests((a) -> a
.requestMatchers(HttpMethod.DELETE, "/api/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.PUT, "/api/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.POST, "/api/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/api/customer/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/api/store/addStore/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/customer/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/store/addToStore/**").hasRole("ADMIN")
.requestMatchers("/api/**").authenticated()
.requestMatchers(HttpMethod.POST, UserController.URL_LOGIN).permitAll()
.requestMatchers(HttpMethod.GET, "/img/**").permitAll())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.anonymous().and().authorizeHttpRequests((a) ->
a.requestMatchers(LOGIN_URL, UserLoginMVCController.SIGNUP_URL, "/h2-console/**")
.permitAll().requestMatchers("/users").hasRole("ADMIN").anyRequest().authenticated())
.formLogin()
.loginPage(LOGIN_URL).permitAll()
.defaultSuccessUrl("/", true)
.and()
.logout().permitAll()
.logoutSuccessUrl("/login")
.and()
.userDetailsService(userService);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/css/**", "/js/**", "/templates/**", "/webjars/**", "/styles/**");
}
}

View File

@ -0,0 +1,11 @@
package com.example.ipLab.StoreDataBase.Configurations.jwt;
public class JwtException extends RuntimeException{
public JwtException(Throwable throwable) {
super(throwable);
}
public JwtException(String message) {
super(message);
}
}

View File

@ -0,0 +1,92 @@
package com.example.ipLab.StoreDataBase.Configurations.jwt;
import com.example.ipLab.StoreDataBase.Service.UserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.util.StringUtils;
import java.io.IOException;
public class JwtFilter extends AbstractPreAuthenticatedProcessingFilter {
private static final String AUTHORIZATION = "Authorization";
public static final String TOKEN_BEGIN_STR = "Bearer ";
private final UserService userService;
public JwtFilter(UserService userService) {
this.userService = userService;
}
private String getTokenFromRequest(HttpServletRequest request) {
String bearer = request.getHeader(AUTHORIZATION);
if (StringUtils.hasText(bearer) && bearer.startsWith(TOKEN_BEGIN_STR)) {
return bearer.substring(TOKEN_BEGIN_STR.length());
}
return null;
}
private void raiseException(ServletResponse response, int status, String message) throws IOException {
if (response instanceof final HttpServletResponse httpResponse) {
httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
httpResponse.setStatus(status);
final byte[] body = new ObjectMapper().writeValueAsBytes(message);
response.getOutputStream().write(body);
}
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof final HttpServletRequest httpRequest) {
final String token = getTokenFromRequest(httpRequest);
if (StringUtils.hasText(token)) {
try {
final UserDetails user = userService.loadUserByToken(token);
final UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
} catch (JwtException e) {
raiseException(response, HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return;
} catch (Exception e) {
e.printStackTrace();
raiseException(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
String.format("Internal error: %s", e.getMessage()));
return;
}
}
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (httpRequest.getRequestURI().startsWith("/api/")) {
// Для URL, начинающихся с /api/, выполняем проверку наличия токена
super.doFilter(request, response, chain);
} else {
// Для остальных URL выполняем авторизацию
chain.doFilter(request, response);
}
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String token = getTokenFromRequest(request);
// Возвращаем токен как принципала
return token;
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return new WebAuthenticationDetailsSource().buildDetails(request);
}
}

View File

@ -0,0 +1,27 @@
package com.example.ipLab.StoreDataBase.Configurations.jwt;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "jwt", ignoreInvalidFields = true)
public class JwtProperties {
private String devToken = "";
private Boolean isDev = true;
public String getDevToken() {
return devToken;
}
public void setDevToken(String devToken) {
this.devToken = devToken;
}
public Boolean isDev() {
return isDev;
}
public void setDev(Boolean dev) {
isDev = dev;
}
}

View File

@ -0,0 +1,47 @@
package com.example.ipLab.StoreDataBase.Configurations.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
@Component
public class JwtsProvider {
@Value("jwt.secret")
private String secret;
public String generateToken(String login, String role) {
Date date = Date.from(LocalDate.now().plusDays(15).atStartOfDay(ZoneId.systemDefault()).toInstant());
JwtBuilder builder = Jwts.builder()
.setSubject(login)
.setExpiration(date)
.signWith(SignatureAlgorithm.HS512, secret);
Claims claims = Jwts.claims();
claims.put("role", role);
builder.addClaims(claims);
return builder.compact();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
public String getLogin(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}

View File

@ -1,10 +1,14 @@
package com.example.ipLab.StoreDataBase.Controllers;
import com.example.ipLab.StoreDataBase.DTO.CustomerDTO;
import com.example.ipLab.StoreDataBase.Exceptions.ForbiddenException;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.Customer;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.CustomerService;
import com.example.ipLab.WebConfiguration;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -24,7 +28,7 @@ public class CustomerController {
}
@GetMapping
public List<CustomerDTO> getCustomers(){
public List<CustomerDTO> getCustomers(@AuthenticationPrincipal CustomUser user){
return customerService.getAllCustomers().stream()
.map(CustomerDTO::new)
.toList();

View File

@ -1,12 +1,15 @@
package com.example.ipLab.StoreDataBase.Controllers;
import com.example.ipLab.StoreDataBase.DTO.OrderedDTO;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.Ordered;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.CustomerService;
import com.example.ipLab.StoreDataBase.Service.OrderService;
import com.example.ipLab.StoreDataBase.Service.ProductService;
import com.example.ipLab.WebConfiguration;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@ -30,10 +33,18 @@ public class OrderedController {
}
@GetMapping
public List<OrderedDTO> getOrdereds(){
return orderedService.getAllOrders().stream()
.map(OrderedDTO::new)
.toList();
public List<OrderedDTO> getOrdereds(@AuthenticationPrincipal CustomUser user){
if (user.getRole() == UserRole.USER){
return orderedService.getOrdersByCustomerId(user.getUserID()).stream()
.map(OrderedDTO::new)
.toList();
}
else{
return orderedService.getAllOrders().stream()
.map(OrderedDTO::new)
.toList();
}
}
@PostMapping

View File

@ -1,10 +1,13 @@
package com.example.ipLab.StoreDataBase.Controllers;
import com.example.ipLab.StoreDataBase.DTO.ProductDTO;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.Product;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.ProductService;
import com.example.ipLab.WebConfiguration;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -24,10 +27,18 @@ public class ProductController {
}
@GetMapping
public List<ProductDTO> getProducts(){
return productService.getAllProducts().stream()
.map(ProductDTO::new)
.toList();
public List<ProductDTO> getProducts(@AuthenticationPrincipal CustomUser user){
if (user.getRole() == UserRole.USER){
return productService.getAllProductsWithStores().stream()
.map(ProductDTO::new)
.toList();
}
else{
return productService.getAllProducts().stream()
.map(ProductDTO::new)
.toList();
}
}
@GetMapping("/getWithStores")

View File

@ -0,0 +1,24 @@
package com.example.ipLab.StoreDataBase.Controllers;
import com.example.ipLab.StoreDataBase.DTO.UserDTO;
import com.example.ipLab.StoreDataBase.Service.UserService;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
public static final String URL_LOGIN = "/jwt/login";
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping(URL_LOGIN)
public String login(@RequestBody @Valid UserDTO userDto) {
return userService.loginAndGetToken(userDto);
}
}

View File

@ -0,0 +1,36 @@
package com.example.ipLab.StoreDataBase.DTO;
import jakarta.validation.constraints.NotBlank;
public class LoginDTO {
@NotBlank
private String login;
@NotBlank
private String password;
@NotBlank
private String passwordConfirm;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordConfirm() {
return passwordConfirm;
}
public void setPasswordConfirm(String passwordConfirm) {
this.passwordConfirm = passwordConfirm;
}
}

View File

@ -0,0 +1,49 @@
package com.example.ipLab.StoreDataBase.DTO;
import com.example.ipLab.StoreDataBase.Model.User;
import com.example.ipLab.StoreDataBase.Model.UserRole;
public class UserDTO {
private long id;
private String login;
private UserRole role;
private String password;
public UserDTO() {
}
public UserDTO(User user) {
this.id = user.getId();
this.login = user.getLogin();
this.role = user.getRole();
this.password = user.getPassword();
}
public long getId() {
return id;
}
public String getLogin() {
return login;
}
public UserRole getRole() {
return role;
}
public String getPassword() {
return password;
}
public void setLogin(String login) {
this.login = login;
}
public void setRole(UserRole role) {
this.role = role;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,8 @@
package com.example.ipLab.StoreDataBase.Exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {
}

View File

@ -0,0 +1,7 @@
package com.example.ipLab.StoreDataBase.Exceptions;
public class UserNotFoundException extends RuntimeException{
public UserNotFoundException(String login){
super(String.format("User with login: %s hasn't been found", login));
}
}

View File

@ -3,10 +3,13 @@ package com.example.ipLab.StoreDataBase.MVC;
import com.example.ipLab.StoreDataBase.DTO.CustomerDTO;
import com.example.ipLab.StoreDataBase.DTO.OrderedDTO;
import com.example.ipLab.StoreDataBase.DTO.ProductDTO;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.CustomerService;
import com.example.ipLab.StoreDataBase.Service.OrderService;
import com.example.ipLab.StoreDataBase.Service.ProductService;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
@ -26,11 +29,19 @@ public class OrderedMVCController {
}
@GetMapping
public String getOrdereds(Model model) {
model.addAttribute("orders",
orderedService.getAllOrders().stream()
.map(OrderedDTO::new)
.toList());
public String getOrdereds(Model model, @AuthenticationPrincipal CustomUser user) {
if (user.getRole() == UserRole.USER){
model.addAttribute("orders",
orderedService.getOrdersByCustomerId(user.getUserID()).stream()
.map(OrderedDTO::new)
.toList());
}
else {
model.addAttribute("orders",
orderedService.getAllOrders().stream()
.map(OrderedDTO::new)
.toList());
}
return "order";
}

View File

@ -1,13 +1,24 @@
package com.example.ipLab.StoreDataBase.MVC;
import com.example.ipLab.StoreDataBase.Configurations.SecurityConfiguration;
import com.example.ipLab.StoreDataBase.DTO.ProductDTO;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.User;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.ProductService;
import com.example.ipLab.StoreDataBase.Service.UserService;
import jakarta.validation.Valid;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@Controller
@RequestMapping("/product")
public class ProductMVCController {
@ -18,11 +29,21 @@ public class ProductMVCController {
}
@GetMapping
public String getProducts(Model model) {
model.addAttribute("products",
productService.getAllProducts().stream()
.map(ProductDTO::new)
.toList());
public String getProducts(Model model, @AuthenticationPrincipal CustomUser user) {
if (user.getRole() == UserRole.USER){
model.addAttribute("products",
productService.getAllProductsWithStores().stream()
.map(ProductDTO::new)
.toList());
}
else{
model.addAttribute("products",
productService.getAllProducts().stream()
.map(ProductDTO::new)
.toList());
}
return "product";
}

View File

@ -0,0 +1,51 @@
package com.example.ipLab.StoreDataBase.MVC;
import com.example.ipLab.StoreDataBase.DTO.LoginDTO;
import com.example.ipLab.StoreDataBase.Model.User;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.UserService;
import com.example.ipLab.StoreDataBase.util.validation.ValidationException;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(UserLoginMVCController.SIGNUP_URL)
public class UserLoginMVCController {
public static final String SIGNUP_URL = "/signup";
private final UserService userService;
public UserLoginMVCController(UserService userService) {
this.userService = userService;
}
@GetMapping
public String showSignupForm(Model model) {
model.addAttribute("userDto", new LoginDTO());
return "signup";
}
@PostMapping
public String signup(@ModelAttribute("userDto") @Valid LoginDTO userSignupDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "signup";
}
try {
final User user = userService.addUser(
userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm(), UserRole.USER, Long.parseLong("1"));
return "redirect:/login?created=" + user.getLogin();
} catch (ValidationException e) {
model.addAttribute("errors", e.getMessage());
return "signup";
}
}
}

View File

@ -0,0 +1,33 @@
package com.example.ipLab.StoreDataBase.MVC;
import com.example.ipLab.StoreDataBase.DTO.ProductDTO;
import com.example.ipLab.StoreDataBase.DTO.UserDTO;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Service.UserService;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserMVCController {
private final UserService userService;
public UserMVCController(UserService userService) {
this.userService = userService;
}
@GetMapping
@Secured({UserRole.AsString.ADMIN})
public String getUsers(Model model){
model.addAttribute("users",
userService.getAllUsers().stream()
.map(UserDTO::new)
.toList());
return "users";
}
}

View File

@ -0,0 +1,26 @@
package com.example.ipLab.StoreDataBase.Model;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
public class CustomUser extends User {
private final Long userID;
private final UserRole role;
public CustomUser(String username, String password,
Collection<? extends GrantedAuthority> authorities, Long userID, UserRole role) {
super(username, password, authorities);
this.userID = userID;
this.role = role;
}
public Long getUserID() {
return userID;
}
public UserRole getRole() {
return role;
}
}

View File

@ -0,0 +1,79 @@
package com.example.ipLab.StoreDataBase.Model;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import java.util.Objects;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
@NotBlank
private String login;
@Column
@NotBlank
private String password;
@Column
private Long userId;
private UserRole role;
public User() {
}
public User(String login, String password, Long userId) {
this(login, password, UserRole.USER, userId);
}
public User(String login, String password, UserRole role, Long userId) {
this.login = login;
this.password = password;
this.role = role;
this.userId = userId;
}
public Long getId() {
return id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserRole getRole() {
return role;
}
public Long getUserId() {
return userId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) && Objects.equals(login, user.login);
}
@Override
public int hashCode() {
return Objects.hash(id, login);
}
}

View File

@ -0,0 +1,20 @@
package com.example.ipLab.StoreDataBase.Model;
import org.springframework.security.core.GrantedAuthority;
public enum UserRole implements GrantedAuthority {
ADMIN,
USER;
private static final String PREFIX = "ROLE_";
@Override
public String getAuthority() {
return PREFIX + this.name();
}
public static final class AsString {
public static final String ADMIN = PREFIX + "ADMIN";
public static final String USER = PREFIX + "USER";
}
}

View File

@ -1,7 +1,13 @@
package com.example.ipLab.StoreDataBase.Repositories;
import com.example.ipLab.StoreDataBase.Model.Ordered;
import com.example.ipLab.StoreDataBase.Model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.Collection;
public interface OrderedRepository extends JpaRepository<Ordered, Long> {
@Query("SELECT o FROM Ordered o WHERE o.customer.id = ?1")
Collection<Ordered> findOrdersByCustomerId(Long clientId);
}

View File

@ -0,0 +1,8 @@
package com.example.ipLab.StoreDataBase.Repositories;
import com.example.ipLab.StoreDataBase.Model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findOneByLogin(String login);
}

View File

@ -52,6 +52,11 @@ public class OrderService {
return orderedRepository.findAll();
}
@Transactional
public List<Ordered> getOrdersByCustomerId(Long customerId){
return orderedRepository.findOrdersByCustomerId(customerId).stream().toList();
}
@Transactional
public Ordered updateOrder(Long id, int quantity){
final Ordered order = getOrder(id);

View File

@ -36,7 +36,6 @@ public class ProductService {
public Product getProduct(Long id){
return productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException(id));
}
@Transactional
public List<Product> getAllProducts(){
return productRepository.findAll();

View File

@ -0,0 +1,97 @@
package com.example.ipLab.StoreDataBase.Service;
import com.example.ipLab.StoreDataBase.Configurations.jwt.JwtException;
import com.example.ipLab.StoreDataBase.Configurations.jwt.JwtsProvider;
import com.example.ipLab.StoreDataBase.DTO.UserDTO;
import com.example.ipLab.StoreDataBase.Exceptions.CustomerNotFoundException;
import com.example.ipLab.StoreDataBase.Exceptions.UserNotFoundException;
import com.example.ipLab.StoreDataBase.Model.CustomUser;
import com.example.ipLab.StoreDataBase.Model.Customer;
import com.example.ipLab.StoreDataBase.Model.User;
import com.example.ipLab.StoreDataBase.Model.UserRole;
import com.example.ipLab.StoreDataBase.Repositories.UserRepository;
import com.example.ipLab.StoreDataBase.util.validation.ValidationException;
import com.example.ipLab.StoreDataBase.util.validation.ValidatorUtil;
import jakarta.transaction.Transactional;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@Service
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final ValidatorUtil validatorUtil;
private final JwtsProvider jwtProvider;
public UserService(UserRepository userRepository,
PasswordEncoder passwordEncoder,
ValidatorUtil validatorUtil,
JwtsProvider jwtProvider) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.validatorUtil = validatorUtil;
this.jwtProvider = jwtProvider;
}
@Transactional
public User addUser(String login, String password, String passwordConfirm, UserRole role, Long userId){
if (getUserByLogin(login) != null){
throw new ValidationException(String.format("User with login %s already exists", login));
}
if (!Objects.equals(password, passwordConfirm)) {
throw new ValidationException("Passwords not equals");
}
final User user = new User(login, passwordEncoder.encode(password), role, userId);
validatorUtil.validate(user);
return userRepository.save(user);
}
@Transactional
public User getUserByLogin(String login){
return userRepository.findOneByLogin(login);
}
@Transactional
public List<User> getAllUsers(){
return userRepository.findAll();
}
public UserDetails loadUserByToken(String token) throws UsernameNotFoundException {
if (!jwtProvider.validateToken(token)) {
throw new JwtException("Bad token");
}
final String userLogin = jwtProvider.getLogin(token);
if (userLogin.isEmpty()) {
throw new JwtException("Token is not contain Login");
}
return loadUserByUsername(userLogin);
}
public String loginAndGetToken(UserDTO userDto) {
final User user = getUserByLogin(userDto.getLogin());
if (user == null) {
throw new UserNotFoundException(userDto.getLogin());
}
if (!passwordEncoder.matches(userDto.getPassword(), user.getPassword())) {
throw new UserNotFoundException(user.getLogin());
}
return jwtProvider.generateToken(user.getLogin(), user.getRole().name());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
final User userEntity = getUserByLogin(username);
if (userEntity == null) {
throw new UsernameNotFoundException(username);
}
return new CustomUser(
userEntity.getLogin(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()), userEntity.getUserId(), userEntity.getRole());
}
}

View File

@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import java.nio.file.AccessDeniedException;
import java.util.stream.Collectors;
@ControllerAdvice(annotations = RestController.class)
@ -35,6 +36,14 @@ public class AdviceController {
return handleException(validationException);
}
@ExceptionHandler({
AccessDeniedException.class
})
public ResponseEntity<Object> handleAccessDeniedException(Throwable e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleUnknownException(Throwable e) {
e.printStackTrace();

View File

@ -6,4 +6,8 @@ public class ValidationException extends RuntimeException{
public ValidationException(Set<String> errors){
super(String.join("\n", errors));
}
public ValidationException(String error){
super(error);
}
}

View File

@ -2,11 +2,18 @@ package com.example.ipLab;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("login");
}
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**").allowedMethods("*");

View File

@ -9,3 +9,6 @@ spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
jwt.dev-token=my-secret-jwt
jwt.dev=true
jwt.secret = my-secret-jwt

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -5,7 +5,7 @@
<head>
</head>
<body>
<div layout:fragment="content">
<div sec:authorize="hasRole('ROLE_ADMIN')" layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/store/add}" method="post">
<div class="mb-3">

View File

@ -6,49 +6,59 @@
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/customer/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/customer/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
</div>
<div class="table-responsive">
<table class="table table-success table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Фамилия</th>
<th scope="col">Имя</th>
<th scope="col">Отчество</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="customer, iterator: ${customers}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${customer.Id}"/>
<td th:text="${customer.lastName}"/>
<td th:text="${customer.firstName}"/>
<td th:text="${customer.middleName}"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/customer/edit/{id}(id=${customer.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${customer.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/customer/delete/{id}(id=${customer.id})}" method="post">
<button th:id="'remove-' + ${customer.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="table-responsive">
<table class="table table-success table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Фамилия</th>
<th scope="col">Имя</th>
<th scope="col">Отчество</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="customer, iterator: ${customers}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${customer.lastName}"/>
<td th:text="${customer.firstName}"/>
<td th:text="${customer.middleName}"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/customer/edit/{id}(id=${customer.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${customer.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/customer/delete/{id}(id=${customer.id})}" method="post">
<button th:id="'remove-' + ${customer.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
<div sec:authorize="hasRole('ROLE_USER')">
<div>
<h2>Forbidden</h2>
<a href="/">На главную</a>
</div>
</div>
</div>
</body>

View File

@ -23,7 +23,7 @@
</button>
<div class="d-flex flex-row ml-3 ms-3 mt-auto mb-auto align-items-center">
<a>
<img src="/logo.png" alt="*" width="60" height="60" class="align-text-top"></img>
<img src="/img/logo.png" alt="*" width="60" height="60" class="align-text-top"/>
</a>
<div id="logoName">
<a href="/">boxStore</a>
@ -31,7 +31,7 @@
</div>
<div class="navbar-collapse collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav" id="headerNavigation">
<a class="nav-link headNav" href="/customer"
<a sec:authorize="hasRole('ROLE_ADMIN')" class="nav-link headNav" href="/customer"
th:classappend="${#strings.equals(activeLink, '/customer')} ? 'active' : ''">Клиенты</a>
<a class="nav-link headNav" href="/store"
th:classappend="${#strings.equals(activeLink, '/store')} ? 'active' : ''">Магазины</a>
@ -39,8 +39,10 @@
th:classappend="${#strings.equals(activeLink, '/product')} ? 'active' : ''">Товары</a>
<a class="nav-link headNav" href="/order"
th:classappend="${#strings.equals(activeLink, '/order')} ? 'active' : ''">Заказы</a>
<a class="nav-link headNav" href="/store/addToStore"
<a sec:authorize="hasRole('ROLE_ADMIN')" class="nav-link headNav" href="/store/addToStore"
th:classappend="${#strings.equals(activeLink, '/order')} ? 'active' : ''">Доставка</a>
<a sec:authorize="!isAuthenticated()" class="nav-link headNav" href="/login">Войти</a>
<a sec:authorize="isAuthenticated()" class="nav-link headNav" href="/logout">Выйти</a>
</ul>
</div>
</div>

View File

@ -6,7 +6,7 @@
</head>
<body>
<div layout:fragment="content">
<h2>Добро пожаловать!</h2>
<h2>Добро пожаловать, <span sec:authentication="name"></span>!</h2>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div class="container-fluid" layout:fragment="content">
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
Пользователь не найден или пароль указан не верно
</div>
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
Выход успешно произведен
</div>
<div th:if="${param.created}" class="alert alert-success margin-bottom">
Пользователь '<span th:text="${param.created}"></span>' успешно создан
</div>
<div class="row justify-content-center align-items-center vh-100">
<div class="col-sm-6 col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Авторизация</h5>
<form th:action="@{/login}" method="post">
<div class="mb-3">
<label htmlFor="login">Логин</label>
<input type="text" name="username" id="username" class="form-control"
placeholder="Логин" required="true" autofocus="true"/>
</div>
<div class="mb-3">
<label htmlFor="login">Пароль</label>
<input type="password" name="password" id="password" class="form-control"
placeholder="Пароль" required="true"/>
</div>
<button type="submit" class="btn btn-primary button-fixed">Войти</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -6,7 +6,7 @@
</head>
<body>
<div layout:fragment="content">
<div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<a class="btn btn-success button-fixed"
th:href="@{/order/edit/}">
<i class="fa-solid fa-plus"></i> Добавить

View File

@ -6,7 +6,7 @@
</head>
<body>
<div layout:fragment="content">
<div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<a class="btn btn-success button-fixed "
th:href="@{/product/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
@ -19,7 +19,7 @@
<th scope="col">#</th>
<th scope="col">Название товара</th>
<th scope="col">Название магазина</th>
<th scope="col"></th>
<th sec:authorize="hasRole('ROLE_ADMIN')" scope="col"></th>
</tr>
</thead>
<tbody>
@ -27,7 +27,7 @@
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${product.productName}"/>
<td th:text="${product.storeName}"/>
<td style="width: 10%">
<td sec:authorize="hasRole('ROLE_ADMIN')" style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/product/edit/{id}(id=${product.id})}">

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container container-padding" layout:fragment="content">
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
<form action="#" th:action="@{/signup}" th:object="${LoginDTO}" method="post">
<div class="mb-3">
<input type="text" class="form-control" th:field="${LoginDTO.login}"
placeholder="Логин" required="true" autofocus="true" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${LoginDTO.password}"
placeholder="Пароль" required="true" minlength="6" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${LoginDTO.passwordConfirm}"
placeholder="Пароль (подтверждение)" required="true" minlength="6" maxlength="64"/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-success button-fixed">Создать</button>
<a class="btn btn-primary button-fixed" href="/login">Назад</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -6,7 +6,7 @@
</head>
<body>
<div layout:fragment="content">
<div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<a class="btn btn-success button-fixed"
th:href="@{/store/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
@ -18,14 +18,14 @@
<tr>
<th scope="col">#</th>
<th scope="col">Название магазина</th>
<th scope="col"></th>
<th sec:authorize="hasRole('ROLE_ADMIN')" scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="store, iterator: ${stores}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${store.storeName}"/>
<td style="width: 10%">
<td sec:authorize="hasRole('ROLE_ADMIN')" style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/store/edit/{id}(id=${store.id})}">

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="table-responsive">
<table class="table table-success table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Логин</th>
<th scope="col">Роль</th>
</tr>
</thead>
<tbody>
<tr th:each="user, iterator: ${users}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${user.login}"/>
<td th:text="${user.role}"/>
</tr>
</tbody>
</table>
</div>
</body>
</html>

View File

@ -1,10 +1,14 @@
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
import { useState, useEffect } from 'react';
import Header from './components/common/Header';
import CustomerPage from './components/pages/customerPage';
import StorePage from './components/pages/storePage';
import ProductPage from './components/pages/productPage';
import OrderPage from './components/pages/orderPage';
import AddToStorePage from './components/pages/addToStorePage'
import AddToStorePage from './components/pages/addToStorePage';
import LoginPage from './components/pages/loginPage';
import Logout from './components/pages/logout';
import ForbiddenPage from './components/pages/forbiddenPage'
import './styleSite.css';
function Router(props) {
@ -13,14 +17,34 @@ function Router(props) {
export default function App() {
const routes = [
{ index: true, element: <CustomerPage/> },
{ path: 'customer', element: <CustomerPage/>, label:'Покупатели'},
{ index: true, element: <StorePage/> },
localStorage.getItem("role") === "ADMIN" && { path: 'customer', element: <CustomerPage/>, label:'Покупатели'},
localStorage.getItem("role") !== "ADMIN" && { path: 'customer', element: <ForbiddenPage/>},
{ path: 'store', element: <StorePage/>, label: 'Магазины' },
{ path: 'product', element: <ProductPage/>, label: 'Товары' },
{ path: 'order', element: <OrderPage/>, label: 'Заказы'},
{ path: 'addToStore', element: <AddToStorePage/>, label: 'Доставка'}
localStorage.getItem("role") === "ADMIN" && { path: 'addToStore', element: <AddToStorePage/>, label: 'Доставка'},
localStorage.getItem("role") !== "ADMIN" && { path: 'addToStore', element: <ForbiddenPage/>},
{ path: '/login', element: <LoginPage/>},
{ path: '/logout', element: <Logout/>}
];
const links = routes.filter(route => route.hasOwnProperty('label'));
const [token, setToken] = useState(localStorage.getItem('token'));
useEffect(() => {
function handleStorageChange() {
setToken(localStorage.getItem('token'));
}
window.addEventListener('storage', handleStorageChange);
return () => {
window.removeEventListener('storage', handleStorageChange);
};
}, []);
const rootRoute = [
{ path: '/', element: render(links), children: routes }
];
@ -29,7 +53,7 @@ export default function App() {
console.info('render links');
return (
<>
<Header links={links} />
<Header token={token} links={links} />
<div className="container-fluid">
<Outlet />
</div>

View File

@ -0,0 +1,24 @@
import React from 'react'
import { useNavigate} from "react-router-dom";
import { useEffect } from 'react';
const checkLogin = (Component) => {
const AuthenticatedComponent = (props) => {
const navigate = useNavigate();
const token = localStorage.getItem('token');
useEffect(() => {
if (!token || token === 'undefined') {
navigate('/login');
}
}, [navigate, token]);
if (token && token !== 'undefined') {
return <Component {...props} />
}
return null;
}
return AuthenticatedComponent;
}
export default checkLogin;

View File

@ -10,7 +10,7 @@ export default function Header(props){
<img src="logo.png" alt="*" width="60" height="60" className="align-text-top"></img>
</a>
<div id="logoName">
<a href="customer">boxStore</a>
<a href="store">boxStore</a>
</div>
</div>
<nav className="navbar navbar-expand-md">
@ -31,6 +31,15 @@ export default function Header(props){
</li>
)
}
{props.token && props.token !== undefined ?
<NavLink className="nav-link navigationCaption" to="/logout">
<div>Выход</div>
</NavLink>
:
<NavLink className="nav-link navigationCaption" to="/login">
<div>Вход</div>
</NavLink>
}
</ul>
</div>
</div>

View File

@ -15,15 +15,15 @@ export default function Toolbar(props) {
return (
<div className="btn-group my-2 mx-4" role="group">
<button type="button" className={`btn btn-success ${styles.btn}`} onClick={add}>
{localStorage.getItem("role") === "ADMIN" && <button type="button" className={`btn btn-success ${styles.btn}`} onClick={add}>
Добавить
</button>
<button type="button" className={`btn btn-warning ${styles.btn}`} onClick={edit} >
</button>}
{localStorage.getItem("role") === "ADMIN" && <button type="button" className={`btn btn-warning ${styles.btn}`} onClick={edit} >
Изменить
</button >
<button type="button" className={`btn btn-danger ${styles.btn}`} onClick={remove}>
</button >}
{localStorage.getItem("role") === "ADMIN" && <button type="button" className={`btn btn-danger ${styles.btn}`} onClick={remove}>
Удалить
</button >
</button >}
</div >
);
}

View File

@ -7,9 +7,9 @@ export default function ToolbarOrder(props) {
return (
<div className="btn-group my-2 mx-4" role="group">
<button type="button" className={`btn btn-success ${styles.btn}`} onClick={add}>
{localStorage.getItem("role") === "ADMIN" && <button type="button" className={`btn btn-success ${styles.btn}`} onClick={add}>
Добавить
</button>
</button>}
</div >
);
}

View File

@ -2,8 +2,9 @@ import Product from "../../models/product"
import Store from "../../models/store"
import DataService from '../../services/DataService';
import { useState, useEffect} from "react";
import checkLogin from '../../checkLogin';
export default function AddToStorePage(){
function AddToStorePage(){
const getStoreUrl = 'store';
const getProductUrl = 'product/getWithoutStores'
const url = 'store/'
@ -86,4 +87,6 @@ export default function AddToStorePage(){
</div>
</>
);
}
}
export default checkLogin(AddToStorePage);

View File

@ -1,8 +1,9 @@
import Customer from "../../models/customer"
import CustomerTable from '../common/customerTable'
import { useState, useEffect} from "react";
import checkLogin from '../../checkLogin';
export default function CustomerPage(){
function CustomerPage(){
const url = 'customer';
const getUrl = 'customer/';
const transformer = (data) => new Customer(data);
@ -27,7 +28,7 @@ export default function CustomerPage(){
}
return(
<article className="h-100 mt-0 mb-0 d-flex flex-column justify-content-between">
<CustomerTable headers={catalogCustomerHeaders}
{localStorage.getItem("role") === "ADMIN" && <CustomerTable headers={catalogCustomerHeaders}
getAllUrl={url}
url={url}
getUrl={getUrl}
@ -47,7 +48,14 @@ export default function CustomerPage(){
<label className="form-label" forhtml="middleName">Отчество</label>
<input className="form-control" type="text" id="middleName" value={data.middleName} onChange={handleFormChange} required="required"/>
</div>
</CustomerTable>
</CustomerTable>}
{localStorage.getItem("role") !== "ADMIN" &&
<div>
<h2>Forbidden</h2>
<a href="/">На главную</a>
</div>}
</article>
)
}
}
export default checkLogin(CustomerPage);

View File

@ -0,0 +1,8 @@
export default function ForbiddenPage(){
return(
<div>
<h2>Forbidden</h2>
<a href="/">На главную</a>
</div>
)
}

View File

@ -0,0 +1,50 @@
import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useNavigate} from "react-router-dom";
import DataService from '../../services/DataService'
export default function LoginPage() {
const [loginData, setLoginData] = useState({ login: '', password: '' });
const hostURL = 'http://localhost:8080';
const handleLoginSubmit = (e) => {
e.preventDefault();
login(loginData.login, loginData.password);
};
const login = async function (login, password) {
console.log(localStorage.getItem('token'));
let loginFlag = await DataService.login(hostURL + "/jwt/login", login, password).catch(() => {alert("Wrong login or password!");});
if (loginFlag) {
window.dispatchEvent(new Event("storage"));
console.log("Успешный вход");
window.location.replace("/store");
}
}
return (
<div className="container-fluid">
<div className="row justify-content-center align-items-center vh-100">
<div className="col-sm-6 col-md-4">
<div className="card">
<div className="card-body">
<h5 className="card-title">Авторизация</h5>
<form onSubmit={handleLoginSubmit}>
<div className="form-group mb-3">
<label htmlFor="login">Логин</label>
<input type="text" className="form-control" id="login" value={loginData.login} onChange={(e) => setLoginData({ ...loginData, login: e.target.value })} />
</div>
<div className="form-group mb-3">
<label htmlFor="loginPassword">Пароль</label>
<input type="password" className="form-control" id="loginPassword" value={loginData.password} onChange={(e) => setLoginData({ ...loginData, password: e.target.value })} />
</div>
<button type="submit" className="btn btn-primary">Вход</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,20 @@
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
function Logout() {
const navigate = useNavigate();
useEffect(() => {
// Удаление токена из localStorage или другого места
localStorage.removeItem('token');
localStorage.removeItem("user");
localStorage.removeItem("role");
window.dispatchEvent(new Event("storage"));
// Перенаправление пользователя на страницу входа или другую страницу
navigate('/login');
}, [navigate]);
return null;
}
export default Logout;

View File

@ -3,8 +3,9 @@ import Product from "../../models/product"
import Customer from "../../models/customer";
import OrderTable from '../common/orderTable'
import { useState, useEffect} from "react";
import checkLogin from '../../checkLogin';
export default function OrderPage(){
function OrderPage(){
const url = 'order';
const getUrl = 'order/';
const getCustomerUrl = 'customer';
@ -105,4 +106,5 @@ export default function OrderPage(){
</OrderTable>
</article>
)
}
}
export default checkLogin(OrderPage);

View File

@ -1,8 +1,9 @@
import Product from "../../models/product"
import ProductTable from '../common/productTable'
import { useState, useEffect} from "react";
import checkLogin from "../../checkLogin";
export default function ProductPage(){
function ProductPage(){
const url = 'product';
const getUrl = 'product/';
const transformer = (data) => new Product(data);
@ -41,4 +42,6 @@ export default function ProductPage(){
</ProductTable>
</article>
)
}
}
export default checkLogin(ProductPage);

View File

@ -1,8 +1,9 @@
import Store from "../../models/store"
import StoreTable from '../common/storeTable'
import { useState, useEffect} from "react";
import checkLogin from "../../checkLogin";
export default function StorePage(){
function StorePage(){
const url = 'store';
const getUrl = 'store/';
const transformer = (data) => new Store(data);
@ -40,4 +41,6 @@ export default function StorePage(){
</StoreTable>
</article>
)
}
}
export default checkLogin(StorePage);

View File

@ -12,32 +12,60 @@ function toJSON(data) {
return jsonObj;
}
const getTokenForHeader = function () {
return "Bearer " + localStorage.getItem("token");
}
export default class DataService {
static dataUrlPrefix = 'http://localhost:8080/api/';
static async readAll(url, transformer) {
const response = await axios.get(this.dataUrlPrefix + url);
const response = await axios.get(this.dataUrlPrefix + url, {headers: {"Authorization": getTokenForHeader()}});
console.log(response);
return response.data.map(item => transformer(item));
}
static async read(url, transformer) {
const response = await axios.get(this.dataUrlPrefix + url);
const response = await axios.get(this.dataUrlPrefix + url, {headers: {"Authorization": getTokenForHeader()}});
return transformer(response.data);
}
static async create(url, data) {
const response = await axios.post(this.dataUrlPrefix + url, data);
const response = await axios.post(this.dataUrlPrefix + url, data, {headers: {"Authorization": getTokenForHeader()}});
return true;
}
static async update(url, data) {
const response = await axios.put(this.dataUrlPrefix + url, data);
const response = await axios.put(this.dataUrlPrefix + url, data, {headers: {"Authorization": getTokenForHeader()}});
return true;
}
static async delete(url) {
const response = await axios.delete(this.dataUrlPrefix + url);
const response = await axios.delete(this.dataUrlPrefix + url, {headers: {"Authorization": getTokenForHeader()}});
return response.data.id;
}
static async login(url, login, password){
const response = await axios.post(url, toJSON({login: login, password: password}))
console.log("status " + response.status);
if (response.status === 200) {
const result = response.data;
console.log(result);
localStorage.setItem("token", result);
localStorage.setItem("user", login);
let jwtData = result.split('.')[1]
let decodedJwtJsonData = window.atob(jwtData);
let decodedJwtData = JSON.parse(decodedJwtJsonData);
let role = decodedJwtData.role;
localStorage.setItem("role", role.toUpperCase());
return true;
} else {
console.error("BAD USER!!!!!");
localStorage.removeItem("token");
localStorage.removeItem("user");
localStorage.removeItem("role");
return false;
}
}
}