mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Basic hibernate structure.
This commit is contained in:
parent
5ab5635fc4
commit
da395757d7
6 changed files with 386 additions and 5 deletions
|
@ -16,7 +16,6 @@ dependencies {
|
|||
implementation 'it.unimi.dsi:fastutil-core:8.5.4'
|
||||
implementation 'commons-codec:commons-codec:1.15'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
|
||||
implementation 'org.mongodb:mongodb-driver-sync:4.2.2'
|
||||
implementation 'com.github.TiA4f8R.NewPipeExtractor:NewPipeExtractor:df53170023ff5b97ad1d7ccc74bfce74c3998bcc'
|
||||
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
|
||||
|
@ -32,6 +31,8 @@ dependencies {
|
|||
implementation 'io.activej:activej-boot:4.3'
|
||||
implementation 'io.activej:activej-specializer:4.3'
|
||||
implementation 'io.activej:activej-launchers-http:4.3'
|
||||
implementation 'org.postgresql:postgresql:42.2.19'
|
||||
implementation 'org.hibernate:hibernate-core:5.4.30.Final'
|
||||
implementation 'net.java.dev.jna:jna-platform:5.8.0'
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.schabi.newpipe.extractor.Page;
|
|||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.mongodb.client.MongoClient;
|
||||
|
||||
import me.kavin.piped.utils.PageMixin;
|
||||
|
||||
|
@ -36,8 +35,6 @@ public class Constants {
|
|||
.version(Version.HTTP_2).build();
|
||||
// public static final HttpClient h3client = Http3ClientBuilder.newBuilder().followRedirects(Redirect.NORMAL).build();
|
||||
|
||||
public static final MongoClient mongoClient;
|
||||
|
||||
public static final ObjectMapper mapper = new ObjectMapper().addMixIn(Page.class, PageMixin.class);
|
||||
|
||||
static {
|
||||
|
@ -51,7 +48,6 @@ public class Constants {
|
|||
PROXY_PART = prop.getProperty("PROXY_PART");
|
||||
CAPTCHA_BASE_URL = prop.getProperty("CAPTCHA_BASE_URL");
|
||||
CAPTCHA_API_KEY = prop.getProperty("CAPTCHA_API_KEY");
|
||||
mongoClient = null/* MongoClients.create(prop.getProperty("MONGO_URI")) */;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
152
src/main/java/me/kavin/piped/utils/PasswordHash.java
Normal file
152
src/main/java/me/kavin/piped/utils/PasswordHash.java
Normal file
|
@ -0,0 +1,152 @@
|
|||
package me.kavin.piped.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
/*
|
||||
* PBKDF2 salted password hashing.
|
||||
* Author: havoc AT defuse.ca
|
||||
* www: http://crackstation.net/hashing-security.htm
|
||||
* source: https://gist.github.com/jtan189/3804290
|
||||
*/
|
||||
public class PasswordHash {
|
||||
public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA512";
|
||||
|
||||
// The following constants may be changed without breaking existing hashes.
|
||||
public static final int SALT_BYTES = 64;
|
||||
public static final int HASH_BYTES = 64;
|
||||
public static final int PBKDF2_ITERATIONS = 1000;
|
||||
|
||||
public static final int ITERATION_INDEX = 0;
|
||||
public static final int SALT_INDEX = 1;
|
||||
public static final int PBKDF2_INDEX = 2;
|
||||
|
||||
/**
|
||||
* Returns a salted PBKDF2 hash of the password.
|
||||
*
|
||||
* @param password the password to hash
|
||||
* @return a salted PBKDF2 hash of the password
|
||||
*/
|
||||
public static String createHash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
return createHash(password.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a salted PBKDF2 hash of the password.
|
||||
*
|
||||
* @param password the password to hash
|
||||
* @return a salted PBKDF2 hash of the password
|
||||
*/
|
||||
public static String createHash(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
// Generate a random salt
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] salt = new byte[SALT_BYTES];
|
||||
random.nextBytes(salt);
|
||||
|
||||
// Hash the password
|
||||
byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTES);
|
||||
// format iterations:salt:hash
|
||||
return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" + toHex(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a password using a hash.
|
||||
*
|
||||
* @param password the password to check
|
||||
* @param goodHash the hash of the valid password
|
||||
* @return true if the password is correct, false if not
|
||||
*/
|
||||
public static boolean validatePassword(String password, String goodHash)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
return validatePassword(password.toCharArray(), goodHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a password using a hash.
|
||||
*
|
||||
* @param password the password to check
|
||||
* @param goodHash the hash of the valid password
|
||||
* @return true if the password is correct, false if not
|
||||
*/
|
||||
public static boolean validatePassword(char[] password, String goodHash)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
// Decode the hash into its parameters
|
||||
String[] params = goodHash.split(":");
|
||||
int iterations = Integer.parseInt(params[ITERATION_INDEX]);
|
||||
byte[] salt = fromHex(params[SALT_INDEX]);
|
||||
byte[] hash = fromHex(params[PBKDF2_INDEX]);
|
||||
// Compute the hash of the provided password, using the same salt,
|
||||
// iteration count, and hash length
|
||||
byte[] testHash = pbkdf2(password, salt, iterations, hash.length);
|
||||
// Compare the hashes in constant time. The password is correct if
|
||||
// both hashes match.
|
||||
return slowEquals(hash, testHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two byte arrays in length-constant time. This comparison method is
|
||||
* used so that password hashes cannot be extracted from an on-line system using
|
||||
* a timing attack and then attacked off-line.
|
||||
*
|
||||
* @param a the first byte array
|
||||
* @param b the second byte array
|
||||
* @return true if both byte arrays are the same, false if not
|
||||
*/
|
||||
private static boolean slowEquals(byte[] a, byte[] b) {
|
||||
int diff = a.length ^ b.length;
|
||||
for (int i = 0; i < a.length && i < b.length; i++)
|
||||
diff |= a[i] ^ b[i];
|
||||
return diff == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the PBKDF2 hash of a password.
|
||||
*
|
||||
* @param password the password to hash.
|
||||
* @param salt the salt
|
||||
* @param iterations the iteration count (slowness factor)
|
||||
* @param bytes the length of the hash to compute in bytes
|
||||
* @return the PBDKF2 hash of the password
|
||||
*/
|
||||
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
||||
return skf.generateSecret(spec).getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string of hexadecimal characters into a byte array.
|
||||
*
|
||||
* @param hex the hex string
|
||||
* @return the hex string decoded into a byte array
|
||||
*/
|
||||
private static byte[] fromHex(String hex) {
|
||||
byte[] binary = new byte[hex.length() / 2];
|
||||
for (int i = 0; i < binary.length; i++) {
|
||||
binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array into a hexadecimal string.
|
||||
*
|
||||
* @param array the byte array to convert
|
||||
* @return a length*2 character string encoding the byte array
|
||||
*/
|
||||
private static String toHex(byte[] array) {
|
||||
BigInteger bi = new BigInteger(1, array);
|
||||
String hex = bi.toString(16);
|
||||
int paddingLength = (array.length * 2) - hex.length();
|
||||
if (paddingLength > 0)
|
||||
return String.format("%0" + paddingLength + "d", 0) + hex;
|
||||
else
|
||||
return hex;
|
||||
}
|
||||
}
|
80
src/main/java/me/kavin/piped/utils/obj/db/User.java
Normal file
80
src/main/java/me/kavin/piped/utils/obj/db/User.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
package me.kavin.piped.utils.obj.db;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users", indexes = { @Index(columnList = "id", name = "id_idx"),
|
||||
@Index(columnList = "username", name = "username_idx") })
|
||||
public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "username", unique = true, length = 24)
|
||||
private String username;
|
||||
|
||||
@Column(name = "password", columnDefinition = "text")
|
||||
private String password;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "users_subscribed", joinColumns = @JoinColumn(name = "subscriber"), indexes = @Index(columnList = "subscriber", name = "subscriber_idx"))
|
||||
@Column(name = "channel", length = 30)
|
||||
private List<String> subscribed_ids;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String username, String password, List<String> subscribed_ids) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.subscribed_ids = subscribed_ids;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
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 List<String> getSubscribed() {
|
||||
return subscribed_ids;
|
||||
}
|
||||
|
||||
public void setSubscribed(List<String> subscribed_ids) {
|
||||
this.subscribed_ids = subscribed_ids;
|
||||
}
|
||||
}
|
140
src/main/java/me/kavin/piped/utils/obj/db/Video.java
Normal file
140
src/main/java/me/kavin/piped/utils/obj/db/Video.java
Normal file
|
@ -0,0 +1,140 @@
|
|||
package me.kavin.piped.utils.obj.db;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "videos", indexes = { @Index(columnList = "id", name = "id_idx") })
|
||||
public class Video {
|
||||
|
||||
@Id
|
||||
@Column(name = "id", unique = true, length = 16)
|
||||
private String id;
|
||||
|
||||
@Column(name = "title", length = 100)
|
||||
private String title;
|
||||
|
||||
@Column(name = "views")
|
||||
private long views;
|
||||
|
||||
@Column(name = "duration")
|
||||
private int duration;
|
||||
|
||||
@Column(name = "uploaded")
|
||||
private long uploaded;
|
||||
|
||||
@Column(name = "uploader", length = 80)
|
||||
private String uploader;
|
||||
|
||||
@Column(name = "uploader_url", length = 30)
|
||||
private String uploaderUrl;
|
||||
|
||||
@Column(name = "uploader_avatar", length = 150)
|
||||
private String uploaderAvatar;
|
||||
|
||||
@Column(name = "verified")
|
||||
private boolean verified;
|
||||
|
||||
@Column(name = "thumbnail", length = 150)
|
||||
private String thumbnail;
|
||||
|
||||
public Video() {
|
||||
}
|
||||
|
||||
public Video(String id, String title, long views, int duration, long uploaded, String uploader, String uploaderUrl,
|
||||
String uploaderAvatar, boolean verified, String thumbnail) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.views = views;
|
||||
this.duration = duration;
|
||||
this.uploaded = uploaded;
|
||||
this.uploader = uploader;
|
||||
this.uploaderUrl = uploaderUrl;
|
||||
this.uploaderAvatar = uploaderAvatar;
|
||||
this.verified = verified;
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public long getViews() {
|
||||
return views;
|
||||
}
|
||||
|
||||
public void setViews(long views) {
|
||||
this.views = views;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public long getUploaded() {
|
||||
return uploaded;
|
||||
}
|
||||
|
||||
public void setUploaded(long uploaded) {
|
||||
this.uploaded = uploaded;
|
||||
}
|
||||
|
||||
public String getUploader() {
|
||||
return uploader;
|
||||
}
|
||||
|
||||
public void setUploader(String uploader) {
|
||||
this.uploader = uploader;
|
||||
}
|
||||
|
||||
public String getUploaderUrl() {
|
||||
return uploaderUrl;
|
||||
}
|
||||
|
||||
public void setUploaderUrl(String uploaderUrl) {
|
||||
this.uploaderUrl = uploaderUrl;
|
||||
}
|
||||
|
||||
public String getUploaderAvatar() {
|
||||
return uploaderAvatar;
|
||||
}
|
||||
|
||||
public void setUploaderAvatar(String uploaderAvatar) {
|
||||
this.uploaderAvatar = uploaderAvatar;
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return verified;
|
||||
}
|
||||
|
||||
public void setVerified(boolean verified) {
|
||||
this.verified = verified;
|
||||
}
|
||||
|
||||
public String getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public void setThumbnail(String thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
}
|
12
src/main/resources/hibernate.cfg.xml
Normal file
12
src/main/resources/hibernate.cfg.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!DOCTYPE hibernate-configuration PUBLIC
|
||||
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<property name="hibernate.hbm2ddl.auto">update</property>
|
||||
<!-- Optional: Show SQL output for debugging -->
|
||||
<property name="hibernate.show_sql">true</property>
|
||||
<property name="hibernate.format_sql">true</property>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
Loading…
Add table
Add a link
Reference in a new issue