chore(*): restore from backup
this project was archived and never moved to my new gittea instance, until now
This commit is contained in:
commit
3e62ad946d
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/target/
|
||||
/build/
|
||||
/.classpath
|
||||
/.project
|
||||
.settings/
|
||||
/cryptonote.log
|
||||
/.idea
|
||||
/bin/
|
||||
.springBeans
|
||||
cryptonote.iml
|
||||
mvnw
|
||||
mvnw.cmd
|
||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"conventionalCommits.scopes": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
96
pom.xml
Normal file
96
pom.xml
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.jkgroller.cryptonote</groupId>
|
||||
<artifactId>cryptonote-api</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>cryptonote-api</name>
|
||||
<description>API for encrypting notes.</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.5.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>13</java.version>
|
||||
<crnk.version>3.1.20191113192440</crnk.version>
|
||||
<commons-codec.version>1.14</commons-codec.version>
|
||||
<mapstruct.version>1.3.1.Final</mapstruct.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jcenter</id>
|
||||
<url>https://jcenter.bintray.com/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.crnk</groupId>
|
||||
<artifactId>crnk-setup-spring-boot2</artifactId>
|
||||
<version>${crnk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>cryptonote-api</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
20
src/main/java/com/jkgroller/cryptonote/CryptonoteApi.java
Normal file
20
src/main/java/com/jkgroller/cryptonote/CryptonoteApi.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jkgroller.cryptonote;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class CryptonoteApi {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CryptonoteApi.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
package com.jkgroller.cryptonote.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
|
||||
import org.springframework.security.crypto.keygen.KeyGenerators;
|
||||
|
||||
@Configuration
|
||||
public class KeyGeneratorConfig {
|
||||
|
||||
private final int ENCRYPTION_KEY_LENGTH;
|
||||
|
||||
private final int USERNAME_LENGTH;
|
||||
|
||||
private final int PASSWORD_LENGTH;
|
||||
|
||||
private final int IDENTIFIER_LENGTH;
|
||||
|
||||
/**
|
||||
* This is how you inject a value from a properties file into a constant.
|
||||
*/
|
||||
public KeyGeneratorConfig(@Value("${encryption.key.length}") int encryptKeyLength
|
||||
, @Value("${username.length}") int userNameLength
|
||||
, @Value("${password.length}") int passwordLength
|
||||
, @Value("${identifier.length}") int identifierLength) {
|
||||
this.ENCRYPTION_KEY_LENGTH = encryptKeyLength;
|
||||
this.USERNAME_LENGTH = userNameLength;
|
||||
this.PASSWORD_LENGTH = passwordLength;
|
||||
this.IDENTIFIER_LENGTH = identifierLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "encryptionKeyGenerator")
|
||||
public BytesKeyGenerator encryptionKeyGenerator() {
|
||||
return KeyGenerators.secureRandom(ENCRYPTION_KEY_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "userNameGenerator")
|
||||
public BytesKeyGenerator userNameGenerator() {
|
||||
return KeyGenerators.secureRandom(USERNAME_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "passwordGenerator")
|
||||
public BytesKeyGenerator passwordGenerator() {
|
||||
return KeyGenerators.secureRandom(PASSWORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "identifierGenerator")
|
||||
public BytesKeyGenerator identifierGenerator() {
|
||||
return KeyGenerators.secureRandom(IDENTIFIER_LENGTH);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.jkgroller.cryptonote.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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 PasswordEncoderConfig {
|
||||
|
||||
private final int PASSWORD_ENCRYPTION_STRENGTH;
|
||||
|
||||
/**
|
||||
* This is how you inject a value from a properties file into a constant.
|
||||
*/
|
||||
public PasswordEncoderConfig(@Value("${password.encryption.strength}") int passwordEncryptionStrength) {
|
||||
this.PASSWORD_ENCRYPTION_STRENGTH = passwordEncryptionStrength;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public PasswordEncoder createPasswordEncoderBean() {
|
||||
return new BCryptPasswordEncoder(PASSWORD_ENCRYPTION_STRENGTH);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.jkgroller.cryptonote.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param httpSecurity
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
||||
//httpSecurity.authorizeRequests().antMatchers("/v1/userAccounts/**").permitAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param web
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/v1/userAccounts/**", "/h2/**", "/v1/notes/**");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.jkgroller.cryptonote.converter;
|
||||
|
||||
import com.jkgroller.cryptonote.entity.AccountEntity;
|
||||
import com.jkgroller.cryptonote.service.to.AccountTO;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface AccountEntityConverter {
|
||||
|
||||
AccountTO accountEntityToAccountTO(AccountEntity accountEntity);
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.jkgroller.cryptonote.converter;
|
||||
|
||||
import com.jkgroller.cryptonote.resource.UserAccountResource;
|
||||
import com.jkgroller.cryptonote.service.to.AccountTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface AccountTOConverter {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param accountTO
|
||||
* @return
|
||||
*/
|
||||
@Mapping(target = "credentialsAttribute.userName", source = "accountTO.userName")
|
||||
@Mapping(target = "credentialsAttribute.password", source = "accountTO.password")
|
||||
UserAccountResource accountTOToUserAccountResource(AccountTO accountTO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.jkgroller.cryptonote.converter;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface NoteEntityConverter {
|
||||
|
||||
//NoteTO noteEntityToNoteTO(NoteEntity noteEntity);
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.jkgroller.cryptonote.converter;
|
||||
|
||||
import com.jkgroller.cryptonote.resource.NoteResource;
|
||||
import com.jkgroller.cryptonote.service.to.CreateNoteRequestTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface NoteResourceConverter {
|
||||
|
||||
@Mapping(target = "userName", source = "credentialsAttribute.userName")
|
||||
@Mapping(target = "password", source = "credentialsAttribute.password")
|
||||
@Mapping(target = "noteName", source = "name")
|
||||
@Mapping(target = "noteContents", source = "contents")
|
||||
CreateNoteRequestTO noteResourceToCreateEncryptedNoteRequestTO(NoteResource noteResource);
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.jkgroller.cryptonote.converter;
|
||||
|
||||
import com.jkgroller.cryptonote.resource.NoteResource;
|
||||
import com.jkgroller.cryptonote.service.to.NoteTO;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface NoteTOConverter {
|
||||
|
||||
NoteResource noteTOToNoteResource(NoteTO noteTO);
|
||||
|
||||
}
|
||||
177
src/main/java/com/jkgroller/cryptonote/entity/AccountEntity.java
Normal file
177
src/main/java/com/jkgroller/cryptonote/entity/AccountEntity.java
Normal file
@ -0,0 +1,177 @@
|
||||
package com.jkgroller.cryptonote.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity(name = "account")
|
||||
public class AccountEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String identifier;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String userName;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String passwordHash;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] encryptedSurrogateKey;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] surrogateKeySalt;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String role;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime creationDateTime;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime lastLoginDateTime;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userName
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param passwordHash
|
||||
*/
|
||||
public void setPasswordHash(String passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param role
|
||||
*/
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
*/
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LocalDateTime getCreationDateTime() {
|
||||
return creationDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param creationDateTime
|
||||
*/
|
||||
public void setCreationDateTime(LocalDateTime creationDateTime) {
|
||||
this.creationDateTime = creationDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getEncryptedSurrogateKey() {
|
||||
return encryptedSurrogateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param encryptedSurrogateKey
|
||||
*/
|
||||
public void setEncryptedSurrogateKey(byte[] encryptedSurrogateKey) {
|
||||
this.encryptedSurrogateKey = encryptedSurrogateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public LocalDateTime getLastLoginDateTime() {
|
||||
return lastLoginDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastLoginDateTime
|
||||
*/
|
||||
public void setLastLoginDateTime(LocalDateTime lastLoginDateTime) {
|
||||
this.lastLoginDateTime = lastLoginDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getSurrogateKeySalt() {
|
||||
return surrogateKeySalt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param surrogateKeySalt
|
||||
*/
|
||||
public void setSurrogateKeySalt(byte[] surrogateKeySalt) {
|
||||
this.surrogateKeySalt = surrogateKeySalt;
|
||||
}
|
||||
}
|
||||
145
src/main/java/com/jkgroller/cryptonote/entity/NoteEntity.java
Normal file
145
src/main/java/com/jkgroller/cryptonote/entity/NoteEntity.java
Normal file
@ -0,0 +1,145 @@
|
||||
package com.jkgroller.cryptonote.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity(name = "note")
|
||||
public class NoteEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String identifier;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] key;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] keySalt;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] name;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] nameSalt;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] contents;
|
||||
|
||||
@Column(nullable = false)
|
||||
private byte[] contentsSalt;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param identifier
|
||||
*/
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
*/
|
||||
public void setKey(byte[] key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public void setName(byte[] name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents
|
||||
*/
|
||||
public void setContents(byte[] contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getKeySalt() {
|
||||
return keySalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keySalt
|
||||
*/
|
||||
public void setKeySalt(byte[] keySalt) {
|
||||
this.keySalt = keySalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getNameSalt() {
|
||||
return nameSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameSalt
|
||||
*/
|
||||
public void setNameSalt(byte[] nameSalt) {
|
||||
this.nameSalt = nameSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getContentsSalt() {
|
||||
return contentsSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentsSalt
|
||||
*/
|
||||
public void setContentsSalt(byte[] contentsSalt) {
|
||||
this.contentsSalt = contentsSalt;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.jkgroller.cryptonote.entity.repository;
|
||||
|
||||
import com.jkgroller.cryptonote.entity.AccountEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public interface AccountEntityRepository extends JpaRepository<AccountEntity, Integer> {
|
||||
|
||||
AccountEntity findAccountByUserName(String userName);
|
||||
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.jkgroller.cryptonote.entity.repository;
|
||||
|
||||
import com.jkgroller.cryptonote.entity.NoteEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface NoteEntityRepository extends JpaRepository<NoteEntity, Integer> {
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.jkgroller.cryptonote.enums;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum AccountRole {
|
||||
USER,
|
||||
ADMIN
|
||||
}
|
||||
36
src/main/java/com/jkgroller/cryptonote/resource/Account.java
Normal file
36
src/main/java/com/jkgroller/cryptonote/resource/Account.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.jkgroller.cryptonote.resource;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.jkgroller.cryptonote.resource.attribute.CredentialsAttribute;
|
||||
import io.crnk.core.resource.annotations.JsonApiField;
|
||||
import io.crnk.core.resource.annotations.JsonApiId;
|
||||
|
||||
/**
|
||||
* Base class for the different types of account resources there may be. Will likely be a resource in the future.
|
||||
*/
|
||||
public class Account {
|
||||
|
||||
@JsonApiId
|
||||
private String identifier;
|
||||
|
||||
@JsonProperty("credentials")
|
||||
@JsonApiField(readable = true, postable = false, patchable = false, deletable = false)
|
||||
private CredentialsAttribute credentialsAttribute;
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public CredentialsAttribute getCredentialsAttribute() {
|
||||
return credentialsAttribute;
|
||||
}
|
||||
|
||||
public void setCredentialsAttribute(CredentialsAttribute credentialsAttribute) {
|
||||
this.credentialsAttribute = credentialsAttribute;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package com.jkgroller.cryptonote.resource;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.jkgroller.cryptonote.resource.attribute.CredentialsAttribute;
|
||||
import io.crnk.core.resource.annotations.JsonApiField;
|
||||
import io.crnk.core.resource.annotations.JsonApiId;
|
||||
import io.crnk.core.resource.annotations.JsonApiResource;
|
||||
|
||||
@JsonApiResource(type = "note", resourcePath = "notes")
|
||||
public class NoteResource {
|
||||
|
||||
@JsonApiId
|
||||
private String identifier;
|
||||
|
||||
private String name;
|
||||
|
||||
private String contents;
|
||||
|
||||
@JsonProperty("credentials")
|
||||
@JsonApiField(readable = false, postable = true, patchable = false, deletable = false)
|
||||
private CredentialsAttribute credentialsAttribute;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
*/
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents
|
||||
*/
|
||||
public void setContents(String contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public CredentialsAttribute getCredentialsAttribute() {
|
||||
return credentialsAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param credentialsAttribute
|
||||
*/
|
||||
public void setCredentialsAttribute(CredentialsAttribute credentialsAttribute) {
|
||||
this.credentialsAttribute = credentialsAttribute;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.jkgroller.cryptonote.resource;
|
||||
|
||||
import io.crnk.core.resource.annotations.JsonApiResource;
|
||||
|
||||
@JsonApiResource(type = "userAccount", resourcePath = "userAccounts")
|
||||
public class UserAccountResource extends Account {
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.jkgroller.cryptonote.resource.attribute;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CredentialsAttribute {
|
||||
|
||||
private String userName;
|
||||
|
||||
private String password;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userName
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.jkgroller.cryptonote.resource.repository;
|
||||
|
||||
import com.jkgroller.cryptonote.converter.NoteResourceConverter;
|
||||
import com.jkgroller.cryptonote.converter.NoteTOConverter;
|
||||
import com.jkgroller.cryptonote.resource.NoteResource;
|
||||
import com.jkgroller.cryptonote.service.NoteService;
|
||||
import com.jkgroller.cryptonote.service.to.CreateNoteRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.CreateNoteResponseTO;
|
||||
import io.crnk.core.exception.BadRequestException;
|
||||
import io.crnk.core.queryspec.QuerySpec;
|
||||
import io.crnk.core.repository.ResourceRepository;
|
||||
import io.crnk.core.resource.list.ResourceList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class NoteResourceRepository implements ResourceRepository<NoteResource, String> {
|
||||
|
||||
@Autowired
|
||||
private NoteService noteService;
|
||||
|
||||
@Autowired
|
||||
private NoteResourceConverter noteResourceConverter;
|
||||
|
||||
@Autowired
|
||||
private NoteTOConverter noteTOConverter;
|
||||
|
||||
@Override
|
||||
public Class<NoteResource> getResourceClass() {
|
||||
return NoteResource.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteResource findOne(String s, QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceList<NoteResource> findAll(QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceList<NoteResource> findAll(Collection<String> collection, QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends NoteResource> S save(S s) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends NoteResource> S create(S s) {
|
||||
|
||||
CreateNoteRequestTO createNoteRequestTO = noteResourceConverter.noteResourceToCreateEncryptedNoteRequestTO(s);
|
||||
CreateNoteResponseTO createNoteResponseTO = noteService.createNote(createNoteRequestTO);
|
||||
|
||||
return (S) noteTOConverter.noteTOToNoteResource(createNoteResponseTO.getNoteTO());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String s) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
package com.jkgroller.cryptonote.resource.repository;
|
||||
|
||||
import com.jkgroller.cryptonote.converter.AccountTOConverter;
|
||||
import com.jkgroller.cryptonote.resource.UserAccountResource;
|
||||
import com.jkgroller.cryptonote.service.AccountService;
|
||||
import com.jkgroller.cryptonote.service.to.CreateNewUserAccountResponseTO;
|
||||
import io.crnk.core.exception.BadRequestException;
|
||||
import io.crnk.core.queryspec.QuerySpec;
|
||||
import io.crnk.core.repository.ResourceRepository;
|
||||
import io.crnk.core.resource.list.ResourceList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class UserAccountResourceRepository implements ResourceRepository<UserAccountResource, String> {
|
||||
|
||||
@Autowired
|
||||
private AccountService accountService;
|
||||
|
||||
@Autowired
|
||||
private AccountTOConverter accountTOConverter;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Class<UserAccountResource> getResourceClass() {
|
||||
return UserAccountResource.class;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s
|
||||
* @param querySpec
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserAccountResource findOne(String s, QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param querySpec
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ResourceList<UserAccountResource> findAll(QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param collection
|
||||
* @param querySpec
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ResourceList<UserAccountResource> findAll(Collection<String> collection, QuerySpec querySpec) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s
|
||||
* @param <S>
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public <S extends UserAccountResource> S save(S s) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s
|
||||
* @param <S>
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public <S extends UserAccountResource> S create(S s) {
|
||||
|
||||
CreateNewUserAccountResponseTO createNewUserAccountResponseTO = accountService.createNewUserAccount();
|
||||
|
||||
return (S) accountTOConverter.accountTOToUserAccountResource(createNewUserAccountResponseTO.getAccountTO());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
@Override
|
||||
public void delete(String s) {
|
||||
throw new BadRequestException("Unsupported.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.service.to.CreateNewUserAccountResponseTO;
|
||||
import com.jkgroller.cryptonote.service.to.RetrieveUserAccountRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.RetrieveUserAccountResponseTO;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface AccountService {
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
CreateNewUserAccountResponseTO createNewUserAccount();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
RetrieveUserAccountResponseTO retrieveUserAccount(RetrieveUserAccountRequestTO retrieveUserAccountRequestTO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.converter.AccountEntityConverter;
|
||||
import com.jkgroller.cryptonote.entity.AccountEntity;
|
||||
import com.jkgroller.cryptonote.entity.repository.AccountEntityRepository;
|
||||
import com.jkgroller.cryptonote.enums.AccountRole;
|
||||
import com.jkgroller.cryptonote.service.to.*;
|
||||
import io.crnk.core.exception.UnauthorizedException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class AccountServiceImpl implements AccountService {
|
||||
|
||||
@Autowired
|
||||
private AccountEntityConverter accountEntityConverter;
|
||||
|
||||
@Autowired
|
||||
private AccountEntityRepository accountEntityRepository;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private CipherService cipherService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("identifierGenerator")
|
||||
private BytesKeyGenerator identifierGenerator;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("encryptionKeyGenerator")
|
||||
private BytesKeyGenerator encryptionKeyGenerator;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("userNameGenerator")
|
||||
private BytesKeyGenerator userNameGenerator;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("passwordGenerator")
|
||||
private BytesKeyGenerator passwordGenerator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CreateNewUserAccountResponseTO createNewUserAccount() {
|
||||
|
||||
String password = generatePassword();
|
||||
AccountEntity accountEntity = accountEntityRepository.save(buildAccountEntity(password, AccountRole.USER));
|
||||
|
||||
CreateNewUserAccountResponseTO createNewUserAccountResponseTO = new CreateNewUserAccountResponseTO();
|
||||
createNewUserAccountResponseTO.setAccountTO(accountEntityConverter.accountEntityToAccountTO(accountEntity));
|
||||
createNewUserAccountResponseTO.getAccountTO().setPassword(password);
|
||||
|
||||
return createNewUserAccountResponseTO;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param retrieveUserAccountRequestTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public RetrieveUserAccountResponseTO retrieveUserAccount(RetrieveUserAccountRequestTO retrieveUserAccountRequestTO) {
|
||||
|
||||
AccountEntity accountEntity = accountEntityRepository.findAccountByUserName(retrieveUserAccountRequestTO.getUserName());
|
||||
|
||||
if (null != accountEntity && passwordEncoder.matches(retrieveUserAccountRequestTO.getPassword(), accountEntity.getPasswordHash())) {
|
||||
RetrieveUserAccountResponseTO retrieveUserAccountResponseTO = new RetrieveUserAccountResponseTO();
|
||||
AccountTO accountTO = accountEntityConverter.accountEntityToAccountTO(accountEntity);
|
||||
retrieveUserAccountResponseTO.setAccountTO(accountTO);
|
||||
return retrieveUserAccountResponseTO;
|
||||
}
|
||||
|
||||
throw new UnauthorizedException("Unable to verify credentials.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private String generatePassword() {
|
||||
return Hex.encodeHexString(passwordGenerator.generateKey());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
private AccountEntity buildAccountEntity(String password, AccountRole accountRole) {
|
||||
|
||||
AccountEntity accountEntity = new AccountEntity();
|
||||
LocalDateTime localDateTime = LocalDateTime.now();
|
||||
|
||||
accountEntity.setUserName(Hex.encodeHexString(userNameGenerator.generateKey()));
|
||||
accountEntity.setPasswordHash(passwordEncoder.encode(password));
|
||||
accountEntity.setRole(accountRole.name());
|
||||
accountEntity.setIdentifier(Hex.encodeHexString(identifierGenerator.generateKey()));
|
||||
accountEntity.setCreationDateTime(localDateTime);
|
||||
accountEntity.setLastLoginDateTime(localDateTime);
|
||||
|
||||
EncryptResponseTO encryptResponseTO = generateEncryptedSurrogateKey(password);
|
||||
|
||||
accountEntity.setEncryptedSurrogateKey(encryptResponseTO.getEncrypted());
|
||||
accountEntity.setSurrogateKeySalt(encryptResponseTO.getSalt());
|
||||
|
||||
return accountEntity;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
private EncryptResponseTO generateEncryptedSurrogateKey(String password){
|
||||
|
||||
EncryptRequestTO encryptRequest = new EncryptRequestTO(password, encryptionKeyGenerator.generateKey());
|
||||
|
||||
return cipherService.encrypt(encryptRequest);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.service.to.DecryptRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.DecryptResponseTO;
|
||||
import com.jkgroller.cryptonote.service.to.EncryptRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.EncryptResponseTO;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface CipherService {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param encryptRequestTO
|
||||
* @return
|
||||
*/
|
||||
EncryptResponseTO encrypt(EncryptRequestTO encryptRequestTO);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param decryptRequestTO
|
||||
* @return
|
||||
*/
|
||||
DecryptResponseTO decrypt(DecryptRequestTO decryptRequestTO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.service.to.DecryptRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.DecryptResponseTO;
|
||||
import com.jkgroller.cryptonote.service.to.EncryptRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.EncryptResponseTO;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.crypto.encrypt.BytesEncryptor;
|
||||
import org.springframework.security.crypto.encrypt.Encryptors;
|
||||
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
|
||||
import org.springframework.security.crypto.keygen.KeyGenerators;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class CipherServiceImpl implements CipherService {
|
||||
|
||||
private final int SALT_SIZE;
|
||||
|
||||
/**
|
||||
* This is how you inject a value from a properties file into a constant.
|
||||
*/
|
||||
public CipherServiceImpl(@Value("${salt.size}") int saltSize) {
|
||||
this.SALT_SIZE = saltSize;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param encryptRequestTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public EncryptResponseTO encrypt(EncryptRequestTO encryptRequestTO) {
|
||||
|
||||
BytesKeyGenerator generator = KeyGenerators.secureRandom(SALT_SIZE);
|
||||
|
||||
byte[] saltBytes = generator.generateKey();
|
||||
|
||||
String saltString = Hex.encodeHexString(saltBytes);
|
||||
|
||||
BytesEncryptor bytesEncryptor = Encryptors.stronger(encryptRequestTO.getKey(), saltString);
|
||||
|
||||
byte[] encrypted = bytesEncryptor.encrypt(encryptRequestTO.getUnencryptedBytes());
|
||||
|
||||
return new EncryptResponseTO(encrypted, saltBytes);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param decryptRequestTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public DecryptResponseTO decrypt(DecryptRequestTO decryptRequestTO) {
|
||||
|
||||
BytesEncryptor bytesEncryptor = Encryptors.stronger(decryptRequestTO.getKey(),
|
||||
decryptRequestTO.getSaltString());
|
||||
|
||||
byte[] decrypted = bytesEncryptor.decrypt(decryptRequestTO.getEncrypted());
|
||||
|
||||
return new DecryptResponseTO(decrypted);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.service.to.CreateNoteRequestTO;
|
||||
import com.jkgroller.cryptonote.service.to.CreateNoteResponseTO;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface NoteService {
|
||||
|
||||
CreateNoteResponseTO createNote(CreateNoteRequestTO createNoteRequestTO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package com.jkgroller.cryptonote.service;
|
||||
|
||||
import com.jkgroller.cryptonote.converter.NoteEntityConverter;
|
||||
import com.jkgroller.cryptonote.entity.NoteEntity;
|
||||
import com.jkgroller.cryptonote.entity.repository.NoteEntityRepository;
|
||||
import com.jkgroller.cryptonote.service.to.*;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class NoteServiceImpl implements NoteService {
|
||||
|
||||
@Autowired
|
||||
private AccountService accountService;
|
||||
|
||||
@Autowired
|
||||
private CipherService cipherService;
|
||||
|
||||
@Autowired
|
||||
private NoteEntityRepository noteEntityRepository;
|
||||
|
||||
@Autowired
|
||||
private NoteEntityConverter noteEntityConverter;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("encryptionKeyGenerator")
|
||||
private BytesKeyGenerator encryptionKeyGenerator;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("identifierGenerator")
|
||||
private BytesKeyGenerator identifierGenerator;
|
||||
|
||||
/**
|
||||
* @param createNoteRequestTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CreateNoteResponseTO createNote(CreateNoteRequestTO createNoteRequestTO) {
|
||||
|
||||
//Retrieve user account
|
||||
RetrieveUserAccountRequestTO retrieveUserAccountRequestTO = new RetrieveUserAccountRequestTO();
|
||||
|
||||
retrieveUserAccountRequestTO.setUserName(createNoteRequestTO.getUserName());
|
||||
retrieveUserAccountRequestTO.setPassword(createNoteRequestTO.getPassword());
|
||||
|
||||
RetrieveUserAccountResponseTO retrieveUserAccountResponseTO = accountService.retrieveUserAccount(retrieveUserAccountRequestTO);
|
||||
|
||||
//Get the entity ready.
|
||||
NoteEntity noteEntity = new NoteEntity();
|
||||
|
||||
//Generate encryption Key
|
||||
byte[] key = encryptionKeyGenerator.generateKey();
|
||||
|
||||
//Encrypt note name with key
|
||||
EncryptRequestTO encryptNameRequestTO = new EncryptRequestTO(key, createNoteRequestTO.getNoteName());
|
||||
EncryptResponseTO encryptNameResponseTO = cipherService.encrypt(encryptNameRequestTO);
|
||||
|
||||
//Encrypt note contents with key.
|
||||
EncryptRequestTO encryptContentsRequestTO = new EncryptRequestTO(key, createNoteRequestTO.getNoteContents());
|
||||
EncryptResponseTO encryptContentsResponseTO = cipherService.encrypt(encryptContentsRequestTO);
|
||||
|
||||
//Decrypt surrogate key.
|
||||
DecryptRequestTO decryptSurrogateKeyRequestTO = new DecryptRequestTO(createNoteRequestTO.getPassword()
|
||||
, retrieveUserAccountResponseTO.getAccountTO().getEncryptedSurrogateKey()
|
||||
, retrieveUserAccountResponseTO.getAccountTO().getSurrogateKeySalt());
|
||||
|
||||
DecryptResponseTO decryptSurrogateKeyResponseTO = cipherService.decrypt(decryptSurrogateKeyRequestTO);
|
||||
|
||||
//Encrypt the key.
|
||||
EncryptRequestTO encryptKeyRequestTO = new EncryptRequestTO(decryptSurrogateKeyResponseTO.getUnencrypted(), key);
|
||||
EncryptResponseTO encryptKeyResponseTO = cipherService.encrypt(encryptKeyRequestTO);
|
||||
|
||||
//Generate an identifier.
|
||||
String noteIdentifier = Hex.encodeHexString(identifierGenerator.generateKey());
|
||||
|
||||
//Save it.
|
||||
noteEntity.setIdentifier(noteIdentifier);
|
||||
noteEntity.setContents(encryptContentsResponseTO.getEncrypted());
|
||||
noteEntity.setContentsSalt(encryptContentsResponseTO.getSalt());
|
||||
noteEntity.setName(encryptNameResponseTO.getEncrypted());
|
||||
noteEntity.setNameSalt(encryptNameResponseTO.getSalt());
|
||||
noteEntity.setKey(encryptKeyResponseTO.getEncrypted());
|
||||
noteEntity.setKeySalt(encryptKeyResponseTO.getSalt());
|
||||
|
||||
noteEntity = noteEntityRepository.save(noteEntity);
|
||||
|
||||
NoteTO noteTO = decryptNote(noteEntity, key);
|
||||
|
||||
CreateNoteResponseTO createNoteResponseTO = new CreateNoteResponseTO();
|
||||
createNoteResponseTO.setNoteTO(noteTO);
|
||||
|
||||
return createNoteResponseTO;
|
||||
}
|
||||
|
||||
private NoteTO decryptNote(NoteEntity noteEntity, byte[] key) {
|
||||
|
||||
NoteTO noteTO = new NoteTO();
|
||||
|
||||
DecryptRequestTO decryptNoteContentsRequestTO = new DecryptRequestTO(Hex.encodeHexString(key)
|
||||
, noteEntity.getContents()
|
||||
, noteEntity.getContentsSalt());
|
||||
|
||||
DecryptRequestTO decryptNoteNameRequestTO = new DecryptRequestTO(Hex.encodeHexString(key)
|
||||
, noteEntity.getContents()
|
||||
, noteEntity.getContentsSalt());
|
||||
|
||||
noteTO.setContents(cipherService.decrypt(decryptNoteContentsRequestTO).getUnencrypted());
|
||||
|
||||
noteTO.setName(cipherService.decrypt(decryptNoteNameRequestTO).getUnencrypted());
|
||||
|
||||
noteTO.setIdentifier(noteEntity.getIdentifier());
|
||||
|
||||
return noteTO;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
import com.jkgroller.cryptonote.enums.AccountRole;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class AccountTO {
|
||||
|
||||
private String identifier;
|
||||
|
||||
private String userName;
|
||||
|
||||
private String password;
|
||||
|
||||
private AccountRole role;
|
||||
|
||||
private LocalDateTime creationDateTime;
|
||||
|
||||
private byte[] encryptedSurrogateKey;
|
||||
|
||||
private byte[] surrogateKeySalt;
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public AccountRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(AccountRole role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreationDateTime() {
|
||||
return creationDateTime;
|
||||
}
|
||||
|
||||
public void setCreationDateTime(LocalDateTime creationDateTime) {
|
||||
this.creationDateTime = creationDateTime;
|
||||
}
|
||||
|
||||
public byte[] getEncryptedSurrogateKey() {
|
||||
return encryptedSurrogateKey;
|
||||
}
|
||||
|
||||
public void setEncryptedSurrogateKey(byte[] encryptedSurrogateKey) {
|
||||
this.encryptedSurrogateKey = encryptedSurrogateKey;
|
||||
}
|
||||
|
||||
public byte[] getSurrogateKeySalt() {
|
||||
return surrogateKeySalt;
|
||||
}
|
||||
|
||||
public void setSurrogateKeySalt(byte[] surrogateKeySalt) {
|
||||
this.surrogateKeySalt = surrogateKeySalt;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CreateNewAccountResponseTO {
|
||||
|
||||
private AccountTO accountTO;
|
||||
|
||||
public AccountTO getAccountTO() {
|
||||
return accountTO;
|
||||
}
|
||||
|
||||
public void setAccountTO(AccountTO accountTO) {
|
||||
this.accountTO = accountTO;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
import com.jkgroller.cryptonote.enums.AccountRole;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CreateNewUserAccountResponseTO extends CreateNewAccountResponseTO {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public CreateNewUserAccountResponseTO() {
|
||||
AccountTO accountTO = new AccountTO();
|
||||
accountTO.setRole(AccountRole.USER);
|
||||
super.setAccountTO(accountTO);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CreateNoteRequestTO {
|
||||
|
||||
private String userName;
|
||||
|
||||
private String password;
|
||||
|
||||
private String noteName;
|
||||
|
||||
private String noteContents;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userName
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getNoteName() {
|
||||
return noteName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noteName
|
||||
*/
|
||||
public void setNoteName(String noteName) {
|
||||
this.noteName = noteName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getNoteContents() {
|
||||
return noteContents;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noteContents
|
||||
*/
|
||||
public void setNoteContents(String noteContents) {
|
||||
this.noteContents = noteContents;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CreateNoteResponseTO {
|
||||
|
||||
private NoteTO noteTO;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public NoteTO getNoteTO() {
|
||||
return noteTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param noteTO
|
||||
*/
|
||||
public void setNoteTO(NoteTO noteTO) {
|
||||
this.noteTO = noteTO;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DecryptRequestTO {
|
||||
|
||||
private final String key;
|
||||
|
||||
private final byte[] encrypted;
|
||||
|
||||
private final byte[] salt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
* @param encrypted
|
||||
* @param salt
|
||||
*/
|
||||
public DecryptRequestTO(String key, byte[] encrypted, byte[] salt) {
|
||||
super();
|
||||
this.key = key;
|
||||
this.encrypted = encrypted;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getEncrypted() {
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the salt
|
||||
*/
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the salt
|
||||
*/
|
||||
public String getSaltString() {
|
||||
return Hex.encodeHexString(salt);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DecryptResponseTO {
|
||||
|
||||
private final String unencrypted;
|
||||
|
||||
/**
|
||||
* @param unencrypted
|
||||
*/
|
||||
public DecryptResponseTO(String unencrypted) {
|
||||
super();
|
||||
this.unencrypted = unencrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unencrypted
|
||||
*/
|
||||
public DecryptResponseTO(byte[] unencrypted) {
|
||||
super();
|
||||
this.unencrypted = new String(unencrypted, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unencrypted
|
||||
*/
|
||||
public String getUnencrypted() {
|
||||
return unencrypted;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EncryptRequestTO {
|
||||
|
||||
private final String key;
|
||||
|
||||
private final String unencrypted;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param unencrypted
|
||||
*/
|
||||
public EncryptRequestTO(String key, String unencrypted) {
|
||||
super();
|
||||
this.key = key;
|
||||
this.unencrypted = unencrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param unencrypted
|
||||
*/
|
||||
public EncryptRequestTO(String key, byte[] unencrypted) {
|
||||
super();
|
||||
this.key = key;
|
||||
this.unencrypted = Hex.encodeHexString(unencrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
* @param unencrypted
|
||||
*/
|
||||
public EncryptRequestTO(byte[] key, byte[] unencrypted) {
|
||||
super();
|
||||
this.key = Hex.encodeHexString(key);
|
||||
this.unencrypted = Hex.encodeHexString(unencrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
* @param unencrypted
|
||||
*/
|
||||
public EncryptRequestTO(byte[] key, String unencrypted) {
|
||||
super();
|
||||
this.key = Hex.encodeHexString(key);
|
||||
this.unencrypted = unencrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getUnencrypted() {
|
||||
return unencrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public byte[] getUnencryptedBytes() {
|
||||
return unencrypted.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EncryptResponseTO {
|
||||
|
||||
private final byte[] encrypted;
|
||||
|
||||
private final byte[] salt;
|
||||
|
||||
/**
|
||||
* @param encrypted
|
||||
* @param salt
|
||||
*/
|
||||
public EncryptResponseTO(byte[] encrypted, byte[] salt) {
|
||||
this.encrypted = encrypted;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public EncryptResponseTO() {
|
||||
this.encrypted = null;
|
||||
this.salt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the encrypted
|
||||
*/
|
||||
public byte[] getEncrypted() {
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class NoteTO {
|
||||
|
||||
private String identifier;
|
||||
|
||||
private String name;
|
||||
|
||||
private String contents;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param identifier
|
||||
*/
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents
|
||||
*/
|
||||
public void setContents(String contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RetrieveUserAccountRequestTO {
|
||||
|
||||
private String userName;
|
||||
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userName
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.jkgroller.cryptonote.service.to;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RetrieveUserAccountResponseTO {
|
||||
|
||||
private AccountTO accountTO;
|
||||
|
||||
public AccountTO getAccountTO() {
|
||||
return accountTO;
|
||||
}
|
||||
|
||||
public void setAccountTO(AccountTO accountTO) {
|
||||
this.accountTO = accountTO;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
30
src/main/resources/application.properties
Normal file
30
src/main/resources/application.properties
Normal file
@ -0,0 +1,30 @@
|
||||
#===============================
|
||||
# = CRNK
|
||||
# ===============================
|
||||
crnk.path-prefix=/v1
|
||||
crnk.return404-on-null=true
|
||||
|
||||
#===============================
|
||||
# = Security & Generators
|
||||
# ===============================
|
||||
password.encryption.strength=12
|
||||
salt.size=32
|
||||
encryption.key.length=32
|
||||
username.length=8
|
||||
password.length=16
|
||||
identifier.length=8
|
||||
|
||||
#===============================
|
||||
# = Data Source
|
||||
# ===============================
|
||||
spring.datasource.url=jdbc:h2:mem:cryptonote;DB_CLOSE_DELAY=-1
|
||||
spring.datasource.platform=h2
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
spring.jpa.show-sql=false
|
||||
#spring.datasource.initialization-mode=ALWAYS
|
||||
#spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2
|
||||
spring.h2.console.settings.web-allow-others=true
|
||||
58
src/test/resources/db.sql
Normal file
58
src/test/resources/db.sql
Normal file
@ -0,0 +1,58 @@
|
||||
-- --------------------------------------------------------
|
||||
-- Host: 192.168.0.18
|
||||
-- Server version: 5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
|
||||
-- Server OS: Linux
|
||||
-- HeidiSQL Version: 9.4.0.5169
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
|
||||
|
||||
-- Dumping database structure for spring_security
|
||||
CREATE DATABASE IF NOT EXISTS `spring_security` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
USE `spring_security`;
|
||||
|
||||
-- Dumping structure for table spring_security.member
|
||||
CREATE TABLE IF NOT EXISTS `member` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`active` int(1) NOT NULL,
|
||||
`verified` int(1) NOT NULL,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`last_name` varchar(255) NOT NULL,
|
||||
`first_name` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`surrogate_key` binary(58) NOT NULL,
|
||||
`surrogate_key_salt` binary(28) NOT NULL,
|
||||
`verification_key` char(36) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
-- Dumping structure for table spring_security.member_role
|
||||
CREATE TABLE IF NOT EXISTS `member_role` (
|
||||
`member_id` int(11) NOT NULL,
|
||||
`role_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`member_id`,`role_id`),
|
||||
KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
|
||||
CONSTRAINT `FK34g7epqlcxqloewku3aoqhhmg` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`),
|
||||
CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`),
|
||||
CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
|
||||
CONSTRAINT `FKdiix07v86r3ntrbs3l02qr7y0` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
-- Dumping structure for table spring_security.role
|
||||
CREATE TABLE IF NOT EXISTS `role` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`role` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
Loading…
x
Reference in New Issue
Block a user