diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..13e1825bc Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/.idea/FullStack.MicroWebApplication-Server.iml b/.idea/FullStack.MicroWebApplication-Server.iml index 52657c62b..308873028 100644 --- a/.idea/FullStack.MicroWebApplication-Server.iml +++ b/.idea/FullStack.MicroWebApplication-Server.iml @@ -14,7 +14,10 @@ - + + + + @@ -33,9 +36,10 @@ + + - @@ -64,6 +68,13 @@ + + + + + + + @@ -87,17 +98,7 @@ - - - - - - - - - - @@ -106,9 +107,6 @@ - - - @@ -120,5 +118,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 000000000..f1917db48 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306/moneymanagement + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_mifmif_generex_1_0_1.xml b/.idea/libraries/Maven__com_github_mifmif_generex_1_0_1.xml new file mode 100644 index 000000000..e29a95df3 --- /dev/null +++ b/.idea/libraries/Maven__com_github_mifmif_generex_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_2_1_0.xml b/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_2_1_0.xml new file mode 100644 index 000000000..d01004b72 --- /dev/null +++ b/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_2_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_starter_2_1_0.xml b/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_starter_2_1_0.xml new file mode 100644 index 000000000..9194ea1b6 --- /dev/null +++ b/.idea/libraries/Maven__com_github_ulisesbocchio_jasypt_spring_boot_starter_2_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__dk_brics_automaton_automaton_1_11_8.xml b/.idea/libraries/Maven__dk_brics_automaton_automaton_1_11_8.xml new file mode 100644 index 000000000..40327c1ef --- /dev/null +++ b/.idea/libraries/Maven__dk_brics_automaton_automaton_1_11_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml new file mode 100644 index 000000000..f25b99b8f --- /dev/null +++ b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_micrometer_micrometer_core_1_6_2.xml b/.idea/libraries/Maven__io_micrometer_micrometer_core_1_6_2.xml new file mode 100644 index 000000000..e03387be3 --- /dev/null +++ b/.idea/libraries/Maven__io_micrometer_micrometer_core_1_6_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_13_1.xml b/.idea/libraries/Maven__junit_junit_4_13_1.xml new file mode 100644 index 000000000..9fa24fcbd --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_13_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_2.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_2.xml new file mode 100644 index 000000000..15f1e4c17 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_12.xml b/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_12.xml new file mode 100644 index 000000000..6908885fb --- /dev/null +++ b/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jasypt_jasypt_1_9_2.xml b/.idea/libraries/Maven__org_jasypt_jasypt_1_9_2.xml new file mode 100644 index 000000000..652ffddc2 --- /dev/null +++ b/.idea/libraries/Maven__org_jasypt_jasypt_1_9_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml b/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml new file mode 100644 index 000000000..bf6816984 --- /dev/null +++ b/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_4_1.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_4_1.xml new file mode 100644 index 000000000..cef03e6e1 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_4_1.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_4_1.xml new file mode 100644 index 000000000..c23dfe430 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_4_1.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_4_1.xml new file mode 100644 index 000000000..45071a5a7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_4_1.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_4_1.xml new file mode 100644 index 000000000..f695444f8 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_2.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_2.xml new file mode 100644 index 000000000..31af903c8 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_2.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_2.xml new file mode 100644 index 000000000..be467e489 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_test_5_4_2.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_test_5_4_2.xml new file mode 100644 index 000000000..387889ad6 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_test_5_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_2.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_2.xml new file mode 100644 index 000000000..827baa4f9 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 000000000..fedfd37a7 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 7b72c6e34..59f2abf6f 100644 --- a/README.md +++ b/README.md @@ -15,62 +15,24 @@ Use Spring Initializr to create an starting point for you application - - - - - - -## Project Topics - -### TCP Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can send messages to a _peer_. - * can view default channels - * can view all accessible channels - * can view messages live as they are received - -
- - - - - -### Blog Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can create new blog posts - * A blog post can consist of images and text - * can view list of all blog posts - * can view blog posts filtered by blog-tag - * can view new blog posts upon refreshing the DOM - -
- - - - - -### Video Library Application +### Money Management Application #### User Stories to Fulfill -* As a client, (not logged in) I - * can upload new videos - * can view list of all videos - * can post simple text-comments on a video - - - - +* As a logged in client, + * can create new client + * can create new account for a client + * deposit money to each account + * withdraw money from each account + * transfer money to and from any 2 accounts + * delete the client if accounts with Balance = 0 + * display all account belonging to client + * display account details and transaction details of loaded account + ### Money Management Application #### User Stories to Fulfill * As a client, (not logged in) I - * can create new accounts - * deposit money to each account - * withdraw money from each account - * transfer money to and from any 2 accounts + * can create new customer profile + * login + diff --git a/ZipBank_UI_Snapshots/1.png b/ZipBank_UI_Snapshots/1.png new file mode 100644 index 000000000..e3f64b4cb Binary files /dev/null and b/ZipBank_UI_Snapshots/1.png differ diff --git a/ZipBank_UI_Snapshots/10.png b/ZipBank_UI_Snapshots/10.png new file mode 100644 index 000000000..2678029a2 Binary files /dev/null and b/ZipBank_UI_Snapshots/10.png differ diff --git a/ZipBank_UI_Snapshots/11.png b/ZipBank_UI_Snapshots/11.png new file mode 100644 index 000000000..7d03de921 Binary files /dev/null and b/ZipBank_UI_Snapshots/11.png differ diff --git a/ZipBank_UI_Snapshots/12.png b/ZipBank_UI_Snapshots/12.png new file mode 100644 index 000000000..a7f11b96c Binary files /dev/null and b/ZipBank_UI_Snapshots/12.png differ diff --git a/ZipBank_UI_Snapshots/13.png b/ZipBank_UI_Snapshots/13.png new file mode 100644 index 000000000..495ea3748 Binary files /dev/null and b/ZipBank_UI_Snapshots/13.png differ diff --git a/ZipBank_UI_Snapshots/14.png b/ZipBank_UI_Snapshots/14.png new file mode 100644 index 000000000..3ae89c683 Binary files /dev/null and b/ZipBank_UI_Snapshots/14.png differ diff --git a/ZipBank_UI_Snapshots/15.png b/ZipBank_UI_Snapshots/15.png new file mode 100644 index 000000000..b680e9fac Binary files /dev/null and b/ZipBank_UI_Snapshots/15.png differ diff --git a/ZipBank_UI_Snapshots/2.png b/ZipBank_UI_Snapshots/2.png new file mode 100644 index 000000000..acf99e576 Binary files /dev/null and b/ZipBank_UI_Snapshots/2.png differ diff --git a/ZipBank_UI_Snapshots/3.png b/ZipBank_UI_Snapshots/3.png new file mode 100644 index 000000000..5c894577a Binary files /dev/null and b/ZipBank_UI_Snapshots/3.png differ diff --git a/ZipBank_UI_Snapshots/4.png b/ZipBank_UI_Snapshots/4.png new file mode 100644 index 000000000..0aa43e429 Binary files /dev/null and b/ZipBank_UI_Snapshots/4.png differ diff --git a/ZipBank_UI_Snapshots/5.png b/ZipBank_UI_Snapshots/5.png new file mode 100644 index 000000000..1d9b63e3d Binary files /dev/null and b/ZipBank_UI_Snapshots/5.png differ diff --git a/ZipBank_UI_Snapshots/6.png b/ZipBank_UI_Snapshots/6.png new file mode 100644 index 000000000..deca035e5 Binary files /dev/null and b/ZipBank_UI_Snapshots/6.png differ diff --git a/ZipBank_UI_Snapshots/7.png b/ZipBank_UI_Snapshots/7.png new file mode 100644 index 000000000..ae0dcfe42 Binary files /dev/null and b/ZipBank_UI_Snapshots/7.png differ diff --git a/ZipBank_UI_Snapshots/8.png b/ZipBank_UI_Snapshots/8.png new file mode 100644 index 000000000..2bf34339b Binary files /dev/null and b/ZipBank_UI_Snapshots/8.png differ diff --git a/ZipBank_UI_Snapshots/9.png b/ZipBank_UI_Snapshots/9.png new file mode 100644 index 000000000..11fbb598a Binary files /dev/null and b/ZipBank_UI_Snapshots/9.png differ diff --git a/dump.sql b/dump.sql new file mode 100644 index 000000000..9ecc50a2b --- /dev/null +++ b/dump.sql @@ -0,0 +1,179 @@ +-- MySQL dump 10.13 Distrib 8.0.22, for macos10.15 (x86_64) +-- +-- Host: localhost Database: moneymanagement +-- ------------------------------------------------------ +-- Server version 8.0.22 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!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' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Current Database: `moneymanagement` +-- + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `moneymanagement` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; + +USE `moneymanagement`; + +-- +-- Table structure for table `account` +-- + +DROP TABLE IF EXISTS `account`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `account` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `account_number` varchar(255) NOT NULL, + `account_type` varchar(255) NOT NULL, + `balance` double NOT NULL, + `date_of_opening` date NOT NULL, + `interest_rate` double NOT NULL, + `routing_number` varchar(255) NOT NULL, + `customer_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FKnnwpo0lfq4xai1rs6887sx02k` (`customer_id`) +) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `account` +-- + +LOCK TABLES `account` WRITE; +/*!40000 ALTER TABLE `account` DISABLE KEYS */; +INSERT INTO `account` VALUES (1,'CHECKING-123456','CHECKING',10000,'2004-01-22',0.2,'12455122',1),(2,'SAVINGS-1245451','SAVINGS',25000,'2004-01-22',0.85,'2001445',1); +/*!40000 ALTER TABLE `account` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `address` +-- + +DROP TABLE IF EXISTS `address`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `address` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `city` varchar(255) NOT NULL, + `first_line` varchar(255) NOT NULL, + `secondline` varchar(255) DEFAULT NULL, + `state` varchar(255) NOT NULL, + `zipcode` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `address` +-- + +LOCK TABLES `address` WRITE; +/*!40000 ALTER TABLE `address` DISABLE KEYS */; +INSERT INTO `address` VALUES (1,'Philadelphia','123 A st','Second Line','Pennsylvania','19147'); +/*!40000 ALTER TABLE `address` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `customer` +-- + +DROP TABLE IF EXISTS `customer`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `customer` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `date_of_birth` date NOT NULL, + `email` varchar(255) NOT NULL, + `first_name` varchar(255) NOT NULL, + `last_name` varchar(255) NOT NULL, + `middle_name` varchar(255) DEFAULT NULL, + `phone_number` varchar(255) NOT NULL, + `social_security` varchar(255) NOT NULL, + `address_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `FKglkhkmh2vyn790ijs6hiqqpi` (`address_id`) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `customer` +-- + +LOCK TABLES `customer` WRITE; +/*!40000 ALTER TABLE `customer` DISABLE KEYS */; +INSERT INTO `customer` VALUES (1,'2012-05-05','tom@gmail.com','Tom','Walter','G','5122264785','435435345',1); +/*!40000 ALTER TABLE `customer` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `login` +-- + +DROP TABLE IF EXISTS `login`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `login` ( + `user_id` bigint NOT NULL AUTO_INCREMENT, + `password` varchar(255) NOT NULL, + `username` varchar(255) NOT NULL, + PRIMARY KEY (`user_id`) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `login` +-- + +LOCK TABLES `login` WRITE; +/*!40000 ALTER TABLE `login` DISABLE KEYS */; +INSERT INTO `login` VALUES (1,'c51ChDMn','tom'); +/*!40000 ALTER TABLE `login` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `transaction` +-- + +DROP TABLE IF EXISTS `transaction`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transaction` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `account_number` varchar(255) NOT NULL, + `transaction_balance` double NOT NULL, + `transaction_date` date NOT NULL, + `transaction_description` varchar(255) NOT NULL, + `account_id` bigint NOT NULL, + PRIMARY KEY (`id`), + KEY `FK6g20fcr3bhr6bihgy24rq1r1b` (`account_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `transaction` +-- + +LOCK TABLES `transaction` WRITE; +/*!40000 ALTER TABLE `transaction` DISABLE KEYS */; +/*!40000 ALTER TABLE `transaction` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-12-29 11:00:39 diff --git a/pom.xml b/pom.xml index b5aedba0e..38488bd21 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,11 @@ h2 runtime + + org.mockito + mockito-junit-jupiter + test + org.springframework.boot spring-boot-starter-test @@ -49,7 +54,54 @@ mysql-connector-java runtime + + org.junit.jupiter + junit-jupiter-engine + test + + + junit + junit + 4.13.1 + test + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 2.1.0 + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-test + test + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + com.github.mifmif + generex + 1.0.1 + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 000000000..8023d4bd9 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 000000000..7584523ec Binary files /dev/null and b/src/main/.DS_Store differ diff --git a/src/main/java/AppRunner.java b/src/main/java/AppRunner.java deleted file mode 100644 index 2f11a0bac..000000000 --- a/src/main/java/AppRunner.java +++ /dev/null @@ -1,11 +0,0 @@ -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class AppRunner { - - public static void main(String[] args) { - SpringApplication.run(AppRunner.class, args); - - } -} diff --git a/src/main/java/controllers/AccountController.java b/src/main/java/controllers/AccountController.java deleted file mode 100644 index b0479543a..000000000 --- a/src/main/java/controllers/AccountController.java +++ /dev/null @@ -1,11 +0,0 @@ -package controllers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RestController; -import services.AccountServices; - -@RestController -public class AccountController { - @Autowired - private AccountServices accountServices; -} diff --git a/src/main/java/controllers/LoginController.java b/src/main/java/controllers/LoginController.java deleted file mode 100644 index 5ec632231..000000000 --- a/src/main/java/controllers/LoginController.java +++ /dev/null @@ -1,14 +0,0 @@ -package controllers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RestController; -import services.LoginServices; - -@RestController -public class LoginController { - - @Autowired - private LoginServices loginServices; - - -} diff --git a/src/main/java/controllers/TransactionController.java b/src/main/java/controllers/TransactionController.java deleted file mode 100644 index 0edb7d66c..000000000 --- a/src/main/java/controllers/TransactionController.java +++ /dev/null @@ -1,4 +0,0 @@ -package controllers; - -public class TransactionController { -} diff --git a/src/main/java/controllers/UserController.java b/src/main/java/controllers/UserController.java deleted file mode 100644 index 8a2d45cd6..000000000 --- a/src/main/java/controllers/UserController.java +++ /dev/null @@ -1,46 +0,0 @@ -package controllers; - -import entities.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import services.UserServices; - -import java.util.List; - -@RestController -public class UserController { - @Autowired - private UserServices userServices; - -// @GetMapping(value = "/user/read/{id}") -// public ResponseEntity readById(@PathVariable Long id) { -// return new ResponseEntity<>(userServices.readUser(id), HttpStatus.OK); -// } -// -//// @GetMapping(value = "/readAll") -//// public ResponseEntity> readAll() { -//// return new ResponseEntity<>(userServices.readAll(), HttpStatus.OK); -//// } -// @PostMapping(value = "/user/create") -// public ResponseEntity create(@RequestBody User user) { -// return new ResponseEntity<>(userServices.createUser(user), HttpStatus.CREATED); -// } -// -// @PutMapping(value = "/user/update/{id}") -// public ResponseEntity update(@RequestBody User user,@PathVariable Long id) { -// return new ResponseEntity<>(userServices.updateUser(id,user), HttpStatus.OK); -// } -// -// @DeleteMapping(value = "/user/delete/{id}") -// public ResponseEntity deleteById(@PathVariable Long id) { -// return new ResponseEntity<>(userServices.deleteUser(id), HttpStatus.OK); -// } - - @GetMapping(value = "/home") - public String displayHome() { - return "Hello World"; - } - -} diff --git a/src/main/java/entities/Account.java b/src/main/java/entities/Account.java deleted file mode 100644 index 360f632bd..000000000 --- a/src/main/java/entities/Account.java +++ /dev/null @@ -1,61 +0,0 @@ -package entities; - -import javax.persistence.*; -import java.time.LocalDate; -import java.util.Date; -@Entity -public abstract class Account { - @Id - protected Long Id; - protected String accountNumber; - protected String routingNumber; - protected Double balance; - protected LocalDate dateOfOpening; - protected Double interestRate; - public Account() { - } -// public Account(Long id, String accountNumber, String routingNumber, Double balance, LocalDate dateOfOpening, Double interestRate) { -// Id = id; -// this.accountNumber = accountNumber; -// this.routingNumber = routingNumber; -// this.balance = balance; -// this.dateOfOpening = dateOfOpening; -// this.interestRate = interestRate; -// } - public Long getId() { - return Id; - } - public void setId(Long id) { - Id = id; - } - public String getAccountNumber() { - return accountNumber; - } - public void setAccountNumber(String accountNumber) { - this.accountNumber = accountNumber; - } - public String getRoutingNumber() { - return routingNumber; - } - public void setRoutingNumber(String routingNumber) { - this.routingNumber = routingNumber; - } - public Double getBalance() { - return balance; - } - public void setBalance(Double balance) { - this.balance = balance; - } - public LocalDate getDateOfOpening() { - return dateOfOpening; - } - public void setDateOfOpening(LocalDate dateOfOpening) { - this.dateOfOpening = dateOfOpening; - } - public Double getInterestRate() { - return interestRate; - } - public void setInterestRate(Double interestRate) { - this.interestRate = interestRate; - } -} \ No newline at end of file diff --git a/src/main/java/entities/Checkings.java b/src/main/java/entities/Checkings.java deleted file mode 100644 index b30cb094d..000000000 --- a/src/main/java/entities/Checkings.java +++ /dev/null @@ -1,4 +0,0 @@ -package entities; - -public class Checkings extends Account{ -} diff --git a/src/main/java/entities/Investments.java b/src/main/java/entities/Investments.java deleted file mode 100644 index f03a78c64..000000000 --- a/src/main/java/entities/Investments.java +++ /dev/null @@ -1,7 +0,0 @@ -package entities; - -public class Investments extends Account{ - - - -} diff --git a/src/main/java/entities/Login.java b/src/main/java/entities/Login.java deleted file mode 100644 index 7fff15a9c..000000000 --- a/src/main/java/entities/Login.java +++ /dev/null @@ -1,35 +0,0 @@ -package entities; - -import javax.persistence.*; - -@Entity -public class Login { - @Id - private Long Id; - private String username; - private String password; - - public Long getId() { - return Id; - } - - public void setId(Long id) { - 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; - } -} diff --git a/src/main/java/entities/TransactionHistory.java b/src/main/java/entities/TransactionHistory.java deleted file mode 100644 index 8ae19170a..000000000 --- a/src/main/java/entities/TransactionHistory.java +++ /dev/null @@ -1,16 +0,0 @@ -package entities; - -import javax.persistence.Entity; -import javax.persistence.Id; -import java.time.LocalDate; -@Entity -public class TransactionHistory { - @Id - private Long id; - private String accountType; - private String transactionType; - private Double balanceAfterTransaction; - private LocalDate dateOfTransaction; - - -} diff --git a/src/main/java/entities/User.java b/src/main/java/entities/User.java deleted file mode 100644 index cdfe5fb26..000000000 --- a/src/main/java/entities/User.java +++ /dev/null @@ -1,58 +0,0 @@ -package entities; - -import javax.persistence.*; -import java.time.LocalDate; -@Entity -public class User { - @Id - private Long Id; - private String firstName; - private String lastName; - private LocalDate dateOfBirth; - private String socialSecurity; - private String address; - - public User() { - } - - - public Long getId() { - return Id; - } - - public void setId(Long id) { - Id = id; - } - - - public String getFirstName() { - return firstName; - } - public void setFirstName(String firstName) { - this.firstName = firstName; - } - public String getLastName() { - return lastName; - } - public void setLastName(String lastName) { - this.lastName = lastName; - } - public LocalDate getDateOfBirth() { - return dateOfBirth; - } - public void setDateOfBirth(LocalDate dateOfBirth) { - this.dateOfBirth = dateOfBirth; - } - public String getSocialSecurity() { - return socialSecurity; - } - public void setSocialSecurity(String socialSecurity) { - this.socialSecurity = socialSecurity; - } - public String getAddress() { - return address; - } - public void setAddress(String address) { - this.address = address; - } -} \ No newline at end of file diff --git a/src/main/java/repositories/AccountRepo.java b/src/main/java/repositories/AccountRepo.java deleted file mode 100644 index 78ce09a6d..000000000 --- a/src/main/java/repositories/AccountRepo.java +++ /dev/null @@ -1,13 +0,0 @@ -package repositories; - -import entities.Account; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface AccountRepo extends CrudRepository { - - List findAll(); -} diff --git a/src/main/java/repositories/UserRepo.java b/src/main/java/repositories/UserRepo.java deleted file mode 100644 index 11a33e1de..000000000 --- a/src/main/java/repositories/UserRepo.java +++ /dev/null @@ -1,19 +0,0 @@ -package repositories; - -import entities.User; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface UserRepo extends CrudRepository { - - User findUserById(Integer Id); - - // List findAll(); - - //update --save - //create -- save - //delete --delete -} diff --git a/src/main/java/runner/AppRunner.java b/src/main/java/runner/AppRunner.java new file mode 100644 index 000000000..0e6dd8e09 --- /dev/null +++ b/src/main/java/runner/AppRunner.java @@ -0,0 +1,18 @@ +package runner; + +import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@SpringBootApplication +@EnableEncryptableProperties +public class AppRunner { + + public static void main(String[] args) { + SpringApplication.run(AppRunner.class, args); + } +} diff --git a/src/main/java/runner/controllers/AccountController.java b/src/main/java/runner/controllers/AccountController.java new file mode 100644 index 000000000..5609d40c1 --- /dev/null +++ b/src/main/java/runner/controllers/AccountController.java @@ -0,0 +1,90 @@ +package runner.controllers; +import com.fasterxml.jackson.annotation.JsonView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import runner.entities.Account; +import runner.entities.Transaction; +import runner.services.AccountServices; +import runner.views.Views; + +import javax.transaction.Transactional; +import java.util.Optional; +import java.util.Set; + +@CrossOrigin(origins = "*", allowedHeaders = "*") +@RequestMapping("/myaccount") +@RestController +public class AccountController { + + @Autowired + private AccountServices accountServices; + + /** + * This controller is used only for JWT testing purposes + * */ + @GetMapping(value = "/test") + public String testJWT() { + return "Hello World"; + } + + //get accounts for the authenticated user only, THIS is the homepage once user has logged in + @JsonView(Views.AllAccounts.class) + @GetMapping + public ResponseEntity> readAllAccount() { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(accountServices.getAllAccounts(currentPrincipalName), HttpStatus.OK); + } + + @JsonView(Views.AccountSpecific.class) + @GetMapping(value = "/{encryptedUrl}") + public ResponseEntity readAccountByUrl(@PathVariable String encryptedUrl){ + return new ResponseEntity<>(accountServices.getAccountByEncryptedUrl(encryptedUrl), HttpStatus.OK); + } + + + @PostMapping(value = "/create") + public ResponseEntity create(@RequestBody Account account) throws Exception { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(accountServices.createAccount(account, currentPrincipalName), HttpStatus.CREATED); + } +// +// //REMOVE if not needed +// @PutMapping(value = "/update/{id}") +// public ResponseEntity> update(@RequestBody Account account, @PathVariable Long id) throws Exception { +// return new ResponseEntity<>(accountServices.updateAccount(id,account), HttpStatus.OK); +// } + + //This needs to be rewritten with "encryptedUrl/delete", need to doublecheck if deleting account deletes User due to cascade.ALL +// @DeleteMapping(value = "/{encryptedUrl}/delete") +// public ResponseEntity deleteAccount(@PathVariable String encryptedUrl){ +// return new ResponseEntity<>(accountServices.removeAccount(encryptedUrl), HttpStatus.OK); +// } + + @JsonView(Views.AccountSpecific.class) + @PutMapping(value = "/{encryptedUrl}/deposit") + public ResponseEntity updateAccountDeposit(@RequestBody Transaction transaction, @PathVariable String encryptedUrl) throws Exception { + return new ResponseEntity<>(accountServices.deposit(transaction,encryptedUrl), HttpStatus.OK); + } + + @JsonView(Views.AccountSpecific.class) + @PutMapping(value = "/{encryptedUrl}/withdraw") + public ResponseEntity updateAccountWithdraw(@RequestBody Transaction transaction, @PathVariable String encryptedUrl) throws Exception { + return new ResponseEntity<>(accountServices.withdraw(transaction,encryptedUrl), HttpStatus.OK); + } + + //same method as withdraw since JSON payload is same, only front end is different + @JsonView(Views.AccountSpecific.class) + @PutMapping(value = "/{encryptedUrl}/transfer") + public ResponseEntity updateAccountTransfer(@RequestBody Transaction transaction, @PathVariable String encryptedUrl) throws Exception { + return new ResponseEntity<>(accountServices.withdraw(transaction,encryptedUrl), HttpStatus.OK); + } + + @GetMapping("/loggedout") + public ResponseEntity updateAccountTransfer(){ + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(accountServices.logout(currentPrincipalName), HttpStatus.OK); + } +} \ No newline at end of file diff --git a/src/main/java/runner/controllers/CustomerController.java b/src/main/java/runner/controllers/CustomerController.java new file mode 100644 index 000000000..08d28f91a --- /dev/null +++ b/src/main/java/runner/controllers/CustomerController.java @@ -0,0 +1,88 @@ +package runner.controllers; +import com.fasterxml.jackson.annotation.JsonView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import runner.entities.Address; +import runner.entities.Customer; +import runner.services.CustomerServices; +import runner.views.Views; + +@CrossOrigin(origins = "*", allowedHeaders = "*") +@RestController +public class CustomerController { + + @Autowired + private CustomerServices customerServices; + + @JsonView(Views.Profile.class) + @GetMapping(value = "/myaccount/profile") + public ResponseEntity getCustomer() { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); //needs JWT token in header + return new ResponseEntity<>(customerServices.readCustomerByLogin(currentPrincipalName), HttpStatus.OK); + } + + @PostMapping(value = "/openaccount",consumes = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity create(@RequestBody Customer customer) throws Exception { + customer = customerServices.createCustomer(customer); + + if(customer!=null) { + return new ResponseEntity<>(customer, HttpStatus.CREATED); + } + else + return new ResponseEntity<>("Login user name already exist", HttpStatus.CONFLICT); + } + +/* @PutMapping(value = "myaccount/profile") + public ResponseEntity update(@RequestBody Customer customer) throws Exception { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + Customer customerReturned =customerServices.readCustomerByLogin(*//*currentPrincipalName*//* "user1"); + Long id = customerReturned.getId(); + return new ResponseEntity<>(customerServices.updateCustomer(id,customer), HttpStatus.OK); + }*/ + + @JsonView(Views.PhoneNumber.class) + @PutMapping(value = "myaccount/profile/phone") + public ResponseEntity updatePhone(@RequestBody Customer customer) throws Exception { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(customerServices.updateCustomerPhoneNumber(currentPrincipalName,customer), HttpStatus.OK); + } + + @JsonView(Views.Email.class) + @PutMapping(value = "myaccount/profile/email") + public ResponseEntity updateEmail(@RequestBody Customer customer) { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(customerServices.updateCustomerEmail(currentPrincipalName, customer), HttpStatus.OK); + } + + @JsonView(Views.Address.class) + @PutMapping(value = "myaccount/profile/address") + public ResponseEntity updateEmail(@RequestBody Address address) { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(customerServices.updateCustomerAddress(currentPrincipalName, address), HttpStatus.OK); + } + + @DeleteMapping(value = "myaccount/profile/delete") + public ResponseEntity deleteById() { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + Customer customerReturned =customerServices.readCustomerByLogin(currentPrincipalName); + Long id = customerReturned.getId(); + int flag=customerServices.deleteCustomer(id); + if(flag ==0) + return new ResponseEntity<>("User has been deleted as all accounts has balance as Zero.", HttpStatus.OK); + else if(flag==2) + return new ResponseEntity<>("User has account with balance , cannot be deleted", HttpStatus.FORBIDDEN); + else + return new ResponseEntity<>("No accounts/user found", HttpStatus.NOT_FOUND); + } + + @DeleteMapping(value = "myaccount/{encryptedUrl}/delete") + public ResponseEntity deleteAccount(@PathVariable String encryptedUrl) throws Exception{ + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(customerServices.removeAccount(currentPrincipalName,encryptedUrl), HttpStatus.OK); + } + +} \ No newline at end of file diff --git a/src/main/java/runner/controllers/LoginController.java b/src/main/java/runner/controllers/LoginController.java new file mode 100644 index 000000000..6bd70352c --- /dev/null +++ b/src/main/java/runner/controllers/LoginController.java @@ -0,0 +1,35 @@ +package runner.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import runner.entities.Login; +import runner.services.LoginServices; + +@RestController +public class LoginController { + + @Autowired + private LoginServices loginServices; + + //Remove if not needed +// @GetMapping(value = "/read/{id}") +// public ResponseEntity readById(@PathVariable Long id) throws Exception { +// if(new ResponseEntity<>(loginServices.readLogin(id), HttpStatus.OK) == null) throw new Exception("Error , the user id is null") ; +// else +// return new ResponseEntity<>(loginServices.readLogin(id), HttpStatus.OK); +// } + + //Remove if not needed +// @PostMapping(value = "/create") +// public ResponseEntity create(@RequestBody Login login) { +// Login loginResult =loginServices.createLogin(login); +// if( loginResult == null) +// return new ResponseEntity<>(null, HttpStatus.FORBIDDEN); +// else +// return new ResponseEntity<>(loginResult, HttpStatus.OK); +// } + + +} \ No newline at end of file diff --git a/src/main/java/runner/controllers/TestHomePageDeleteLater.java b/src/main/java/runner/controllers/TestHomePageDeleteLater.java new file mode 100644 index 000000000..d551e6358 --- /dev/null +++ b/src/main/java/runner/controllers/TestHomePageDeleteLater.java @@ -0,0 +1,50 @@ +package runner.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import runner.entities.Account; +import runner.services.AccountServices; +import runner.services.CustomerServices; +import runner.services.LoginServices; + +import java.util.Set; +import java.util.stream.Collectors; + +@RestController +public class TestHomePageDeleteLater { + @Autowired + CustomerServices customerServices; + + @Autowired + AccountServices accountServices; + + @Autowired + LoginServices loginServices; + + @GetMapping(value = "/") + public String homePage(){ + return "Hello World"; + } + + //get accounts for the authenticated user only: THIS METHOD HAS BEEN MOVED TO ACCOUNTCONTROLLER +/* @GetMapping(value = "/myaccount") + public ResponseEntity> readAllAccount(){ + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + return new ResponseEntity<>(customerServices.getAllAccounts(currentPrincipalName), HttpStatus.OK); + }*/ + + + //get account for specific encrypted URL: THIS METHOD HAS BEEN MOVED TO ACCOUNTCONTROLLER +/* @GetMapping(value = "/{accountEncryptedUrl}") + public ResponseEntity readAccountById(@PathVariable String accountEncryptedUrl) throws Exception { + String currentPrincipalName = SecurityContextHolder.getContext().getAuthentication().getName(); + Long accountId = accountServices.getAllAccounts(currentPrincipalName).stream() + .filter(a->a.getEncryptedUrl().equals(accountEncryptedUrl)) + .collect(Collectors.toList()).get(0).getId(); + return new ResponseEntity<>(accountServices.readAccount(accountId), HttpStatus.OK); + }*/ + +} \ No newline at end of file diff --git a/src/main/java/runner/controllers/TransactionController.java b/src/main/java/runner/controllers/TransactionController.java new file mode 100644 index 000000000..13f82115b --- /dev/null +++ b/src/main/java/runner/controllers/TransactionController.java @@ -0,0 +1,11 @@ +package runner.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; +import runner.services.TransactionServices; + +@RestController +public class TransactionController { + @Autowired + private TransactionServices transactionServices; +} diff --git a/src/main/java/runner/entities/Account.java b/src/main/java/runner/entities/Account.java new file mode 100644 index 000000000..f2c7c3b95 --- /dev/null +++ b/src/main/java/runner/entities/Account.java @@ -0,0 +1,148 @@ +package runner.entities; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonView; +import runner.enums.AccountType; +import runner.views.Views; + +import javax.persistence.*; +import java.time.LocalDate; + +import java.util.*; + +@Entity +public class Account { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @JsonView(Views.AccountNumber.class) + private String accountNumber; + + @JsonView(Views.RoutingNumber.class) + private String routingNumber = "091000022"; + + @JsonView(Views.AccountType.class) + @Enumerated(EnumType.STRING) + private AccountType accountType; //enum + + @JsonView(Views.AccountActions.class) + private Double balance; + + @JsonView(Views.AccountOpening.class) + private LocalDate dateOfOpening; + + @JsonView(Views.AccountDetails.class) + private Double interestRate; + + @JsonView(Views.AllAccounts.class) //delete this later in production + private String encryptedUrl; + + @JsonView(Views.AccountSpecific.class) + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "account_transaction", + joinColumns = @JoinColumn(name = "account_id"), + inverseJoinColumns = @JoinColumn(name = "transaction_id")) + private List transactions = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name = "customer_id") + private Customer customer; + + public Account() { + } + + public Account(Long id, String accountNumber, AccountType accountType, Double balance, String encryptedUrl, List transactions) { + this.id = id; + this.accountNumber = accountNumber; + this.accountType = accountType; + this.balance = balance; + this.encryptedUrl = encryptedUrl; + this.transactions = transactions; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public void addToTransactionsList(Transaction transaction){ + transactions.add(transaction); + } + + public String getAccountNumber() { + return accountNumber; + } + + public void setAccountNumber(String accountNumber) { + this.accountNumber = accountNumber; + } + + public String getRoutingNumber() { + return routingNumber; + } + + public void setRoutingNumber(String routingNumber) { + this.routingNumber = routingNumber; + } + + public AccountType getAccountType() { + return accountType; + } + + public void setAccountType(AccountType accountType) { + this.accountType = accountType; + } + + public Double getBalance() { + return balance; + } + + public void setBalance(Double balance) { + this.balance = balance; + } + + public LocalDate getDateOfOpening() { + return dateOfOpening; + } + + public void setDateOfOpening(LocalDate dateOfOpening) { + this.dateOfOpening = dateOfOpening; + } + + public Double getInterestRate() { + return interestRate; + } + + public void setInterestRate(Double interestRate) { + this.interestRate = this.accountType.getInterestRate(); + } + + public List getTransactions() { + return transactions; + } + + public void setTransactions(List transactionsList) { + this.transactions = transactionsList; + } + + public String getEncryptedUrl() { + return encryptedUrl; + } + + public void setEncryptedUrl(String encryptedURL) { + this.encryptedUrl = encryptedURL; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } +} \ No newline at end of file diff --git a/src/main/java/runner/entities/Address.java b/src/main/java/runner/entities/Address.java new file mode 100644 index 000000000..13fcaf1eb --- /dev/null +++ b/src/main/java/runner/entities/Address.java @@ -0,0 +1,89 @@ +package runner.entities; + +import com.fasterxml.jackson.annotation.JsonView; +import runner.views.Views; + +import javax.persistence.*; + +@Entity +public class Address { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @JsonView(Views.Address.class) + @Column(nullable = false) + private String firstLine; + @Column(nullable = true) + @JsonView(Views.Address.class) + private String secondLIne; + @Column(nullable = false) + @JsonView(Views.Address.class) + private String city; + @Column(nullable = false) + @JsonView(Views.Address.class) + private String state; + @Column(nullable = false) + @JsonView(Views.Address.class) + private String zipcode; + + public Address() { + } + + //for testing + public Address(Long id, String firstLine, String secondLIne, String city, String state, String zipcode) { + this.id = id; + this.firstLine = firstLine; + this.secondLIne = secondLIne; + this.city = city; + this.state = state; + this.zipcode = zipcode; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstLine() { + return firstLine; + } + + public void setFirstLine(String firstLine) { + this.firstLine = firstLine; + } + + public String getSecondLIne() { + return secondLIne; + } + + public void setSecondLIne(String secondLIne) { + this.secondLIne = secondLIne; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getZipcode() { + return zipcode; + } + + public void setZipcode(String zipcode) { + this.zipcode = zipcode; + } +} diff --git a/src/main/java/runner/entities/Checking.java b/src/main/java/runner/entities/Checking.java new file mode 100644 index 000000000..f1728e7ff --- /dev/null +++ b/src/main/java/runner/entities/Checking.java @@ -0,0 +1,4 @@ +package runner.entities; + +public class Checking extends Account{ +} diff --git a/src/main/java/runner/entities/Customer.java b/src/main/java/runner/entities/Customer.java new file mode 100644 index 000000000..550564301 --- /dev/null +++ b/src/main/java/runner/entities/Customer.java @@ -0,0 +1,171 @@ +package runner.entities; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonView; +import runner.views.Views; + +import javax.persistence.*; +import java.time.LocalDate; +import java.util.Set; +import static javax.persistence.CascadeType.ALL; + +@Entity +public class Customer { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + //@JsonView(Views.Profile.class) + //@Column(nullable = false) + private String firstName; + + //@JsonView(Views.Profile.class) + private String middleName; + + //@JsonView(Views.Profile.class) + //@Column(nullable = false) + private String lastName; + + //@JsonView(Views.Profile.class) + //@Column(nullable = false) + private LocalDate dateOfBirth; + + //@Column(nullable = false) + private String socialSecurity; + + //@Column(nullable = false) + @JsonView(Views.Email.class) + private String email; + + @JsonView(Views.PhoneNumber.class) + //@Column(nullable = false) + private String phoneNumber; + + @JsonView(Views.Address.class) + @OneToOne(cascade = ALL, fetch = FetchType.EAGER) + private Address address; + + @JsonView(Views.Profile.class) //delete in production + @JsonBackReference(value = "login") + @OneToOne(mappedBy = "customer", cascade = ALL,fetch = FetchType.EAGER) + @PrimaryKeyJoinColumn //sharing primary key with user login since creating a new user requires a login anyways + private Login login; + + @JsonView(Views.Profile.class) //delete in production + @OneToMany(mappedBy = "customer", cascade = ALL,fetch = FetchType.EAGER, orphanRemoval = true) + @OrderBy + @JsonBackReference + private Set accounts; + + public Customer() { + } + + //for testing + public Customer(Long id, String firstName, String lastName, Login login, Set accounts) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.login = login; + this.accounts = accounts; + } + + public Customer(Long id, String firstName, String lastName, Address address, Login login, Set accounts) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.address = address; + this.login = login; + this.accounts = accounts; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public LocalDate getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(LocalDate dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getSocialSecurity() { + return socialSecurity; + } + + public void setSocialSecurity(String socialSecurity) { + this.socialSecurity = socialSecurity; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + + this.phoneNumber = phoneNumber; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public Login getLogin() { + return login; + } + + public void setLogin(Login login) { + this.login = login; + } + + public Set getAccounts() { + return accounts; + } + + public void setAccounts(Set accounts) { + this.accounts = accounts; + } + + +} \ No newline at end of file diff --git a/src/main/java/runner/entities/Investment.java b/src/main/java/runner/entities/Investment.java new file mode 100644 index 000000000..0abc3cfee --- /dev/null +++ b/src/main/java/runner/entities/Investment.java @@ -0,0 +1,7 @@ +package runner.entities; + +public class Investment extends Account{ + + + +} diff --git a/src/main/java/runner/entities/Login.java b/src/main/java/runner/entities/Login.java new file mode 100644 index 000000000..ed551156d --- /dev/null +++ b/src/main/java/runner/entities/Login.java @@ -0,0 +1,112 @@ +package runner.entities; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonView; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import runner.views.Views; + +import javax.persistence.*; +import java.util.Collection; + +@Entity +public class Login implements UserDetails { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @JsonView(Views.Profile.class) + @Column(nullable = false) + private String username; + + @Column(nullable = false) + private String password; + + @JsonBackReference(value = "customer") + @OneToOne + @PrimaryKeyJoinColumn + private Customer customer; + + public Login(){ + } + + //for testing + public Login(String username, String password) { + this.username = username; + this.password = password; + } + + //for testing + public Login(Long id, String username, String password, Customer customer) { + this.id = id; + this.username = username; + this.password = password; + this.customer = customer; + } + + 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 Customer getUser() { + return customer; + } + + public void setUser(Customer customer) { + this.customer = customer; + } + + //is user account expired + @Override + public boolean isAccountNonExpired() { + return true; + } + + //is user account locked + @Override + public boolean isAccountNonLocked() { + return true; + } + + //is user credential expired + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + //is user enabled + @Override + public boolean isEnabled() { + return true; + } + + //ignore this, not using authorities + @Override + public Collection getAuthorities() { + return null; + } + +} diff --git a/src/main/java/entities/Savings.java b/src/main/java/runner/entities/Savings.java similarity index 62% rename from src/main/java/entities/Savings.java rename to src/main/java/runner/entities/Savings.java index ce5f0ddf2..9ca731abe 100644 --- a/src/main/java/entities/Savings.java +++ b/src/main/java/runner/entities/Savings.java @@ -1,4 +1,4 @@ -package entities; +package runner.entities; public class Savings extends Account{ } diff --git a/src/main/java/runner/entities/Transaction.java b/src/main/java/runner/entities/Transaction.java new file mode 100644 index 000000000..7ecf69f05 --- /dev/null +++ b/src/main/java/runner/entities/Transaction.java @@ -0,0 +1,101 @@ +package runner.entities; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonView; +import runner.views.Views; + + +import javax.persistence.*; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +@Entity +public class Transaction { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @JsonView(Views.AccountSpecific.class) + private String transactionDescription; + + @JsonView(Views.AccountSpecific.class) + private Double transactionAmount; + + @JsonView(Views.AccountSpecific.class) + private Double transactionBalance; + + @JsonView(Views.AccountSpecific.class) + private LocalDate transactionDate; + + @JsonBackReference + @ManyToMany(mappedBy = "transactions") + private Set accounts = new HashSet<>(); + + public Transaction(){ + } + + //for test only + public Transaction(Double transactionAmount, Set accounts) { + this.transactionAmount = transactionAmount; + this.accounts = accounts; + } + + //for test only + public Transaction(String transactionDescription, Double transactionAmount, Double transactionBalance, LocalDate transactionDate) { + this.transactionDescription = transactionDescription; + this.transactionAmount = transactionAmount; + this.transactionBalance = transactionBalance; + this.transactionDate = transactionDate; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTransactionDescription() { + return transactionDescription; + } + + public void setTransactionDescription(String transactionDescription) { + this.transactionDescription = transactionDescription; + } + + public Double getTransactionBalance() { + return transactionBalance; + } + + public void setTransactionBalance(Double transactionBalance) { + this.transactionBalance = transactionBalance; + } + + public LocalDate getTransactionDate() { + return transactionDate; + } + + public void setTransactionDate(LocalDate transactionDate) { + this.transactionDate = transactionDate; + } + + public Double getTransactionAmount() { + return transactionAmount; + } + + public void setTransactionAmount(Double transactionAmount) { + this.transactionAmount = transactionAmount; + } + + public Set getAccounts() { + return accounts; + } + + public void setAccounts(Set accounts) { + this.accounts = accounts; + } + +} diff --git a/src/main/java/runner/enums/AccountType.java b/src/main/java/runner/enums/AccountType.java new file mode 100644 index 000000000..de10d889a --- /dev/null +++ b/src/main/java/runner/enums/AccountType.java @@ -0,0 +1,19 @@ +package runner.enums; + +public enum AccountType { + CHECKING(0.5),INVESTMENT,SAVINGS(1.3); + + private Double interestRate; + + AccountType(){ + } + + AccountType(Double interestRate){ + this.interestRate = interestRate; + } + + public Double getInterestRate(){ + return interestRate; + } + +} diff --git a/src/main/java/runner/repositories/AccountRepo.java b/src/main/java/runner/repositories/AccountRepo.java new file mode 100644 index 000000000..20782ecda --- /dev/null +++ b/src/main/java/runner/repositories/AccountRepo.java @@ -0,0 +1,21 @@ +package runner.repositories; + +import org.springframework.data.jpa.repository.Query; +import runner.entities.Account; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Set; + + +@Repository +public interface AccountRepo extends CrudRepository { + + Account findAccountById(Long Id); + Account findAccountByEncryptedUrl(String encryptedUrl); + Account findAccountByAccountNumber(String accountNumber); + Set findAccountsByCustomer_LoginUsername (String login); + Integer deleteAccountByEncryptedUrl(String encryptedUrl); + Integer deleteByEncryptedUrl(String encryptedUrl); +} diff --git a/src/main/java/runner/repositories/CustomerRepo.java b/src/main/java/runner/repositories/CustomerRepo.java new file mode 100644 index 000000000..eb23125b1 --- /dev/null +++ b/src/main/java/runner/repositories/CustomerRepo.java @@ -0,0 +1,23 @@ +package runner.repositories; + +import org.springframework.data.jpa.repository.Query; +import runner.entities.Customer; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import runner.entities.Login; + +import java.util.Collection; +import java.util.List; + + +@Repository +public interface CustomerRepo extends CrudRepository { + + Customer findCustomerById(Long Id); + Customer findCustomerByLoginUsername(String name); + @Query( + value = "SELECT username FROM LOGIN", + nativeQuery = true) + List findAllLoginsNative(); + List findAll(); +} \ No newline at end of file diff --git a/src/main/java/repositories/LoginRepo.java b/src/main/java/runner/repositories/LoginRepo.java similarity index 64% rename from src/main/java/repositories/LoginRepo.java rename to src/main/java/runner/repositories/LoginRepo.java index 12d2f2ddf..8f2f8681f 100644 --- a/src/main/java/repositories/LoginRepo.java +++ b/src/main/java/runner/repositories/LoginRepo.java @@ -1,16 +1,16 @@ -package repositories; +package runner.repositories; -import entities.Login; -import org.springframework.data.jpa.repository.Query; +import runner.entities.Login; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import java.util.List; + @Repository public interface LoginRepo extends CrudRepository { Login findLoginById(Long id); - - -} + Login findLoginByUsername (String username); + List findAll(); +} \ No newline at end of file diff --git a/src/main/java/repositories/TransactionRepo.java b/src/main/java/runner/repositories/TransactionRepo.java similarity index 57% rename from src/main/java/repositories/TransactionRepo.java rename to src/main/java/runner/repositories/TransactionRepo.java index 4cd16816a..a42771c36 100644 --- a/src/main/java/repositories/TransactionRepo.java +++ b/src/main/java/runner/repositories/TransactionRepo.java @@ -1,12 +1,11 @@ -package repositories; +package runner.repositories; -import entities.TransactionHistory; -import org.springframework.beans.factory.annotation.Autowired; +import runner.entities.Transaction; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository -public interface TransactionRepo extends CrudRepository { +public interface TransactionRepo extends CrudRepository { } diff --git a/src/main/java/runner/security/config/WebSecurityConfig.java b/src/main/java/runner/security/config/WebSecurityConfig.java new file mode 100644 index 000000000..cc602362d --- /dev/null +++ b/src/main/java/runner/security/config/WebSecurityConfig.java @@ -0,0 +1,126 @@ +package runner.security.config; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.web.filter.CorsFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.BeanIds; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +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.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.util.matcher.AndRequestMatcher; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import runner.security.filters.JwtAuthorizationFilter; +import runner.services.LoginServices; +import runner.services.UserDetailServices; + +@Configuration +@EnableWebSecurity //allows Spring to find and automatically apply the class to the global Web Security. +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserDetailServices userDetailServices; + + @Autowired + private JwtAuthorizationFilter jwtAuthorizationFilter; + + //dependency injects into loginServices + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder(){ + return new BCryptPasswordEncoder(); + } + + //dependency injects into loginController + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + //dependency injects into AuthenticationController + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailServices).passwordEncoder(bCryptPasswordEncoder()); + } + + //allowing user to post to authenticate since spring security is placed on all request + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors(); + http + .csrf().disable() + .authorizeRequests()//.antMatchers().permitAll() //permit everybody for this endpoint + .anyRequest().authenticated() //all other request requires authentication + .and().sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); //jwt is stateless, asking Spring to not create sessions for each request + http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class); //asking Spring to use jwtAuthorizationFilter before UsernamePasswordAuthenticationFilter is called + } + + //Bypasses the jwtAuthorizationFilter for endpoints not required which i think is dictated by web.ignoring() line in configure(WebSecurity web) method + @Bean + public FilterRegistrationBean disableMyFilterBean() { + FilterRegistrationBean registration = new FilterRegistrationBean(jwtAuthorizationFilter); + registration.setEnabled(false); + return registration; + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/authenticate","/","/openaccount"); + } + + @Bean + public WebMvcConfigurer corsConfigurer(){ + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedMethods("GET","POST","PUT","DELETE") + .allowedHeaders("*") + //.allowedOrigins("http://localhost:4200"); //angular default port + .allowedOrigins("http://zip-bank.herokuapp.com"); //angular default port + } + }; + } + + + + + /* @Override //creating own form for login + protected void configure(HttpSecurity http) throws Exception{ + http + .csrf().disable() + .authorizeRequests().antMatchers("/authenticate").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("insertHomePageUrlHere").permitAll() + .and() + .logout().invalidateHttpSession(true) //handles logout + .clearAuthentication(true) + .logoutRequestMatcher(new AntPathRequestMatcher("insertUrlForLogoutHere")) + .logoutSuccessUrl("insertUrlSuccessPageHere").permitAll(); + }*/ + +} \ No newline at end of file diff --git a/src/main/java/runner/security/controllers/AuthenticationController.java b/src/main/java/runner/security/controllers/AuthenticationController.java new file mode 100644 index 000000000..2f56617a3 --- /dev/null +++ b/src/main/java/runner/security/controllers/AuthenticationController.java @@ -0,0 +1,58 @@ +package runner.security.controllers; + +import com.mifmif.common.regex.Generex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import runner.entities.Account; +import runner.entities.Login; +import runner.security.models.AuthenticationResponse; +import runner.security.utilities.JwtUtil; +import runner.services.AccountServices; +import runner.services.CustomerServices; +import runner.services.LoginServices; +import runner.services.UserDetailServices; + +import java.util.Set; + +@RestController +public class AuthenticationController { + + @Autowired + private JwtUtil jwtUtil; + @Autowired + private AuthenticationManager authenticationManager; + @Autowired + private AccountServices accountServices; + @Autowired + private UserDetailServices userDetailServices; + + //jwt authentication + @PostMapping(value = "/authenticate") + public ResponseEntity generateAuthenticationToken(@RequestBody Login login) throws Exception{ + try{ + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(login.getUsername(), login.getPassword()) + ); + } + catch (BadCredentialsException e){ //this exception message should be linked to frontend + throw new Exception("Incorrect username or password", e); + } + addRandomUrlToAccounts(login); + final UserDetails userDetails = userDetailServices.loadUserByUsername(login.getUsername()); + final String jwt = jwtUtil.generateToken(userDetails); + return ResponseEntity.ok(new AuthenticationResponse(jwt)); + } + + //adding the random URL to the accounts + public void addRandomUrlToAccounts(Login login){ + accountServices.getAllAccounts(login.getUsername()).forEach(a->accountServices.SaveAccountWithUrl(a, accountServices.generateRandomUrl())); + } + +} \ No newline at end of file diff --git a/src/main/java/runner/security/filters/JwtAuthorizationFilter.java b/src/main/java/runner/security/filters/JwtAuthorizationFilter.java new file mode 100644 index 000000000..7d2f8e7f4 --- /dev/null +++ b/src/main/java/runner/security/filters/JwtAuthorizationFilter.java @@ -0,0 +1,68 @@ +package runner.security.filters; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +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.stereotype.Component; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.CorsUtils; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.OncePerRequestFilter; +import runner.entities.Login; +import runner.security.utilities.JwtUtil; +import runner.services.LoginServices; +import runner.services.UserDetailServices; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; + +//Once authenticated at login and issued a token, the user should be able to access other resources with same token being passed into headers when requesting +//This class looks for the token in the header and authenticates it +@Component +public class JwtAuthorizationFilter extends OncePerRequestFilter { +/* @Autowired + private LoginServices loginServices*/; + + @Autowired + private UserDetailServices userDetailServices; + + @Autowired + private JwtUtil jwtUtil; + + @Override + protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { + final String authorizationHeader = httpServletRequest.getHeader("Authorization"); + + String username = null; + String jwtToken = null; + + //checks for "Bearer {token}" in header of request + if(authorizationHeader != null && authorizationHeader.startsWith("Bearer")){ + jwtToken = authorizationHeader.substring(7); + username = jwtUtil.extractUsername(jwtToken); + } + + //checks if the token has username and no security context, create an authentication token + if(username != null && SecurityContextHolder.getContext().getAuthentication() == null){ + UserDetails userDetails = userDetailServices.loadUserByUsername(username); + if(jwtUtil.validateToken(jwtToken,userDetails)){ + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, new ArrayList<>()); //arraylist is placeholder for authorities which is not used + usernamePasswordAuthenticationToken + .setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest)); + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + } + } + + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + +} \ No newline at end of file diff --git a/src/main/java/runner/security/models/AuthenticationResponse.java b/src/main/java/runner/security/models/AuthenticationResponse.java new file mode 100644 index 000000000..5c3d448ee --- /dev/null +++ b/src/main/java/runner/security/models/AuthenticationResponse.java @@ -0,0 +1,16 @@ +package runner.security.models; + +import org.springframework.security.authentication.AuthenticationManager; + +public class AuthenticationResponse { + private final String jwt; + + public AuthenticationResponse(String jwt){ + this.jwt = jwt; + } + + public String getJwt() { + return jwt; + } + +} diff --git a/src/main/java/runner/security/utilities/JwtUtil.java b/src/main/java/runner/security/utilities/JwtUtil.java new file mode 100644 index 000000000..05c74ec61 --- /dev/null +++ b/src/main/java/runner/security/utilities/JwtUtil.java @@ -0,0 +1,54 @@ +package runner.security.utilities; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +@Service +public class JwtUtil { + + private String SECRET_KEY = "secret"; + + public String extractUsername (String token){ + return extractClaim(token, Claims::getSubject); + } + + public Date extractExpiration(String token){ + return extractClaim(token, Claims::getExpiration); + } + + public T extractClaim(String token, Function claimsResolver){ + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } + + private Claims extractAllClaims (String token) { + return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); + } + + private Boolean isTokenExpired(String token){ + return extractExpiration(token).before(new Date()); + } + + public String generateToken(UserDetails userDetails){ + Map claims = new HashMap<>(); + return createToken(claims, userDetails.getUsername()); + } + + private String createToken(Map claims, String subject){ + return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis()+1000*60*30)) + .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact(); + } + + public Boolean validateToken(String token, UserDetails userDetails){ + final String username = extractUsername(token); + return (username.equals((userDetails.getUsername()))&& !isTokenExpired(token)); + } +} diff --git a/src/main/java/runner/services/AccountServices.java b/src/main/java/runner/services/AccountServices.java new file mode 100644 index 000000000..957a00615 --- /dev/null +++ b/src/main/java/runner/services/AccountServices.java @@ -0,0 +1,200 @@ +package runner.services; +import com.mifmif.common.regex.Generex; +import runner.entities.Account; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import runner.entities.Customer; +import runner.entities.Transaction; +import runner.repositories.AccountRepo; + +import javax.transaction.Transactional; +import java.time.LocalDate; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +@Transactional +@Service +public class AccountServices { + private final static Logger loggerService = Logger.getLogger(AccountServices.class.getName()); + + @Autowired + private AccountRepo accountRepo; + + @Autowired + private TransactionServices transactionServices; + + public Set getAllAccounts(String username){ + return accountRepo.findAccountsByCustomer_LoginUsername(username); + } + + public void saveAccount(Account account){ + accountRepo.save(account); + } + + public void SaveAccountWithUrl(Account account, String randomUrl){ + account.setEncryptedUrl(randomUrl); + accountRepo.save(account); + } + + public Account createAccount(Account account, String username) throws Exception { + loggerService.log(Level.INFO, "The customer's new account is being saved and given an account number."); + account.setCustomer(accountRepo.findAccountsByCustomer_LoginUsername(username).stream().findFirst().orElse(null).getCustomer()); + setUpAccount(account); + transferMoneyToNewAccount(account); + account.setEncryptedUrl(generateRandomUrl()); + return accountRepo.save(account); + } + + public void transferMoneyToNewAccount(Account newAccount) throws Exception { + Transaction customerTransaction = newAccount.getTransactions().stream().findFirst().orElse(null); + Account sourceAccount = getAccountByAccountNumber( + customerTransaction.getAccounts().stream().findFirst().orElse(null).getAccountNumber()); + transferMoney(customerTransaction,sourceAccount,newAccount); + //removes the empty transaction owned by the new account due to structure of the JSON, newaccount->transactions->account + newAccount.getTransactions().remove(newAccount.getTransactions().stream() + .filter(transaction -> transaction.getTransactionBalance()==null).findFirst().orElse(null)); + } + + public Account setUpAccount(Account account) { + Boolean created = false; + while (!created) { + //double temp = Math.floor(Math.random() * 1000000000); <--this only makes a 9 digit number + long number = (long) Math.floor(Math.random() * 9_000_000_000L) + 1_000_000_000L; + if (accountRepo.findAccountByAccountNumber(String.valueOf(number)) == null) { + account.setAccountNumber(String.valueOf(number)); + account.setDateOfOpening(LocalDate.now()); + account.setBalance(0.00); + account.setInterestRate(account.getInterestRate()); + created = true; + } + } + return account; + } + + public Account getAccountByEncryptedUrl(String encryptedUrl){ + Account individualAccount = accountRepo.findAccountByEncryptedUrl(encryptedUrl); + List sortedList = accountRepo.findAccountByEncryptedUrl(encryptedUrl).getTransactions().stream() + .sorted(Comparator.comparingLong(Transaction::getId).reversed()).collect(Collectors.toList()); + individualAccount.setTransactions(sortedList); + return individualAccount; + } + + public Account getAccountByAccountNumber(String accountNumber){ + return accountRepo.findAccountByAccountNumber(accountNumber); + } + +// public Boolean removeAccount(String encryptedUrl){ +// Account testAcct= accountRepo.findAccountByEncryptedUrl(encryptedUrl); +// Double testBalance = testAcct.getBalance(); +// Customer customer = testAcct.getCustomer(); +// if(accountRepo.findAccountByEncryptedUrl(encryptedUrl).getBalance()==0) { +// Integer testRemoveInt = accountRepo.deleteAccountByEncryptedUrl(encryptedUrl); +// //Integer myAcct = accountRepo.deleteByEncryptedUrl(encryptedUrl); +// Set myAccts = customer.getAccounts(); +// myAccts.remove(testAcct); +// +// return true; +// } +// return false; +// } + +// //REMOVE if not used +// public Optional updateAccount(Long id, Account account) throws Exception{ +// loggerService.log(Level.INFO, "Attempting to update customer's account # " + id); +// if (accountRepo.existsById(id) == true) { +// loggerService.log(Level.INFO, "The customer is updating their account # " + id); +// Account accountFromDB = accountRepo.findAccountById(id); +// accountFromDB.setAccountType(account.getAccountType()); +// accountFromDB.setAccountNumber(account.getAccountNumber()); +// accountFromDB.setInterestRate(account.getInterestRate()); +// accountFromDB.setDateOfOpening(account.getDateOfOpening()); +// accountFromDB.setRoutingNumber(account.getRoutingNumber()); +// accountFromDB.setBalance(account.getBalance()); +// return Optional.of(accountFromDB); +// } +// loggerService.log(Level.WARNING, "The account # " + id + "does not exist to be updated"); +// throw new Exception("Account does not exist"); +// } + + //iterate through set to get accounts but should only be one at any time + public Account iteratorReturn(Iterator iterator){ + while(iterator.hasNext()){ + return iterator.next(); + } + return null; + } + + public Account[] transferMoney(Transaction transaction, Account fromAccount, Account toAccount) throws Exception{ + Double amount = transaction.getTransactionAmount(); + + //check balance; + if(amount>fromAccount.getBalance()){ + throw new Exception("Insufficient funds"); + } + + //do the math, all that stuff below is to make sure the number stays 2 decimal places + fromAccount.setBalance(Math.round((fromAccount.getBalance() - amount)*100.0)/100.0); + toAccount.setBalance(Math.round((toAccount.getBalance() + amount)*100.0)/100.0); + + //adding new transactions to account's transactions set + ArrayList transactionsList = transactionServices.setAllTransactions(transaction, fromAccount, toAccount); + List fromSet = fromAccount.getTransactions(); + List toSet = toAccount.getTransactions(); + fromSet.add(transactionsList.get(0)); + toSet.add(transactionsList.get(1)); + fromAccount.setTransactions(fromSet); + toAccount.setTransactions(toSet); + + Account[] accountArray = {fromAccount,toAccount}; + return accountArray; + } + + //need to add method inside here to check if the routing and account numbers are valid + public Account deposit(Transaction transaction, String encryptedUrl) throws Exception{ + loggerService.log(Level.INFO, "The customer is making a deposit"); + Account toAccount = accountRepo.findAccountByEncryptedUrl(encryptedUrl); + + Iterator iterator = transaction.getAccounts().iterator(); + String accountNum = iteratorReturn(iterator).getAccountNumber(); + Account fromAccount = accountRepo.findAccountByAccountNumber(accountNum); + + Account[] myAccountArray = transferMoney(transaction,fromAccount,toAccount); + + accountRepo.save(myAccountArray[0]); //1st element in list/array always account money is moving out of + return accountRepo.save(myAccountArray[1]); //2nd element in list/array always account money is moving into + } + + //need to add method inside here to check if the routing and account numbers are valid + public Account withdraw(Transaction transaction, String encryptedUrl) throws Exception{ + loggerService.log(Level.INFO, "The customer is making a withdrawal"); + Account fromAccount = accountRepo.findAccountByEncryptedUrl(encryptedUrl); + + Iterator iterator = transaction.getAccounts().iterator(); + String accountNum = iteratorReturn(iterator).getAccountNumber(); + Account toAccount = accountRepo.findAccountByAccountNumber(accountNum); + + Account[] myAccountArray = transferMoney(transaction,fromAccount,toAccount); + + accountRepo.save(myAccountArray[1]); //1st element in list/array always account money is moving out of + return accountRepo.save(myAccountArray[0]); //2nd element in list/array always account money is moving into + } + + public String logout(String username){ + this.getAllAccounts(username).stream().forEach(a->a.setEncryptedUrl(null)); + this.getAllAccounts(username).stream().forEach(a->this.saveAccount(a)); + return "You have been logged out"; + } + + //generate 35-40 random characters + public String generateRandomUrl() { + Generex generex = new Generex("[A-Za-z0-9]{35,40}"); + String randomString = generex.random(); + return randomString; + } + + + +} \ No newline at end of file diff --git a/src/main/java/runner/services/CustomerServices.java b/src/main/java/runner/services/CustomerServices.java new file mode 100644 index 000000000..55724ff99 --- /dev/null +++ b/src/main/java/runner/services/CustomerServices.java @@ -0,0 +1,174 @@ +package runner.services; +import com.fasterxml.jackson.databind.util.JSONPObject; +import com.mifmif.common.regex.Generex; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import runner.entities.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import runner.repositories.CustomerRepo; + +import javax.transaction.Transactional; +import java.text.ParseException; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Service +public class CustomerServices { + //object for logging information,warning,error + private final static Logger loggerService = Logger.getLogger(CustomerServices.class.getName()); + + //Autowired the customerService + @Autowired + private CustomerRepo customerRepo; + + @Autowired + private AccountServices accountServices; + + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; + + //Save the customer in the DB + public Customer createCustomer(Customer customer) throws Exception { + loggerService.log(Level.INFO, "The customer information is being checked"); + if(!checkLogin(customer.getLogin())) { + customer.getLogin().setPassword(bCryptPasswordEncoder.encode(customer.getLogin().getPassword())); //encrypts the password before saving + customer.setSocialSecurity(bCryptPasswordEncoder.encode(customer.getSocialSecurity())); //encrypts the SSN before saving + //get the accounts from the customer and set the customer id in accounts table before saving the Customer. + Account newAccount = customer.getAccounts().stream().findFirst().orElse(null); + //customer.getAccounts().stream().forEach(account -> account.setCustomer(customer)); -Gunjan's method + newAccount.setCustomer(customer); + //passing the account to "createAccount" in accountServices to generate the account number + accountServices.setUpAccount(newAccount); + //doing the deposit from the source account; + accountServices.transferMoneyToNewAccount(newAccount); + loggerService.log(Level.INFO, "The customer information is being saved" + checkLogin(customer.getLogin())); + return customerRepo.save(customer); + } + return null; + } + + //Check if the username already exist + public Boolean checkLogin(Login login) { + loggerService.log(Level.INFO, "I am in first line of checkLogin"); + //List logins= customerRepo.findAllLoginsNative(); + List logins= customerRepo.findAll().stream().map(Customer::getLogin).map(Login::getUsername).collect(Collectors.toList()); + loggerService.log(Level.INFO, "I am have passed customerRepo.findAllLoginsNative"); + long count = logins.stream().filter(name -> name.equalsIgnoreCase(login.getUsername())).count(); + return count!=0 ? true:false; + } + + //Find Customer from DB using the logged in user name + public Customer readCustomerByLogin(String name) { + loggerService.log(Level.INFO, "The customer information is being read"); + Customer customer = customerRepo.findCustomerByLoginUsername(name); + if (customer != null) { + loggerService.log(Level.INFO, "The customer is found and being returned"); + return customer; + } else { + loggerService.log(Level.WARNING, "The customer could not be found, returned null"); + return null; + } + } + //Delete the customer from DB after checking that all account balance are < 0 + //Returns 0 = Deleted , 1 : Customer not found , 2 : Accounts with > 0 balance exist + public int deleteCustomer(Long id) { + Customer customer = customerRepo.findCustomerById(id); + if (customer != null) { + if (customer.getAccounts() != null) { + return checkAccountBalanceAndDelete(id, customer); + } + else + { + customerRepo.delete(customer); + loggerService.log(Level.INFO, "User has been deleted as no accounts found for this customer"); + return 0; + } + } + loggerService.log(Level.WARNING, "The customer not found" + id); + return 1; + } + + // Used in above method to decide if the customer can be deleted + int checkAccountBalanceAndDelete(Long id, Customer customer) { + Set accounts; // To collect all accounts belonging to this customer + List result ; //To collect accounts with balance greater than 0 + accounts = getAllAccounts(id); + result = accounts.stream().filter((account) -> account.getBalance() > 0).collect(Collectors.toList()); + loggerService.log(Level.INFO, "Account list size " + result.size()); + if (result.size() == 0 && accounts.size() != 0) { + customerRepo.delete(customer); + loggerService.log(Level.INFO, "User has been deleted as account balance for all accounts 0 , All accounts are deleted as well."); + return 0; + } else if (result.size() > 0) { + loggerService.log(Level.WARNING, "The customer had a balance greater than 0 and could not remove the account # " + id); + return 2; + } + return 4; + } + + //Update phone number ,check syntax based on the REGEX + //Returns 0 = Updated , 1 : Customer not found , 2 : Phone number format not correct + public Customer updateCustomerPhoneNumber(String username, Customer tempCustomer) throws ParseException { + loggerService.log(Level.INFO, "Finding the customer to be updated"); + Customer customer = customerRepo.findCustomerByLoginUsername(username); + loggerService.log(Level.INFO, "Customer with"+username + "found to be updated"); + customer.setPhoneNumber(tempCustomer.getPhoneNumber()); + loggerService.log(Level.INFO, "User with" +username + "phone number has been updated"); + return customerRepo.save(customer); + } + + //Update Email number ,check syntax based on the REGEX + //Returns 0 = Updated , 1 : Customer not found , 2 : Email format not correct + public Customer updateCustomerEmail(String username, Customer tempCustomer) { + loggerService.log(Level.INFO, "Finding the user to be updated"); + Customer customer = customerRepo.findCustomerByLoginUsername(username); + loggerService.log(Level.INFO, "customer with username "+username+ " found to be updated"); + customer.setEmail(tempCustomer.getEmail()); + loggerService.log(Level.INFO, "customer with username " + username + " email id has been updated"); + return customerRepo.save(customer); + } + + //Update Customer address + public Customer updateCustomerAddress(String username, Address address) { + loggerService.log(Level.INFO, "Finding the customer to be updated"); + Customer customer = customerRepo.findCustomerByLoginUsername(username); + address.setId(customer.getAddress().getId()); + loggerService.log(Level.INFO, "customer with username "+username+ " found to be updated"); + customer.setAddress(address); + loggerService.log(Level.INFO, "customer with username " + username + " address has been updated"); + return customerRepo.save(customer); + } + + //Delete if not needed + public Set getAllAccounts(Long id) { + loggerService.log(Level.INFO, "Finding the customer to get all accounts"); + Customer customer = customerRepo.findCustomerById(id); + + if (customer != null) { + loggerService.log(Level.INFO, "Accounts belonging to "+id+ " use has been found ,accounts are being returned"); + return customer.getAccounts(); + } + return null; + } + + @Transactional + public Customer removeAccount(String username, String encryptedUrl) throws Exception{ + Customer customer = customerRepo.findCustomerByLoginUsername(username); + List testAcct= customer.getAccounts().stream() + .filter(account -> account.getEncryptedUrl().equals(encryptedUrl)).collect(Collectors.toList()); + if(testAcct.get(0).getBalance()==0) { + + Set myAccts = customer.getAccounts().stream() + .filter(account -> !account.getEncryptedUrl().equals(encryptedUrl)).collect(Collectors.toSet()); + customer.getAccounts().clear(); + customer.getAccounts().addAll(myAccts); + return customerRepo.save(customer); + } + throw new Exception("Balance is not 0"); + } + +} diff --git a/src/main/java/runner/services/LoginServices.java b/src/main/java/runner/services/LoginServices.java new file mode 100644 index 000000000..b08c39c49 --- /dev/null +++ b/src/main/java/runner/services/LoginServices.java @@ -0,0 +1,42 @@ +package runner.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.User; +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.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import runner.entities.Login; +import runner.repositories.LoginRepo; + +import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Transactional +public class LoginServices{ //} implements UserDetailsService { <--Moved to UserDetailServices + + @Autowired + private LoginRepo loginRepo; + + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; + + + //need another password authentication done before allowing user to update their password + public Login updatePassword(Long userId, Login login) { + Login updatedLogin = loginRepo.findLoginById(userId); + updatedLogin.setPassword(bCryptPasswordEncoder.encode(login.getPassword())); + return loginRepo.save(updatedLogin); + } + + +//Lock after 3 attempts +//Security questions +//Forgot username +//Forgot password + +} \ No newline at end of file diff --git a/src/main/java/runner/services/TransactionServices.java b/src/main/java/runner/services/TransactionServices.java new file mode 100644 index 000000000..dd5dedc6d --- /dev/null +++ b/src/main/java/runner/services/TransactionServices.java @@ -0,0 +1,44 @@ +package runner.services; + +import runner.entities.Account; +import runner.entities.Transaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import runner.repositories.TransactionRepo; + +import java.lang.reflect.Array; +import java.time.LocalDate; +import java.util.*; + +@Service +public class TransactionServices { + public ArrayList setAllTransactions(Transaction transaction, Account fromAccount, Account toAccount){ + //{0 = withdraw, 1 = deposit} money always leaves from 'fromAccount' to 'toAccount' + ArrayList myList = new ArrayList(); + + myList.add(setOneTransaction(transaction, fromAccount, toAccount, true)); + myList.add(setOneTransaction(transaction, toAccount, fromAccount, false)); + return myList; + } + + public Transaction setOneTransaction(Transaction transaction, Account account1, Account account2, Boolean withdrawType) { + Transaction newTransaction = new Transaction(); + String AccountNum = account2.getAccountNumber(); //get the account number for formatting description + if(withdrawType) { + newTransaction.setTransactionDescription(String.format("Withdrawal to %s XXXXXXXX%s", account2.getAccountType(), + AccountNum.substring(AccountNum.length() - 4))); //format description with last 4 digits of account + newTransaction.setTransactionAmount(transaction.getTransactionAmount()*(-1)); //making "to" transaction amount negative + } + else{ + newTransaction.setTransactionDescription(String.format("Deposit from %s XXXXXXXX%s", account2.getAccountType(), + AccountNum.substring(AccountNum.length() - 4))); //format description with last 4 digits of account + newTransaction.setTransactionAmount(transaction.getTransactionAmount()); //making "to" transaction amount negative + } + + newTransaction.setTransactionBalance(account1.getBalance()); //set the new balance from account + newTransaction.setTransactionDate(LocalDate.now()); //set today's date + + return newTransaction; + } + +} diff --git a/src/main/java/runner/services/UserDetailServices.java b/src/main/java/runner/services/UserDetailServices.java new file mode 100644 index 000000000..4144a69e1 --- /dev/null +++ b/src/main/java/runner/services/UserDetailServices.java @@ -0,0 +1,24 @@ +package runner.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import runner.entities.Login; +import runner.repositories.LoginRepo; + +import java.util.ArrayList; + +@Service +public class UserDetailServices implements UserDetailsService { + @Autowired + private LoginRepo loginRepo; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Login login = loginRepo.findLoginByUsername(username); + return new User(login.getUsername(), login.getPassword(),new ArrayList<>()); //ArrayList is typically for the authority but not using this feature + } +} diff --git a/src/main/java/runner/views/Views.java b/src/main/java/runner/views/Views.java new file mode 100644 index 000000000..ae61fdabe --- /dev/null +++ b/src/main/java/runner/views/Views.java @@ -0,0 +1,58 @@ +package runner.views; + +public class Views { + + public static interface AccountNumber{ + + } + + public static interface AccountType{ + + } + + public static interface RoutingNumber{ + + } + + public static interface AccountOpening{ + + } + + public static class AllAccounts implements AccountNumber, AccountType, RoutingNumber, AccountActions, AccountOpening{ + /* + payload: multiple accounts: account number, account balance, account type, routingNumber, AccountOpening, + */ + } + + public static interface AccountActions{ + /* + payload: account balance + */ + } + + public static class AccountDetails implements AccountNumber, AccountType, AccountActions, AccountOpening, RoutingNumber{ + /* + payload: account balance, interest rate, date of creation, account number, routing number, account type, transactions + */ + } + + public static class AccountSpecific implements AccountActions, AccountNumber{ + /* + payload: account balance, transactions, account number + */ + } + + public static interface Email{ + } + + public static interface PhoneNumber{ + } + + public static interface Address{ + } + + public static class Profile implements Email, PhoneNumber, Address { + //everything in Customer except for SSN, password + } + +} diff --git a/src/main/java/services/AccountServices.java b/src/main/java/services/AccountServices.java deleted file mode 100644 index 655bbbcd2..000000000 --- a/src/main/java/services/AccountServices.java +++ /dev/null @@ -1,58 +0,0 @@ -package services; - -import entities.Account; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import repositories.AccountRepo; - -import java.util.Optional; - -@Service -public class AccountServices { - - @Autowired - private AccountRepo accountRepo; - //CRUD methods - - public Optional createAccount() - { - //Re-direct to POST in ACCOUNT controller - return null; - } - - public Optional readAccount() - { - //Re-direct to GET in ACCOUNT controller - return null; - } - public Boolean removeAccount() - { - //Re-direct to DELETE in ACCOUNT controller - return true; - } - - public Optional updateAccount() - { - //Re-direct to PUT in ACCOUNT controller - return null; - } - - public Double withdraw(Double amount, Long Id) - { - //Login to withdraw from the account - return 0d; - } - public Double deposit(Double amount , Long Id) - { - //Login to withdraw from the account - return 0d; - } - - - public Double transfer(Double amount , Long fromId ,Long toId) - { - //Login to withdraw from the account - return 0d; - } - -} diff --git a/src/main/java/services/LoginServices.java b/src/main/java/services/LoginServices.java deleted file mode 100644 index 9043abaea..000000000 --- a/src/main/java/services/LoginServices.java +++ /dev/null @@ -1,39 +0,0 @@ -package services; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import repositories.LoginRepo; - -@Service -public class LoginServices { - - @Autowired - private LoginRepo loginRepo; - - public Boolean checkUserCredential(String userName,String password) - { - //Check for username and password ,check about Tokens for user authentication - - return true; - } - - public Boolean logOut() - { - // Login for logOut - return true; - } - - // User authentication - - public Boolean autoLogOff() - { - return true; - } - - -//Lock after 3 attempts -//Security questions -//Forgot username -//Forgot password - -} diff --git a/src/main/java/services/TransactionServices.java b/src/main/java/services/TransactionServices.java deleted file mode 100644 index 1120222d6..000000000 --- a/src/main/java/services/TransactionServices.java +++ /dev/null @@ -1,36 +0,0 @@ -package services; - -import entities.TransactionHistory; -import org.springframework.beans.factory.annotation.Autowired; -import repositories.TransactionRepo; - -import java.util.Optional; - -public class TransactionServices { - @Autowired - private TransactionRepo transactionRepo; - //CRUD methods - public Optional createTransaction() - { - //Re-direct to POST in TransactionHistory controller - return null; - } - - public Optional readTransaction() - { - //Re-direct to GET in TransactionHistory controller - return null; - } - public Boolean removeTransaction() - { - //Re-direct to DELETE in TransactionHistory controller - return true; - } - - public Optional updateTransaction() - { - //Re-direct to PUT in TransactionHistory controller - return null; - } - -} diff --git a/src/main/java/services/UserServices.java b/src/main/java/services/UserServices.java deleted file mode 100644 index 385eac189..000000000 --- a/src/main/java/services/UserServices.java +++ /dev/null @@ -1,39 +0,0 @@ -package services; - -import entities.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import repositories.UserRepo; - -import java.util.Optional; - -@Service -public class UserServices { - //CRUD methods - @Autowired - private UserRepo userRepo; - - public Optional createUser(User user) - { - //Re-direct to POST in USER controller - return null; - } - - public Optional readUser(Long id) - { - //Re-direct to GET in USER controller - return null; - } - public Boolean deleteUser(Long id) - { - //Re-direct to DELETE in USER controller - return true; - } - - public Optional updateUser(Long id ,User user) - { - //Re-direct to PUT in USER controller - return null; - } - -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 945220da0..df6e3d65c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,3 @@ -spring.jpa.show-sql=true server.port=8080 spring.h2.console.enabled=true #spring.datasource.generate-unique-name=false @@ -8,9 +7,41 @@ spring.h2.console.enabled=true #spring.jpa.database-platform=org.hibernate.dialect.H2Dialect #spring.h2.console.settings.trace=false #spring.h2.console.settings.web-allow-others=false -spring.datasource.url=jdbc:mysql://localhost:3306/zipcode -spring.datasource.username=gunjan -spring.datasource.password=zipcode0 + +#Stored the values in environment variable +#spring.datasource.url=${JDBC_DATABASE_URL} +spring.datasource.url=${DB_URL} +spring.datasource.username=${DB_USER} +spring.datasource.password=${DB_PASS} +#Another way to encrypt password +#spring.datasource.password=ENC(dTbA3RZ3U1/RJPUcVcJIdkxmopJI1RZP) +#jasypt.encryptor.password=moneymanagement + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ### had to add this because of the .hibernate_sequence doesn't exist errors! -spring.jpa.hibernate.use-new-id-generator-mappings= false \ No newline at end of file +spring.jpa.hibernate.use-new-id-generator-mappings= false + +#set to 'none' to .ddl-auto if you want to create mysql tables from "schema.sql" files instead of from entities +spring.jpa.hibernate.ddl-auto = none +spring.jpa.generate-ddl=true +spring.jpa.show-sql=true +#tells hibernate where to find initial data to import into mysql if .ddl-auto method is used +spring.jpa.properties.hibernate.hbm2ddl.import_files= classpath:db/import.sql +#below is needed for JPA to read SQL language from import.sql +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect +#spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy + +#set to 'always' if you want to create mysql tables from "schema.sql" file instead of from entities +spring.datasource.initialization-mode=never + +#tells hibernate where to find the data and schema file +#spring.datasource.data= classpath:db/data.sql +#spring.datasource.schema = classpath:db/schema.sql + +#Need this for testing to work properly +spring.main.allow-bean-definition-overriding=true + + +#jdbc:mysql://localhost:3306/moneymanagement +#jdbc:mysql://mysql-moneymanagement.cvq8xhrssade.us-east-2.rds.amazonaws.com/moneymanagement + diff --git a/src/main/resources/db/import.sql b/src/main/resources/db/import.sql new file mode 100644 index 000000000..41ac5be6a --- /dev/null +++ b/src/main/resources/db/import.sql @@ -0,0 +1,40 @@ +-- MySQL dump 10.13 Distrib 8.0.22, for macos10.15 (x86_64) +-- +-- Host: localhost Database: moneymanagement +-- ------------------------------------------------------ +-- Server version 8.0.22 + +-- +-- Dumping data for table `account` +-- + +INSERT INTO `account` VALUES (1,'1234567890','CHECKING',999999999999,'2004-01-22',NULL,.2,'091000022',1); +INSERT INTO `account` VALUES (2,'1111111111','CHECKING',0,'2004-01-22',NULL,.2,'091000022',1),(3,'4444444444','SAVINGS',25000,'2004-01-22',NULL,.85,'091000022',1); +# INSERT INTO `account` VALUES (5,'2222222222','CHECKING',0,'2004-01-22',NULL,.2,'091000022',3); +-- +-- Dumping data for table `login` +-- + +INSERT INTO `login` VALUES (1,'$2a$10$DM98Ynu/prVcywurljSHSOko73BKJb29RFW3vCGFYT9DBAW6Jd1W2','user1'); +INSERT INTO `login` VALUES (3,'$2a$10$DM98Ynu/prVcywurljSHSOko73BKJb29RFW3vCGFYT9DBAW6Jd1W2','user3'); +-- +-- Dumping data for table `transaction_history` +-- + + -- INSERT INTO `transaction` VALUES (1,'1245451',10.21,'2004-01-22','testing',1); + +-- +-- Dumping data for table `customer` +-- + +INSERT INTO `customer` VALUES (1,'2012-05-05','tom@gmail.com','Peggy','Patel','G','5122264785','435435345',1); +INSERT INTO `customer` VALUES (3,'2012-05-05','tom@gmail.com','Tom','Walter','G','5122264785','435435345',3); + +-- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +-- +-- Dumping data for table `address` +-- + +INSERT INTO `address` VALUES (1,'Bear','123 A st','Second Line','DE','19801'); +INSERT INTO `address` VALUES (3,'Austin','123 A st','Second Line','Texas','19147'); \ No newline at end of file diff --git a/src/main/resources/rds-combined-ca-bundle.pem b/src/main/resources/rds-combined-ca-bundle.pem new file mode 100644 index 000000000..864a818dd --- /dev/null +++ b/src/main/resources/rds-combined-ca-bundle.pem @@ -0,0 +1,720 @@ +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSUwIwYDVQQDDBxBbWF6b24gUkRTIGFwLWVhc3QtMSBSb290IENBMB4XDTE5MDIx +NzAyNDcwMFoXDTIyMDYwMTEyMDAwMFowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6b24g +V2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSAwHgYDVQQD +DBdBbWF6b24gUkRTIGFwLWVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOcJAUofyJuBuPr5ISHi/Ha5ed8h3eGdzn4MBp6rytPOg9NVGRQs +O93fNGCIKsUT6gPuk+1f1ncMTV8Y0Fdf4aqGWme+Khm3ZOP3V1IiGnVq0U2xiOmn +SQ4Q7LoeQC4lC6zpoCHVJyDjZ4pAknQQfsXb77Togdt/tK5ahev0D+Q3gCwAoBoO +DHKJ6t820qPi63AeGbJrsfNjLKiXlFPDUj4BGir4dUzjEeH7/hx37na1XG/3EcxP +399cT5k7sY/CR9kctMlUyEEUNQOmhi/ly1Lgtihm3QfjL6K9aGLFNwX35Bkh9aL2 +F058u+n8DP/dPeKUAcJKiQZUmzuen5n57x8CAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFlqgF4FQlb9yP6c+Q3E +O3tXv+zOMB8GA1UdIwQYMBaAFK9T6sY/PBZVbnHcNcQXf58P4OuPMA0GCSqGSIb3 +DQEBCwUAA4IBAQDeXiS3v1z4jWAo1UvVyKDeHjtrtEH1Rida1eOXauFuEQa5tuOk +E53Os4haZCW4mOlKjigWs4LN+uLIAe1aFXGo92nGIqyJISHJ1L+bopx/JmIbHMCZ +0lTNJfR12yBma5VQy7vzeFku/SisKwX0Lov1oHD4MVhJoHbUJYkmAjxorcIHORvh +I3Vj5XrgDWtLDPL8/Id/roul/L+WX5ir+PGScKBfQIIN2lWdZoqdsx8YWqhm/ikL +C6qNieSwcvWL7C03ri0DefTQMY54r5wP33QU5hJ71JoaZI3YTeT0Nf+NRL4hM++w +Q0veeNzBQXg1f/JxfeA39IDIX1kiCf71tGlT +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEDCCAvigAwIBAgIJAJF3HxEqKM4lMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJEUyBhcC1lYXN0LTEgUm9vdCBDQTAe +Fw0xOTAyMTcwMjQ2MTFaFw0yNDAyMTYwMjQ2MTFaMIGUMQswCQYDVQQGEwJVUzEQ +MA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UECgwZ +QW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEl +MCMGA1UEAwwcQW1hem9uIFJEUyBhcC1lYXN0LTEgUm9vdCBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOCVr1Yj5IW4XWa9QOLGJDSz4pqIM6BAbqQp +gYvzIO4Lv8c8dEnuuuCY8M/zOrJ1iQJ3cDiKGa32HVBVcH+nUdXzw4Jq5jw0hsb6 +/WW2RD2aUe4jCkRD5wNzmeHM4gTgtMZnXNVHpELgKR4wVhSHEfWFTiMsZi35y8mj +PL98Mz/m/nMnB/59EjMvcJMrsUljHO6B9BMEcvNkwvre9xza0BQWKyiVRcbOpoj1 +w4BPtYYZ+dW2QKw9AmYXwAmCLeATsxrHIJ/IbzS7obxv2QN2Eh4pJ3ghRCFv1XM9 +XVkm13oiCjj7jsxAwF7o+VggPl/GG+/Gwk+TLuaTFNAtROpPxL8CAwEAAaNjMGEw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9T6sY/ +PBZVbnHcNcQXf58P4OuPMB8GA1UdIwQYMBaAFK9T6sY/PBZVbnHcNcQXf58P4OuP +MA0GCSqGSIb3DQEBCwUAA4IBAQBBY+KATaT7ndYT3Ky0VWaiwNfyl1u3aDxr+MKP +VeDhtOhlob5u0E+edOXUvEXd4A+ntS+U0HmwvtMXtQbQ2EJbsNRqZnS8KG9YB2Yc +Q99auphW3wMjwHRtflLO5h14aa9SspqJJgcM1R7Z3pAYeq6bpBDxZSGrYtWI64q4 +h4i67qWAGDFcXSTW1kJ00GMlBCIGTeYiu8LYutdsDWzYKkeezJRjx9VR4w7A7e1G +WmY4aUg/8aPxCioY2zEQKNl55Ghg6Dwy+6BxaV6RlV9r9EaSCai11p1bgS568WQn +4WNQK36EGe37l2SOpDB6STrq57/rjREvmq803Ylg/Gf6qqzK +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTA1 +MTAyMTU4NDNaFw0yNTA2MDExMjAwMDBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBtZS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAudOYPZH+ihJAo6hNYMB5izPVBe3TYhnZm8+X3IoaaYiKtsp1 +JJhkTT0CEejYIQ58Fh4QrMUyWvU8qsdK3diNyQRoYLbctsBPgxBR1u07eUJDv38/ +C1JlqgHmMnMi4y68Iy7ymv50QgAMuaBqgEBRI1R6Lfbyrb2YvH5txjJyTVMwuCfd +YPAtZVouRz0JxmnfsHyxjE+So56uOKTDuw++Ho4HhZ7Qveej7XB8b+PIPuroknd3 +FQB5RVbXRvt5ZcVD4F2fbEdBniF7FAF4dEiofVCQGQ2nynT7dZdEIPfPdH3n7ZmE +lAOmwHQ6G83OsiHRBLnbp+QZRgOsjkHJxT20bQIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUOEVDM7VomRH4HVdA +QvIMNq2tXOcwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXdaiqYwDQYJKoZI +hvcNAQELBQADggEBAHhvMssj+Th8IpNePU6RH0BiL6o9c437R3Q4IEJeFdYL+nZz +PW/rELDPvLRUNMfKM+KzduLZ+l29HahxefejYPXtvXBlq/E/9czFDD4fWXg+zVou +uDXhyrV4kNmP4S0eqsAP/jQHPOZAMFA4yVwO9hlqmePhyDnszCh9c1PfJSBh49+b +4w7i/L3VBOMt8j3EKYvqz0gVfpeqhJwL4Hey8UbVfJRFJMJzfNHpePqtDRAY7yjV +PYquRaV2ab/E+/7VFkWMM4tazYz/qsYA2jSH+4xDHvYk8LnsbcrF9iuidQmEc5sb +FgcWaSKG4DJjcI5k7AJLWcXyTDt21Ci43LE+I9Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJANew34ehz5l8MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBtZS1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkwNTEwMjE0ODI3WhcNMjQwNTA4MjE0ODI3WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgbWUtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp7BYV88MukcY+rq0r79+C8UzkT30fEfT +aPXbx1d6M7uheGN4FMaoYmL+JE1NZPaMRIPTHhFtLSdPccInvenRDIatcXX+jgOk +UA6lnHQ98pwN0pfDUyz/Vph4jBR9LcVkBbe0zdoKKp+HGbMPRU0N2yNrog9gM5O8 +gkU/3O2csJ/OFQNnj4c2NQloGMUpEmedwJMOyQQfcUyt9CvZDfIPNnheUS29jGSw +ERpJe/AENu8Pxyc72jaXQuD+FEi2Ck6lBkSlWYQFhTottAeGvVFNCzKszCntrtqd +rdYUwurYsLTXDHv9nW2hfDUQa0mhXf9gNDOBIVAZugR9NqNRNyYLHQIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU54cf +DjgwBx4ycBH8+/r8WXdaiqYwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXda +iqYwDQYJKoZIhvcNAQELBQADggEBAIIMTSPx/dR7jlcxggr+O6OyY49Rlap2laKA +eC/XI4ySP3vQkIFlP822U9Kh8a9s46eR0uiwV4AGLabcu0iKYfXjPkIprVCqeXV7 +ny9oDtrbflyj7NcGdZLvuzSwgl9SYTJp7PVCZtZutsPYlbJrBPHwFABvAkMvRtDB +hitIg4AESDGPoCl94sYHpfDfjpUDMSrAMDUyO6DyBdZH5ryRMAs3lGtsmkkNUrso +aTW6R05681Z0mvkRdb+cdXtKOSuDZPoe2wJJIaz3IlNQNSrB5TImMYgmt6iAsFhv +3vfTSTKrZDNTJn4ybG6pq1zWExoXsktZPylJly6R3RBwV6nwqBM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEETCCAvmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSUwIwYDVQQDDBxBbWF6b24gUkRTIEJldGEgUm9vdCAyMDE5IENBMB4XDTE5MDgy +MDE3MTAwN1oXDTI0MDgxOTE3MzgyNlowgZkxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6b24g +V2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSowKAYDVQQD +DCFBbWF6b24gUkRTIEJldGEgdXMtZWFzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDTNCOlotQcLP8TP82U2+nk0bExVuuMVOgFeVMx +vbUHZQeIj9ikjk+jm6eTDnnkhoZcmJiJgRy+5Jt69QcRbb3y3SAU7VoHgtraVbxF +QDh7JEHI9tqEEVOA5OvRrDRcyeEYBoTDgh76ROco2lR+/9uCvGtHVrMCtG7BP7ZB +sSVNAr1IIRZZqKLv2skKT/7mzZR2ivcw9UeBBTUf8xsfiYVBvMGoEsXEycjYdf6w +WV+7XS7teNOc9UgsFNN+9AhIBc1jvee5E//72/4F8pAttAg/+mmPUyIKtekNJ4gj +OAR2VAzGx1ybzWPwIgOudZFHXFduxvq4f1hIRPH0KbQ/gkRrAgMBAAGjZjBkMA4G +A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTkvpCD +6C43rar9TtJoXr7q8dkrrjAfBgNVHSMEGDAWgBStoQwVpbGx87fxB3dEGDqKKnBT +4TANBgkqhkiG9w0BAQsFAAOCAQEAJd9fOSkwB3uVdsS+puj6gCER8jqmhd3g/J5V +Zjk9cKS8H0e8pq/tMxeJ8kpurPAzUk5RkCspGt2l0BSwmf3ahr8aJRviMX6AuW3/ +g8aKplTvq/WMNGKLXONa3Sq8591J+ce8gtOX/1rDKmFI4wQ/gUzOSYiT991m7QKS +Fr6HMgFuz7RNJbb3Fy5cnurh8eYWA7mMv7laiLwTNsaro5qsqErD5uXuot6o9beT +a+GiKinEur35tNxAr47ax4IRubuIzyfCrezjfKc5raVV2NURJDyKP0m0CCaffAxE +qn2dNfYc3v1D8ypg3XjHlOzRo32RB04o8ALHMD9LSwsYDLpMag== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEDCCAvigAwIBAgIJAKFMXyltvuRdMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTAe +Fw0xOTA4MTkxNzM4MjZaFw0yNDA4MTkxNzM4MjZaMIGUMQswCQYDVQQGEwJVUzEQ +MA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UECgwZ +QW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEl +MCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMkZdnIH9ndatGAcFo+DppGJ1HUt4x+zeO+0 +ZZ29m0sfGetVulmTlv2d5b66e+QXZFWpcPQMouSxxYTW08TbrQiZngKr40JNXftA +atvzBqIImD4II0ZX5UEVj2h98qe/ypW5xaDN7fEa5e8FkYB1TEemPaWIbNXqchcL +tV7IJPr3Cd7Z5gZJlmujIVDPpMuSiNaal9/6nT9oqN+JSM1fx5SzrU5ssg1Vp1vv +5Xab64uOg7wCJRB9R2GC9XD04odX6VcxUAGrZo6LR64ZSifupo3l+R5sVOc5i8NH +skdboTzU9H7+oSdqoAyhIU717PcqeDum23DYlPE2nGBWckE+eT8CAwEAAaNjMGEw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK2hDBWl +sbHzt/EHd0QYOooqcFPhMB8GA1UdIwQYMBaAFK2hDBWlsbHzt/EHd0QYOooqcFPh +MA0GCSqGSIb3DQEBCwUAA4IBAQAO/718k8EnOqJDx6wweUscGTGL/QdKXUzTVRAx +JUsjNUv49mH2HQVEW7oxszfH6cPCaupNAddMhQc4C/af6GHX8HnqfPDk27/yBQI+ +yBBvIanGgxv9c9wBbmcIaCEWJcsLp3HzXSYHmjiqkViXwCpYfkoV3Ns2m8bp+KCO +y9XmcCKRaXkt237qmoxoh2sGmBHk2UlQtOsMC0aUQ4d7teAJG0q6pbyZEiPyKZY1 +XR/UVxMJL0Q4iVpcRS1kaNCMfqS2smbLJeNdsan8pkw1dvPhcaVTb7CvjhJtjztF +YfDzAI5794qMlWxwilKMmUvDlPPOTen8NNHkLwWvyFCH7Doh +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFzCCAv+gAwIBAgICFSUwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSgwJgYDVQQDDB9BbWF6b24gUkRTIFByZXZpZXcgUm9vdCAyMDE5IENBMB4XDTE5 +MDgyMTIyMzk0N1oXDTI0MDgyMTIyMjk0OVowgZwxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6 +b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMS0wKwYD +VQQDDCRBbWF6b24gUkRTIFByZXZpZXcgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0dB/U7qRnSf05wOi7m10Pa2uPMTJv +r6U/3Y17a5prq5Zr4++CnSUYarG51YuIf355dKs+7Lpzs782PIwCmLpzAHKWzix6 +pOaTQ+WZ0+vUMTxyqgqWbsBgSCyP7pVBiyqnmLC/L4az9XnscrbAX4pNaoJxsuQe +mzBo6yofjQaAzCX69DuqxFkVTRQnVy7LCFkVaZtjNAftnAHJjVgQw7lIhdGZp9q9 +IafRt2gteihYfpn+EAQ/t/E4MnhrYs4CPLfS7BaYXBycEKC5Muj1l4GijNNQ0Efo +xG8LSZz7SNgUvfVwiNTaqfLP3AtEAWiqxyMyh3VO+1HpCjT7uNBFtmF3AgMBAAGj +ZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW +BBQtinkdrj+0B2+qdXngV2tgHnPIujAfBgNVHSMEGDAWgBRp0xqULkNh/w2ZVzEI +o2RIY7O03TANBgkqhkiG9w0BAQsFAAOCAQEAtJdqbCxDeMc8VN1/RzCabw9BIL/z +73Auh8eFTww/sup26yn8NWUkfbckeDYr1BrXa+rPyLfHpg06kwR8rBKyrs5mHwJx +bvOzXD/5WTdgreB+2Fb7mXNvWhenYuji1MF+q1R2DXV3I05zWHteKX6Dajmx+Uuq +Yq78oaCBSV48hMxWlp8fm40ANCL1+gzQ122xweMFN09FmNYFhwuW+Ao+Vv90ZfQG +PYwTvN4n/gegw2TYcifGZC2PNX74q3DH03DXe5fvNgRW5plgz/7f+9mS+YHd5qa9 +tYTPUvoRbi169ou6jicsMKUKPORHWhiTpSCWR1FMMIbsAcsyrvtIsuaGCQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFjCCAv6gAwIBAgIJAMzYZJ+R9NBVMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBD +QTAeFw0xOTA4MjEyMjI5NDlaFw0yNDA4MjEyMjI5NDlaMIGXMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBDQTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7kkS6vjgKKQTPynC2NjdN5aPPV +O71G0JJS/2ARVBVJd93JLiGovVJilfWYfwZCs4gTRSSjrUD4D4HyqCd6A+eEEtJq +M0DEC7i0dC+9WNTsPszuB206Jy2IUmxZMIKJAA1NHSbIMjB+b6/JhbSUi7nKdbR/ +brj83bF+RoSA+ogrgX7mQbxhmFcoZN9OGaJgYKsKWUt5Wqv627KkGodUK8mDepgD +S3ZfoRQRx3iceETpcmHJvaIge6+vyDX3d9Z22jmvQ4AKv3py2CmU2UwuhOltFDwB +0ddtb39vgwrJxaGfiMRHpEP1DfNLWHAnA69/pgZPwIggidS+iBPUhgucMp8CAwEA +AaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FGnTGpQuQ2H/DZlXMQijZEhjs7TdMB8GA1UdIwQYMBaAFGnTGpQuQ2H/DZlXMQij +ZEhjs7TdMA0GCSqGSIb3DQEBCwUAA4IBAQC3xz1vQvcXAfpcZlngiRWeqU8zQAMQ +LZPCFNv7PVk4pmqX+ZiIRo4f9Zy7TrOVcboCnqmP/b/mNq0gVF4O+88jwXJZD+f8 +/RnABMZcnGU+vK0YmxsAtYU6TIb1uhRFmbF8K80HHbj9vSjBGIQdPCbvmR2zY6VJ +BYM+w9U9hp6H4DVMLKXPc1bFlKA5OBTgUtgkDibWJKFOEPW3UOYwp9uq6pFoN0AO +xMTldqWFsOF3bJIlvOY0c/1EFZXu3Ns6/oCP//Ap9vumldYMUZWmbK+gK33FPOXV +8BQ6jNC29icv7lLDpRPwjibJBXX+peDR5UK4FdYcswWEB1Tix5X8dYu6 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgICVIYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDQxNzEz +MDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h +em9uIFJEUyBhcC1zb3V0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDUYOz1hGL42yUCrcsMSOoU8AeD/3KgZ4q7gP+vAz1WnY9K/kim +eWN/2Qqzlo3+mxSFQFyD4MyV3+CnCPnBl9Sh1G/F6kThNiJ7dEWSWBQGAB6HMDbC +BaAsmUc1UIz8sLTL3fO+S9wYhA63Wun0Fbm/Rn2yk/4WnJAaMZcEtYf6e0KNa0LM +p/kN/70/8cD3iz3dDR8zOZFpHoCtf0ek80QqTich0A9n3JLxR6g6tpwoYviVg89e +qCjQ4axxOkWWeusLeTJCcY6CkVyFvDAKvcUl1ytM5AiaUkXblE7zDFXRM4qMMRdt +lPm8d3pFxh0fRYk8bIKnpmtOpz3RIctDrZZxAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBT99wKJftD3jb4sHoHG +i3uGlH6W6TAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAZ17hhr3dII3hUfuHQ1hPWGrpJOX/G9dLzkprEIcCidkmRYl+ +hu1Pe3caRMh/17+qsoEErmnVq5jNY9X1GZL04IZH8YbHc7iRHw3HcWAdhN8633+K +jYEB2LbJ3vluCGnCejq9djDb6alOugdLMJzxOkHDhMZ6/gYbECOot+ph1tQuZXzD +tZ7prRsrcuPBChHlPjmGy8M9z8u+kF196iNSUGC4lM8vLkHM7ycc1/ZOwRq9aaTe +iOghbQQyAEe03MWCyDGtSmDfr0qEk+CHN+6hPiaL8qKt4s+V9P7DeK4iW08ny8Ox +AVS7u0OK/5+jKMAMrKwpYrBydOjTUTHScocyNw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIJAMc0ZzaSUK51MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkw +ODIyMTcwODUwWhcNMjQwODIyMTcwODUwWjCBjzELMAkGA1UEBhMCVVMxEDAOBgNV +BAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoMGUFtYXpv +biBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxIDAeBgNV +BAMMF0FtYXpvbiBSRFMgUm9vdCAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEArXnF/E6/Qh+ku3hQTSKPMhQQlCpoWvnIthzX6MK3p5a0eXKZ +oWIjYcNNG6UwJjp4fUXl6glp53Jobn+tWNX88dNH2n8DVbppSwScVE2LpuL+94vY +0EYE/XxN7svKea8YvlrqkUBKyxLxTjh+U/KrGOaHxz9v0l6ZNlDbuaZw3qIWdD/I +6aNbGeRUVtpM6P+bWIoxVl/caQylQS6CEYUk+CpVyJSkopwJlzXT07tMoDL5WgX9 +O08KVgDNz9qP/IGtAcRduRcNioH3E9v981QO1zt/Gpb2f8NqAjUUCUZzOnij6mx9 +McZ+9cWX88CRzR0vQODWuZscgI08NvM69Fn2SQIDAQABo2MwYTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUc19g2LzLA5j0Kxc0LjZa +pmD/vB8wHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJKoZIhvcN +AQELBQADggEBAHAG7WTmyjzPRIM85rVj+fWHsLIvqpw6DObIjMWokpliCeMINZFV +ynfgBKsf1ExwbvJNzYFXW6dihnguDG9VMPpi2up/ctQTN8tm9nDKOy08uNZoofMc +NUZxKCEkVKZv+IL4oHoeayt8egtv3ujJM6V14AstMQ6SwvwvA93EP/Ug2e4WAXHu +cbI1NAbUgVDqp+DRdfvZkgYKryjTWd/0+1fS8X1bBZVWzl7eirNVnHbSH2ZDpNuY +0SBd8dj5F6ld3t58ydZbrTHze7JJOd8ijySAp4/kiu9UfZWuTPABzDa/DSdz9Dk/ +zPW4CXXvhLmE02TA9/HeCw3KEHIwicNuEfw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICQ2QwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDUxODQ2 +MjlaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBzYS1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMMvR+ReRnOzqJzoaPipNTt1Z2VA968jlN1+SYKUrYM3No+Vpz0H +M6Tn0oYB66ByVsXiGc28ulsqX1HbHsxqDPwvQTKvO7SrmDokoAkjJgLocOLUAeld +5AwvUjxGRP6yY90NV7X786MpnYb2Il9DIIaV9HjCmPt+rjy2CZjS0UjPjCKNfB8J +bFjgW6GGscjeyGb/zFwcom5p4j0rLydbNaOr9wOyQrtt3ZQWLYGY9Zees/b8pmcc +Jt+7jstZ2UMV32OO/kIsJ4rMUn2r/uxccPwAc1IDeRSSxOrnFKhW3Cu69iB3bHp7 +JbawY12g7zshE4I14sHjv3QoXASoXjx4xgMCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFI1Fc/Ql2jx+oJPgBVYq +ccgP0pQ8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQB4VVVabVp70myuYuZ3vltQIWqSUMhkaTzehMgGcHjMf9iLoZ/I +93KiFUSGnek5cRePyS9wcpp0fcBT3FvkjpUdCjVtdttJgZFhBxgTd8y26ImdDDMR +4+BUuhI5msvjL08f+Vkkpu1GQcGmyFVPFOy/UY8iefu+QyUuiBUnUuEDd49Hw0Fn +/kIPII6Vj82a2mWV/Q8e+rgN8dIRksRjKI03DEoP8lhPlsOkhdwU6Uz9Vu6NOB2Q +Ls1kbcxAc7cFSyRVJEhh12Sz9d0q/CQSTFsVJKOjSNQBQfVnLz1GwO/IieUEAr4C +jkTntH0r1LX5b/GwN4R887LvjAEdTbg1his7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgIDAIkHMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTA2MTc0 +MDIxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh +c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg +U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt +YXpvbiBSRFMgdXMtd2VzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDD2yzbbAl77OofTghDMEf624OvU0eS9O+lsdO0QlbfUfWa1Kd6 +0WkgjkLZGfSRxEHMCnrv4UPBSK/Qwn6FTjkDLgemhqBtAnplN4VsoDL+BkRX4Wwq +/dSQJE2b+0hm9w9UMVGFDEq1TMotGGTD2B71eh9HEKzKhGzqiNeGsiX4VV+LJzdH +uM23eGisNqmd4iJV0zcAZ+Gbh2zK6fqTOCvXtm7Idccv8vZZnyk1FiWl3NR4WAgK +AkvWTIoFU3Mt7dIXKKClVmvssG8WHCkd3Xcb4FHy/G756UZcq67gMMTX/9fOFM/v +l5C0+CHl33Yig1vIDZd+fXV1KZD84dEJfEvHAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBR+ap20kO/6A7pPxo3+ +T3CfqZpQWjAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAHCJky2tPjPttlDM/RIqExupBkNrnSYnOK4kr9xJ3sl8UF2DA +PAnYsjXp3rfcjN/k/FVOhxwzi3cXJF/2Tjj39Bm/OEfYTOJDNYtBwB0VVH4ffa/6 +tZl87jaIkrxJcreeeHqYMnIxeN0b/kliyA+a5L2Yb0VPjt9INq34QDc1v74FNZ17 +4z8nr1nzg4xsOWu0Dbjo966lm4nOYIGBRGOKEkHZRZ4mEiMgr3YLkv8gSmeitx57 +Z6dVemNtUic/LVo5Iqw4n3TBS0iF2C1Q1xT/s3h+0SXZlfOWttzSluDvoMv5PvCd +pFjNn+aXLAALoihL1MJSsxydtsLjOBro5eK0Vw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICOFAwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAxNzQ2 +MjFaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAzU72e6XbaJbi4HjJoRNjKxzUEuChKQIt7k3CWzNnmjc5 +8I1MjCpa2W1iw1BYVysXSNSsLOtUsfvBZxi/1uyMn5ZCaf9aeoA9UsSkFSZBjOCN +DpKPCmfV1zcEOvJz26+1m8WDg+8Oa60QV0ou2AU1tYcw98fOQjcAES0JXXB80P2s +3UfkNcnDz+l4k7j4SllhFPhH6BQ4lD2NiFAP4HwoG6FeJUn45EPjzrydxjq6v5Fc +cQ8rGuHADVXotDbEhaYhNjIrsPL+puhjWfhJjheEw8c4whRZNp6gJ/b6WEes/ZhZ +h32DwsDsZw0BfRDUMgUn8TdecNexHUw8vQWeC181hwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwW9bWgkWkr0U +lrOsq2kvIdrECDgwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAEugF0Gj7HVhX0ehPZoGRYRt3PBuI2YjfrrJRTZ9X5wc +9T8oHmw07mHmNy1qqWvooNJg09bDGfB0k5goC2emDiIiGfc/kvMLI7u+eQOoMKj6 +mkfCncyRN3ty08Po45vTLBFZGUvtQmjM6yKewc4sXiASSBmQUpsMbiHRCL72M5qV +obcJOjGcIdDTmV1BHdWT+XcjynsGjUqOvQWWhhLPrn4jWe6Xuxll75qlrpn3IrIx +CRBv/5r7qbcQJPOgwQsyK4kv9Ly8g7YT1/vYBlR3cRsYQjccw5ceWUj2DrMVWhJ4 +prf+E3Aa4vYmLLOUUvKnDQ1k3RGNu56V0tonsQbfsaM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgICEzUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAyMDUy +MjVaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h +em9uIFJEUyBjYS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAOxHqdcPSA2uBjsCP4DLSlqSoPuQ/X1kkJLusVRKiQE2zayB +viuCBt4VB9Qsh2rW3iYGM+usDjltGnI1iUWA5KHcvHszSMkWAOYWLiMNKTlg6LCp +XnE89tvj5dIH6U8WlDvXLdjB/h30gW9JEX7S8supsBSci2GxEzb5mRdKaDuuF/0O +qvz4YE04pua3iZ9QwmMFuTAOYzD1M72aOpj+7Ac+YLMM61qOtU+AU6MndnQkKoQi +qmUN2A9IFaqHFzRlSdXwKCKUA4otzmz+/N3vFwjb5F4DSsbsrMfjeHMo6o/nb6Nh +YDb0VJxxPee6TxSuN7CQJ2FxMlFUezcoXqwqXD0CAwEAAaNmMGQwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFDGGpon9WfIpsggE +CxHq8hZ7E2ESMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG +SIb3DQEBCwUAA4IBAQAvpeQYEGZvoTVLgV9rd2+StPYykMsmFjWQcyn3dBTZRXC2 +lKq7QhQczMAOhEaaN29ZprjQzsA2X/UauKzLR2Uyqc2qOeO9/YOl0H3qauo8C/W9 +r8xqPbOCDLEXlOQ19fidXyyEPHEq5WFp8j+fTh+s8WOx2M7IuC0ANEetIZURYhSp +xl9XOPRCJxOhj7JdelhpweX0BJDNHeUFi0ClnFOws8oKQ7sQEv66d5ddxqqZ3NVv +RbCvCtEutQMOUMIuaygDlMn1anSM8N7Wndx8G6+Uy67AnhjGx7jw/0YPPxopEj6x +JXP8j0sJbcT9K/9/fPVLNT25RvQ/93T2+IQL4Ca2 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICYpgwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExNzMx +NDhaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMk3YdSZ64iAYp6MyyKtYJtNzv7zFSnnNf6vv0FB4VnfITTMmOyZ +LXqKAT2ahZ00hXi34ewqJElgU6eUZT/QlzdIu359TEZyLVPwURflL6SWgdG01Q5X +O++7fSGcBRyIeuQWs9FJNIIqK8daF6qw0Rl5TXfu7P9dBc3zkgDXZm2DHmxGDD69 +7liQUiXzoE1q2Z9cA8+jirDioJxN9av8hQt12pskLQumhlArsMIhjhHRgF03HOh5 +tvi+RCfihVOxELyIRTRpTNiIwAqfZxxTWFTgfn+gijTmd0/1DseAe82aYic8JbuS +EMbrDduAWsqrnJ4GPzxHKLXX0JasCUcWyMECAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPLtsq1NrwJXO13C9eHt +sLY11AGwMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQAnWBKj5xV1A1mYd0kIgDdkjCwQkiKF5bjIbGkT3YEFFbXoJlSP +0lZZ/hDaOHI8wbLT44SzOvPEEmWF9EE7SJzkvSdQrUAWR9FwDLaU427ALI3ngNHy +lGJ2hse1fvSRNbmg8Sc9GBv8oqNIBPVuw+AJzHTacZ1OkyLZrz1c1QvwvwN2a+Jd +vH0V0YIhv66llKcYDMUQJAQi4+8nbRxXWv6Gq3pvrFoorzsnkr42V3JpbhnYiK+9 +nRKd4uWl62KRZjGkfMbmsqZpj2fdSWMY1UGyN1k+kDmCSWYdrTRDP0xjtIocwg+A +J116n4hV/5mbA0BaPiS2krtv17YAeHABZcvz +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgICV2YwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExOTM2 +MjBaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h +em9uIFJEUyBldS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMEx54X2pHVv86APA0RWqxxRNmdkhAyp2R1cFWumKQRofoFv +n+SPXdkpIINpMuEIGJANozdiEz7SPsrAf8WHyD93j/ZxrdQftRcIGH41xasetKGl +I67uans8d+pgJgBKGb/Z+B5m+UsIuEVekpvgpwKtmmaLFC/NCGuSsJoFsRqoa6Gh +m34W6yJoY87UatddCqLY4IIXaBFsgK9Q/wYzYLbnWM6ZZvhJ52VMtdhcdzeTHNW0 +5LGuXJOF7Ahb4JkEhoo6TS2c0NxB4l4MBfBPgti+O7WjR3FfZHpt18A6Zkq6A2u6 +D/oTSL6c9/3sAaFTFgMyL3wHb2YlW0BPiljZIqECAwEAAaNmMGQwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFOcAToAc6skWffJa +TnreaswAfrbcMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG +SIb3DQEBCwUAA4IBAQA1d0Whc1QtspK496mFWfFEQNegLh0a9GWYlJm+Htcj5Nxt +DAIGXb+8xrtOZFHmYP7VLCT5Zd2C+XytqseK/+s07iAr0/EPF+O2qcyQWMN5KhgE +cXw2SwuP9FPV3i+YAm11PBVeenrmzuk9NrdHQ7TxU4v7VGhcsd2C++0EisrmquWH +mgIfmVDGxphwoES52cY6t3fbnXmTkvENvR+h3rj+fUiSz0aSo+XZUGHPgvuEKM/W +CBD9Smc9CBoBgvy7BgHRgRUmwtABZHFUIEjHI5rIr7ZvYn+6A0O6sogRfvVYtWFc +qpyrW1YX8mD0VlJ8fGKM3G+aCOsiiPKDV/Uafrm+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgICGAcwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIxODE5 +NDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h +em9uIFJEUyBldS1ub3J0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCiIYnhe4UNBbdBb/nQxl5giM0XoVHWNrYV5nB0YukA98+TPn9v +Aoj1RGYmtryjhrf01Kuv8SWO+Eom95L3zquoTFcE2gmxCfk7bp6qJJ3eHOJB+QUO +XsNRh76fwDzEF1yTeZWH49oeL2xO13EAx4PbZuZpZBttBM5zAxgZkqu4uWQczFEs +JXfla7z2fvWmGcTagX10O5C18XaFroV0ubvSyIi75ue9ykg/nlFAeB7O0Wxae88e +uhiBEFAuLYdqWnsg3459NfV8Yi1GnaitTym6VI3tHKIFiUvkSiy0DAlAGV2iiyJE +q+DsVEO4/hSINJEtII4TMtysOsYPpINqeEzRAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRR0UpnbQyjnHChgmOc +hnlc0PogzTAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAKJD4xVzSf4zSGTBJrmamo86jl1NHQxXUApAZuBZEc8tqC6TI +T5CeoSr9CMuVC8grYyBjXblC4OsM5NMvmsrXl/u5C9dEwtBFjo8mm53rOOIm1fxl +I1oYB/9mtO9ANWjkykuLzWeBlqDT/i7ckaKwalhLODsRDO73vRhYNjsIUGloNsKe +pxw3dzHwAZx4upSdEVG4RGCZ1D0LJ4Gw40OfD69hfkDfRVVxKGrbEzqxXRvovmDc +tKLdYZO/6REoca36v4BlgIs1CbUXJGLSXUwtg7YXGLSVBJ/U0+22iGJmBSNcoyUN +cjPFD9JQEhDDIYYKSGzIYpvslvGc4T5ISXFiuQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICZIEwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIyMTMy +MzJaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALGiwqjiF7xIjT0Sx7zB3764K2T2a1DHnAxEOr+/EIftWKxWzT3u +PFwS2eEZcnKqSdRQ+vRzonLBeNLO4z8aLjQnNbkizZMBuXGm4BqRm1Kgq3nlLDQn +7YqdijOq54SpShvR/8zsO4sgMDMmHIYAJJOJqBdaus2smRt0NobIKc0liy7759KB +6kmQ47Gg+kfIwxrQA5zlvPLeQImxSoPi9LdbRoKvu7Iot7SOa+jGhVBh3VdqndJX +7tm/saj4NE375csmMETFLAOXjat7zViMRwVorX4V6AzEg1vkzxXpA9N7qywWIT5Y +fYaq5M8i6vvLg0CzrH9fHORtnkdjdu1y+0MCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFOhOx1yt3Z7mvGB9jBv +2ymdZwiOMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQBehqY36UGDvPVU9+vtaYGr38dBbp+LzkjZzHwKT1XJSSUc2wqM +hnCIQKilonrTIvP1vmkQi8qHPvDRtBZKqvz/AErW/ZwQdZzqYNFd+BmOXaeZWV0Q +oHtDzXmcwtP8aUQpxN0e1xkWb1E80qoy+0uuRqb/50b/R4Q5qqSfJhkn6z8nwB10 +7RjLtJPrK8igxdpr3tGUzfAOyiPrIDncY7UJaL84GFp7WWAkH0WG3H8Y8DRcRXOU +mqDxDLUP3rNuow3jnGxiUY+gGX5OqaZg4f4P6QzOSmeQYs6nLpH0PiN00+oS1BbD +bpWdZEttILPI+vAYkU4QuBKKDjJL6HbSd+cn +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgIDAIVCMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTEzMTcw +NjQxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh +c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg +U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt +YXpvbiBSRFMgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDE+T2xYjUbxOp+pv+gRA3FO24+1zCWgXTDF1DHrh1lsPg5k7ht +2KPYzNc+Vg4E+jgPiW0BQnA6jStX5EqVh8BU60zELlxMNvpg4KumniMCZ3krtMUC +au1NF9rM7HBh+O+DYMBLK5eSIVt6lZosOb7bCi3V6wMLA8YqWSWqabkxwN4w0vXI +8lu5uXXFRemHnlNf+yA/4YtN4uaAyd0ami9+klwdkZfkrDOaiy59haOeBGL8EB/c +dbJJlguHH5CpCscs3RKtOOjEonXnKXldxarFdkMzi+aIIjQ8GyUOSAXHtQHb3gZ4 +nS6Ey0CMlwkB8vUObZU9fnjKJcL5QCQqOfwvAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQUPuRHohPxx4VjykmH +6usGrLL1ETAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAUdR9Vb3y33Yj6X6KGtuthZ08SwjImVQPtknzpajNE5jOJAh8 +quvQnU9nlnMO85fVDU1Dz3lLHGJ/YG1pt1Cqq2QQ200JcWCvBRgdvH6MjHoDQpqZ +HvQ3vLgOGqCLNQKFuet9BdpsHzsctKvCVaeBqbGpeCtt3Hh/26tgx0rorPLw90A2 +V8QSkZJjlcKkLa58N5CMM8Xz8KLWg3MZeT4DmlUXVCukqK2RGuP2L+aME8dOxqNv +OnOz1zrL5mR2iJoDpk8+VE/eBDmJX40IJk6jBjWoxAO/RXq+vBozuF5YHN1ujE92 +tO8HItgTp37XT8bJBAiAnt5mxw+NLSqtxk2QdQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICY4kwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTMyMDEx +NDJaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1zb3V0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAr5u9OuLL/OF/fBNUX2kINJLzFl4DnmrhnLuSeSnBPgbb +qddjf5EFFJBfv7IYiIWEFPDbDG5hoBwgMup5bZDbas+ZTJTotnnxVJTQ6wlhTmns +eHECcg2pqGIKGrxZfbQhlj08/4nNAPvyYCTS0bEcmQ1emuDPyvJBYDDLDU6AbCB5 +6Z7YKFQPTiCBblvvNzchjLWF9IpkqiTsPHiEt21sAdABxj9ityStV3ja/W9BfgxH +wzABSTAQT6FbDwmQMo7dcFOPRX+hewQSic2Rn1XYjmNYzgEHisdUsH7eeXREAcTw +61TRvaLH8AiOWBnTEJXPAe6wYfrcSd1pD0MXpoB62wIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUytwMiomQOgX5 +Ichd+2lDWRUhkikwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBACf6lRDpfCD7BFRqiWM45hqIzffIaysmVfr+Jr+fBTjP +uYe/ba1omSrNGG23bOcT9LJ8hkQJ9d+FxUwYyICQNWOy6ejicm4z0C3VhphbTPqj +yjpt9nG56IAcV8BcRJh4o/2IfLNzC/dVuYJV8wj7XzwlvjysenwdrJCoLadkTr1h +eIdG6Le07sB9IxrGJL9e04afk37h7c8ESGSE4E+oS4JQEi3ATq8ne1B9DQ9SasXi +IRmhNAaISDzOPdyLXi9N9V9Lwe/DHcja7hgLGYx3UqfjhLhOKwp8HtoZORixAmOI +HfILgNmwyugAbuZoCazSKKBhQ0wgO0WZ66ZKTMG8Oho= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICUYkwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxODIx +MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyB1cy13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANCEZBZyu6yJQFZBJmSUZfSZd3Ui2gitczMKC4FLr0QzkbxY+cLa +uVONIOrPt4Rwi+3h/UdnUg917xao3S53XDf1TDMFEYp4U8EFPXqCn/GXBIWlU86P +PvBN+gzw3nS+aco7WXb+woTouvFVkk8FGU7J532llW8o/9ydQyDIMtdIkKTuMfho +OiNHSaNc+QXQ32TgvM9A/6q7ksUoNXGCP8hDOkSZ/YOLiI5TcdLh/aWj00ziL5bj +pvytiMZkilnc9dLY9QhRNr0vGqL0xjmWdoEXz9/OwjmCihHqJq+20MJPsvFm7D6a +2NKybR9U+ddrjb8/iyLOjURUZnj5O+2+OPcCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEBxMBdv81xuzqcK5TVu +pHj+Aor8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQBZkfiVqGoJjBI37aTlLOSjLcjI75L5wBrwO39q+B4cwcmpj58P +3sivv+jhYfAGEbQnGRzjuFoyPzWnZ1DesRExX+wrmHsLLQbF2kVjLZhEJMHF9eB7 +GZlTPdTzHErcnuXkwA/OqyXMpj9aghcQFuhCNguEfnROY9sAoK2PTfnTz9NJHL+Q +UpDLEJEUfc0GZMVWYhahc0x38ZnSY2SKacIPECQrTI0KpqZv/P+ijCEcMD9xmYEb +jL4en+XKS1uJpw5fIU5Sj0MxhdGstH6S84iAE5J3GM3XHklGSFwwqPYvuTXvANH6 +uboynxRgSae59jIlAK6Jrr6GWMwQRbgcaAlW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICEkYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxOTUz +NDdaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1zb3V0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAufodI2Flker8q7PXZG0P0vmFSlhQDw907A6eJuF/WeMo +GHnll3b4S6nC3oRS3nGeRMHbyU2KKXDwXNb3Mheu+ox+n5eb/BJ17eoj9HbQR1cd +gEkIciiAltf8gpMMQH4anP7TD+HNFlZnP7ii3geEJB2GGXSxgSWvUzH4etL67Zmn +TpGDWQMB0T8lK2ziLCMF4XAC/8xDELN/buHCNuhDpxpPebhct0T+f6Arzsiswt2j +7OeNeLLZwIZvVwAKF7zUFjC6m7/VmTQC8nidVY559D6l0UhhU0Co/txgq3HVsMOH +PbxmQUwJEKAzQXoIi+4uZzHFZrvov/nDTNJUhC6DqwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwaZpaCme+EiV +M5gcjeHZSTgOn4owHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAAR6a2meCZuXO2TF9bGqKGtZmaah4pH2ETcEVUjkvXVz +sl+ZKbYjrun+VkcMGGKLUjS812e7eDF726ptoku9/PZZIxlJB0isC/0OyixI8N4M +NsEyvp52XN9QundTjkl362bomPnHAApeU0mRbMDRR2JdT70u6yAzGLGsUwMkoNnw +1VR4XKhXHYGWo7KMvFrZ1KcjWhubxLHxZWXRulPVtGmyWg/MvE6KF+2XMLhojhUL ++9jB3Fpn53s6KMx5tVq1x8PukHmowcZuAF8k+W4gk8Y68wIwynrdZrKRyRv6CVtR +FZ8DeJgoNZT3y/GT254VqMxxfuy2Ccb/RInd16tEvVk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICOYIwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTcyMDA1 +MjlaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMyAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA4dMak8W+XW8y/2F6nRiytFiA4XLwePadqWebGtlIgyCS +kbug8Jv5w7nlMkuxOxoUeD4WhI6A9EkAn3r0REM/2f0aYnd2KPxeqS2MrtdxxHw1 +xoOxk2x0piNSlOz6yog1idsKR5Wurf94fvM9FdTrMYPPrDabbGqiBMsZZmoHLvA3 +Z+57HEV2tU0Ei3vWeGIqnNjIekS+E06KhASxrkNU5vi611UsnYZlSi0VtJsH4UGV +LhnHl53aZL0YFO5mn/fzuNG/51qgk/6EFMMhaWInXX49Dia9FnnuWXwVwi6uX1Wn +7kjoHi5VtmC8ZlGEHroxX2DxEr6bhJTEpcLMnoQMqwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUsUI5Cb3SWB8+ +gv1YLN/ABPMdxSAwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAJAF3E9PM1uzVL8YNdzb6fwJrxxqI2shvaMVmC1mXS+w +G0zh4v2hBZOf91l1EO0rwFD7+fxoI6hzQfMxIczh875T6vUXePKVOCOKI5wCrDad +zQbVqbFbdhsBjF4aUilOdtw2qjjs9JwPuB0VXN4/jY7m21oKEOcnpe36+7OiSPjN +xngYewCXKrSRqoj3mw+0w/+exYj3Wsush7uFssX18av78G+ehKPIVDXptOCP/N7W +8iKVNeQ2QGTnu2fzWsGUSvMGyM7yqT+h1ILaT//yQS8er511aHMLc142bD4D9VSy +DgactwPDTShK/PXqhvNey9v/sKXm4XatZvwcc8KYlW4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICcEUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNjU2 +MjBaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAndtkldmHtk4TVQAyqhAvtEHSMb6pLhyKrIFved1WO3S7 ++I+bWwv9b2W/ljJxLq9kdT43bhvzonNtI4a1LAohS6bqyirmk8sFfsWT3akb+4Sx +1sjc8Ovc9eqIWJCrUiSvv7+cS7ZTA9AgM1PxvHcsqrcUXiK3Jd/Dax9jdZE1e15s +BEhb2OEPE+tClFZ+soj8h8Pl2Clo5OAppEzYI4LmFKtp1X/BOf62k4jviXuCSst3 +UnRJzE/CXtjmN6oZySVWSe0rQYuyqRl6//9nK40cfGKyxVnimB8XrrcxUN743Vud +QQVU0Esm8OVTX013mXWQXJHP2c0aKkog8LOga0vobQIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQULmoOS1mFSjj+ +snUPx4DgS3SkLFYwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAAkVL2P1M2/G9GM3DANVAqYOwmX0Xk58YBHQu6iiQg4j +b4Ky/qsZIsgT7YBsZA4AOcPKQFgGTWhe9pvhmXqoN3RYltN8Vn7TbUm/ZVDoMsrM +gwv0+TKxW1/u7s8cXYfHPiTzVSJuOogHx99kBW6b2f99GbP7O1Sv3sLq4j6lVvBX +Fiacf5LAWC925nvlTzLlBgIc3O9xDtFeAGtZcEtxZJ4fnGXiqEnN4539+nqzIyYq +nvlgCzyvcfRAxwltrJHuuRu6Maw5AGcd2Y0saMhqOVq9KYKFKuD/927BTrbd2JVf +2sGWyuPZPCk3gq+5pCjbD0c6DkhcMGI6WwxvM5V/zSM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICJDQwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNzAz +MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTMgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL9bL7KE0n02DLVtlZ2PL+g/BuHpMYFq2JnE2RgompGurDIZdjmh +1pxfL3nT+QIVMubuAOy8InRfkRxfpxyjKYdfLJTPJG+jDVL+wDcPpACFVqoV7Prg +pVYEV0lc5aoYw4bSeYFhdzgim6F8iyjoPnObjll9mo4XsHzSoqJLCd0QC+VG9Fw2 +q+GDRZrLRmVM2oNGDRbGpGIFg77aRxRapFZa8SnUgs2AqzuzKiprVH5i0S0M6dWr +i+kk5epmTtkiDHceX+dP/0R1NcnkCPoQ9TglyXyPdUdTPPRfKCq12dftqll+u4mV +ARdN6WFjovxax8EAP2OAUTi1afY+1JFMj+sCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLfhrbrO5exkCVgxW0x3 +Y2mAi8lNMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQAigQ5VBNGyw+OZFXwxeJEAUYaXVoP/qrhTOJ6mCE2DXUVEoJeV +SxScy/TlFA9tJXqmit8JH8VQ/xDL4ubBfeMFAIAo4WzNWDVoeVMqphVEcDWBHsI1 +AETWzfsapRS9yQekOMmxg63d/nV8xewIl8aNVTHdHYXMqhhik47VrmaVEok1UQb3 +O971RadLXIEbVd9tjY5bMEHm89JsZDnDEw1hQXBb67Elu64OOxoKaHBgUH8AZn/2 +zFsL1ynNUjOhCSAA15pgd1vjwc0YsBbAEBPcHBWYBEyME6NLNarjOzBl4FMtATSF +wWCKRGkvqN8oxYhwR2jf2rR5Mu4DWkK5Q8Ep +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICJVUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTkxODE2 +NTNaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyB1cy1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAM3i/k2u6cqbMdcISGRvh+m+L0yaSIoOXjtpNEoIftAipTUYoMhL +InXGlQBVA4shkekxp1N7HXe1Y/iMaPEyb3n+16pf3vdjKl7kaSkIhjdUz3oVUEYt +i8Z/XeJJ9H2aEGuiZh3kHixQcZczn8cg3dA9aeeyLSEnTkl/npzLf//669Ammyhs +XcAo58yvT0D4E0D/EEHf2N7HRX7j/TlyWvw/39SW0usiCrHPKDLxByLojxLdHzso +QIp/S04m+eWn6rmD+uUiRteN1hI5ncQiA3wo4G37mHnUEKo6TtTUh+sd/ku6a8HK +glMBcgqudDI90s1OpuIAWmuWpY//8xEG2YECAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPqhoWZcrVY9mU7tuemR +RBnQIj1jMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQB6zOLZ+YINEs72heHIWlPZ8c6WY8MDU+Be5w1M+BK2kpcVhCUK +PJO4nMXpgamEX8DIiaO7emsunwJzMSvavSPRnxXXTKIc0i/g1EbiDjnYX9d85DkC +E1LaAUCmCZBVi9fIe0H2r9whIh4uLWZA41oMnJx/MOmo3XyMfQoWcqaSFlMqfZM4 +0rNoB/tdHLNuV4eIdaw2mlHxdWDtF4oH+HFm+2cVBUVC1jXKrFv/euRVtsTT+A6i +h2XBHKxQ1Y4HgAn0jACP2QSPEmuoQEIa57bEKEcZsBR8SDY6ZdTd2HLRIApcCOSF +MRM8CKLeF658I0XgF8D5EsYoKPsA+74Z+jDH +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJAM2ZN/+nPi27MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBhZi1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkxMDI4MTgwNTU4WhcNMjQxMDI2MTgwNTU4WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgYWYtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR2351uPMZaJk2gMGT+1sk8HE9MQh2rc +/sCnbxGn2p1c7Oi9aBbd/GiFijeJb2BXvHU+TOq3d3Jjqepq8tapXVt4ojbTJNyC +J5E7r7KjTktKdLxtBE1MK25aY+IRJjtdU6vG3KiPKUT1naO3xs3yt0F76WVuFivd +9OHv2a+KHvPkRUWIxpmAHuMY9SIIMmEZtVE7YZGx5ah0iO4JzItHcbVR0y0PBH55 +arpFBddpIVHCacp1FUPxSEWkOpI7q0AaU4xfX0fe1BV5HZYRKpBOIp1TtZWvJD+X +jGUtL1BEsT5vN5g9MkqdtYrC+3SNpAk4VtpvJrdjraI/hhvfeXNnAwIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUEEi/ +WWMcBJsoGXg+EZwkQ0MscZQwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0Ms +cZQwDQYJKoZIhvcNAQELBQADggEBAGDZ5js5Pc/gC58LJrwMPXFhJDBS8QuDm23C +FFUdlqucskwOS3907ErK1ZkmVJCIqFLArHqskFXMAkRZ2PNR7RjWLqBs+0znG5yH +hRKb4DXzhUFQ18UBRcvT6V6zN97HTRsEEaNhM/7k8YLe7P8vfNZ28VIoJIGGgv9D +wQBBvkxQ71oOmAG0AwaGD0ORGUfbYry9Dz4a4IcUsZyRWRMADixgrFv6VuETp26s +/+z+iqNaGWlELBKh3iQCT6Y/1UnkPLO42bxrCSyOvshdkYN58Q2gMTE1SVTqyo8G +Lw8lLAz9bnvUSgHzB3jRrSx6ggF/WRMRYlR++y6LXP4SAsSAaC0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw +MjgxODA2NTNaFw0yNDEwMjgxODA2NTNaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBhZi1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAvtV1OqmFa8zCVQSKOvPUJERLVFtd4rZmDpImc5rIoeBk7w/P +9lcKUJjO8R/w1a2lJXx3oQ81tiY0Piw6TpT62YWVRMWrOw8+Vxq1dNaDSFp9I8d0 +UHillSSbOk6FOrPDp+R6AwbGFqUDebbN5LFFoDKbhNmH1BVS0a6YNKpGigLRqhka +cClPslWtPqtjbaP3Jbxl26zWzLo7OtZl98dR225pq8aApNBwmtgA7Gh60HK/cX0t +32W94n8D+GKSg6R4MKredVFqRTi9hCCNUu0sxYPoELuM+mHiqB5NPjtm92EzCWs+ ++vgWhMc6GxG+82QSWx1Vj8sgLqtE/vLrWddf5QIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuLB4gYVJrSKJj/Gz +pqc6yeA+RcAwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0MscZQwDQYJKoZI +hvcNAQELBQADggEBABauYOZxUhe9/RhzGJ8MsWCz8eKcyDVd4FCnY6Qh+9wcmYNT +LtnD88LACtJKb/b81qYzcB0Em6+zVJ3Z9jznfr6buItE6es9wAoja22Xgv44BTHL +rimbgMwpTt3uEMXDffaS0Ww6YWb3pSE0XYI2ISMWz+xRERRf+QqktSaL39zuiaW5 +tfZMre+YhohRa/F0ZQl3RCd6yFcLx4UoSPqQsUl97WhYzwAxZZfwvLJXOc4ATt3u +VlCUylNDkaZztDJc/yN5XQoK9W5nOt2cLu513MGYKbuarQr8f+gYU8S+qOyuSRSP +NRITzwCRVnsJE+2JmcRInn/NcanB7uOGqTvJ9+c= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJAJYM4LxvTZA6MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBldS1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkxMDMwMjAyMDM2WhcNMjQxMDI4MjAyMDM2WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgZXUtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqM921jXCXeqpRNCS9CBPOe5N7gMaEt+D +s5uR3riZbqzRlHGiF1jZihkXfHAIQewDwy+Yz+Oec1aEZCQMhUHxZJPusuX0cJfj +b+UluFqHIijL2TfXJ3D0PVLLoNTQJZ8+GAPECyojAaNuoHbdVqxhOcznMsXIXVFq +yVLKDGvyKkJjai/iSPDrQMXufg3kWt0ISjNLvsG5IFXgP4gttsM8i0yvRd4QcHoo +DjvH7V3cS+CQqW5SnDrGnHToB0RLskE1ET+oNOfeN9PWOxQprMOX/zmJhnJQlTqD +QP7jcf7SddxrKFjuziFiouskJJyNDsMjt1Lf60+oHZhed2ogTeifGwIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUFBAF +cgJe/BBuZiGeZ8STfpkgRYQwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkg +RYQwDQYJKoZIhvcNAQELBQADggEBAKAYUtlvDuX2UpZW9i1QgsjFuy/ErbW0dLHU +e/IcFtju2z6RLZ+uF+5A8Kme7IKG1hgt8s+w9TRVQS/7ukQzoK3TaN6XKXRosjtc +o9Rm4gYWM8bmglzY1TPNaiI4HC7546hSwJhubjN0bXCuj/0sHD6w2DkiGuwKNAef +yTu5vZhPkeNyXLykxkzz7bNp2/PtMBnzIp+WpS7uUDmWyScGPohKMq5PqvL59z+L +ZI3CYeMZrJ5VpXUg3fNNIz/83N3G0sk7wr0ohs/kHTP7xPOYB0zD7Ku4HA0Q9Swf +WX0qr6UQgTPMjfYDLffI7aEId0gxKw1eGYc6Cq5JAZ3ipi/cBFc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIGV1LXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw +MzAyMDIxMzBaFw0yNDEwMzAyMDIxMzBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBldS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAtEyjYcajx6xImJn8Vz1zjdmL4ANPgQXwF7+tF7xccmNAZETb +bzb3I9i5fZlmrRaVznX+9biXVaGxYzIUIR3huQ3Q283KsDYnVuGa3mk690vhvJbB +QIPgKa5mVwJppnuJm78KqaSpi0vxyCPe3h8h6LLFawVyWrYNZ4okli1/U582eef8 +RzJp/Ear3KgHOLIiCdPDF0rjOdCG1MOlDLixVnPn9IYOciqO+VivXBg+jtfc5J+L +AaPm0/Yx4uELt1tkbWkm4BvTU/gBOODnYziITZM0l6Fgwvbwgq5duAtKW+h031lC +37rEvrclqcp4wrsUYcLAWX79ZyKIlRxcAdvEhQIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU7zPyc0azQxnBCe7D +b9KAadH1QSEwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkgRYQwDQYJKoZI +hvcNAQELBQADggEBAFGaNiYxg7yC/xauXPlaqLCtwbm2dKyK9nIFbF/7be8mk7Q3 +MOA0of1vGHPLVQLr6bJJpD9MAbUcm4cPAwWaxwcNpxOjYOFDaq10PCK4eRAxZWwF +NJRIRmGsl8NEsMNTMCy8X+Kyw5EzH4vWFl5Uf2bGKOeFg0zt43jWQVOX6C+aL3Cd +pRS5MhmYpxMG8irrNOxf4NVFE2zpJOCm3bn0STLhkDcV/ww4zMzObTJhiIb5wSWn +EXKKWhUXuRt7A2y1KJtXpTbSRHQxE++69Go1tWhXtRiULCJtf7wF2Ksm0RR/AdXT +1uR1vKyH5KBJPX3ppYkQDukoHTFR0CpB+G84NLo= +-----END CERTIFICATE----- diff --git a/src/test/java/runner/configuration/AccountServiceTestConfiguration.java b/src/test/java/runner/configuration/AccountServiceTestConfiguration.java new file mode 100644 index 000000000..fe73e41e9 --- /dev/null +++ b/src/test/java/runner/configuration/AccountServiceTestConfiguration.java @@ -0,0 +1,19 @@ +package runner.configuration; + +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import runner.services.AccountServices; + +@Profile("test") +@Configuration + +public class AccountServiceTestConfiguration { + @Bean + @Primary + public AccountServices accountServices() { + return Mockito.mock(AccountServices.class); + } +} diff --git a/src/test/java/runner/configuration/CustomerServiceTestConfiguration.java b/src/test/java/runner/configuration/CustomerServiceTestConfiguration.java new file mode 100644 index 000000000..37742ce16 --- /dev/null +++ b/src/test/java/runner/configuration/CustomerServiceTestConfiguration.java @@ -0,0 +1,19 @@ +package runner.configuration; + +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import runner.services.CustomerServices; + +@Profile("test") +@Configuration +public class CustomerServiceTestConfiguration { + @Bean + @Primary + public CustomerServices customerServices() { + return Mockito.mock(CustomerServices.class); + } + +} diff --git a/src/test/java/runner/controllers/AccountControllerTest.java b/src/test/java/runner/controllers/AccountControllerTest.java new file mode 100644 index 000000000..ff980157d --- /dev/null +++ b/src/test/java/runner/controllers/AccountControllerTest.java @@ -0,0 +1,160 @@ +package runner.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import runner.AppRunner; +import runner.entities.Account; +import runner.entities.Transaction; +import runner.enums.AccountType; +import runner.services.AccountServices; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +//@WebMvcTest(controllers = CustomerController.class) +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@AutoConfigureMockMvc +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) + +public class AccountControllerTest { + @Autowired + MockMvc mockMvc; + @MockBean + AccountServices accountServices; + + Account account1; + Account account2; + Transaction transaction; + List transactionSet; + String jsonString; + ObjectMapper objectMapper = new ObjectMapper(); + + @Before + public void setUp() throws JSONException { + transaction = new Transaction("Withdrawal to CHECKING XXXXXXXX0987",10.00, 100.00, LocalDate.now()); + transactionSet = new ArrayList(); + transactionSet.add(transaction); + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", transactionSet); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", transactionSet); + + //payload for transfer,withdraw,deposit <--structure to micmic production but not necessarily used here in testing + JSONObject depositPayload = new JSONObject(); + JSONObject accountPayload = new JSONObject(); + accountPayload.put("accountNumber","09865"); + accountPayload.put("routingNumber","11111"); + JSONArray accounts = new JSONArray(); + accounts.put(0,accountPayload); + depositPayload.put("transactionAmount","10.00"); + depositPayload.put("accounts",accounts); + jsonString = depositPayload.toString(); + } + + @WithMockUser + @Test + public void readAllAccountsTest() throws Exception { + Set accountSet = new HashSet<>(); + accountSet.add(account1); + accountSet.add(account2); + Mockito.when(accountServices.getAllAccounts(any())).thenReturn(accountSet); + + mockMvc.perform(get("/myaccount")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$",hasSize(2))); + } + + @WithMockUser + @Test + public void readAccountByUrlTest() throws Exception { + Mockito.when(accountServices.getAccountByEncryptedUrl(any())).thenReturn(account1); + + mockMvc.perform(get("/myaccount/{encryptedUrl}","12345")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.balance", is(account1.getBalance()))) + .andExpect(jsonPath("$.transactions",hasSize(1))); + } + + @WithMockUser + @Test + public void createAccountTest(){ + } + +// @WithMockUser +// @Test +// public void deleteAccountTest() throws Exception { +// Mockito.when(accountServices.removeAccount(any())).thenReturn(true); +// +// mockMvc.perform(delete("/myaccount/{encryptedUrl}/delete","12345")) +// .andExpect(status().isOk()); +// } + + @WithMockUser + @Test + public void updateAccountDepositTest() throws Exception { + + Mockito.when(accountServices.deposit(any(),any())).thenReturn(account1); + + mockMvc.perform(put("/myaccount/{encryptedUrl}/deposit","12345") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonString)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.balance", is(account1.getBalance()))) + .andExpect(jsonPath("$.transactions", hasSize(1))); + } + + @WithMockUser + @Test + public void updateAccountWithdrawTest() throws Exception { + Mockito.when(accountServices.withdraw(any(),any())).thenReturn(account1); + + mockMvc.perform(put("/myaccount/{encryptedUrl}/withdraw","12345") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonString)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.balance", is(account1.getBalance()))) + .andExpect(jsonPath("$.transactions", hasSize(1))); + } + + @WithMockUser + @Test + public void updateAccountTransferTest() throws Exception { + Mockito.when(accountServices.withdraw(any(),any())).thenReturn(account1); + + mockMvc.perform(put("/myaccount/{encryptedUrl}/transfer","12345") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonString)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.balance", is(account1.getBalance()))) + .andExpect(jsonPath("$.transactions", hasSize(1))); + } + +} diff --git a/src/test/java/runner/controllers/CustomerControllerTest.java b/src/test/java/runner/controllers/CustomerControllerTest.java new file mode 100644 index 000000000..1a15878c2 --- /dev/null +++ b/src/test/java/runner/controllers/CustomerControllerTest.java @@ -0,0 +1,214 @@ +package runner.controllers; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.hamcrest.Matchers; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import runner.AppRunner; +import runner.entities.*; +import runner.enums.AccountType; +import runner.services.CustomerServices; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@AutoConfigureMockMvc +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) + +public class CustomerControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + private CustomerServices customerServices; + ObjectMapper objectMapper = new ObjectMapper(); + Account account1; + Account account2; + Account account3; + Set testAccounts; + Login login; + Customer customer; + Address address,addressUpdate; + String jsonString; + @Before + public void setup() throws JSONException { + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + account3 = new Account(2L,"56789", AccountType.SAVINGS,100.00,"qwerty", new ArrayList()); + testAccounts = new HashSet(); + testAccounts.add(account1); + testAccounts.add(account2); + login = new Login(1L,"user","password",customer); //customer would be null here due to order of code; + customer = new Customer(1L,"John","Doe",address,login,testAccounts); + address = new Address(1L,"Address Line 1", "Address Line 2", "Bear","DE","19701"); + addressUpdate = new Address(1L,"Address Line Updated", "Address Line Updated", "Bear","DE","19701"); + + //payload + JSONObject payload = new JSONObject(); + payload.put("key","value"); + jsonString = payload.toString(); + } + + @WithMockUser + @Test + public void createCustomerTest() { + + try { + String jsonRequest = objectMapper.writeValueAsString(customer); + + Mockito.when(customerServices.createCustomer(any())).thenReturn(customer); + + mockMvc.perform(post("/openaccount") + .content(jsonRequest) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.id", is(1))) + .andReturn(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + @WithMockUser + @Test + public void readCustomer() { + Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(customer); + try { + mockMvc.perform(get("/myaccount/profile")) + .andExpect(jsonPath("$.phoneNumber",is(customer.getPhoneNumber()))) + .andExpect(jsonPath("$.email",is(customer.getEmail()))) + .andExpect(jsonPath("$.address.firstLine",is(customer.getAddress().getFirstLine()))) + .andExpect(status().isOk()); + } catch (Exception e) { + e.printStackTrace(); + } + } + +// @WithMockUser +// @Test +// public void readCustomerNullTest() { +// Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(null); +// try { +// mockMvc.perform(get("/myaccount/profile")) +// .andExpect(status().isNotFound()) +// .andReturn(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + + @WithMockUser + @Test + public void updateCustomerPhone() throws Exception { + //String jsonRequest = objectMapper.writeValueAsString("548-458-4584"); + Mockito.when(customerServices.updateCustomerPhoneNumber(any(),any())).thenReturn(customer); + // Mockito.when(customer.get(any()).thenReturn("512-444-4587"); + mockMvc.perform(put("/myaccount/profile/phone") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonString)) + .andExpect(jsonPath("$.phoneNumber",is(customer.getPhoneNumber()))) + .andExpect(status().isOk()); + } + + @WithMockUser + @Test + public void updateCustomerEmail() throws Exception { + Mockito.when(customerServices.updateCustomerEmail(any(),any())).thenReturn(customer); + mockMvc.perform(put("/myaccount/profile/email") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonString)) + .andExpect(jsonPath("$.email",is(customer.getEmail()))) + .andExpect(status().isOk()); + } + + @WithMockUser + @Test + public void updateCustomerAddress() throws Exception { + String jsonRequest = objectMapper.writeValueAsString(addressUpdate); + Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(customer); + Mockito.when(customerServices.updateCustomerAddress(any(),any())).thenReturn(customer); + mockMvc.perform(put("/myaccount/profile/address") + .content(jsonRequest) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + +// @WithMockUser +// @Test +// public void updateCustomerAddressCustomerNotFound() throws Exception { +// String jsonRequest = objectMapper.writeValueAsString(addressUpdate); +// Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(null); +// Mockito.when(customerServices.updateCustomerAddress(any(),any())).thenReturn(null); +// mockMvc.perform(put("/myaccount/profile/address") +// .content(jsonRequest) +// .contentType(MediaType.APPLICATION_JSON) +// .accept(MediaType.APPLICATION_JSON)) +// .andExpect(status().isNotFound()); +// } + + @WithMockUser + @Test + public void updateCustomerDeleteTest() throws Exception { + Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(customer); + Mockito.when(customerServices.deleteCustomer(any())).thenReturn(0); + mockMvc.perform(delete("/myaccount/profile/delete")) + .andExpect(status().isOk()); + } + + @WithMockUser + @Test + public void updateCustomerDeleteTestAccountWithBalanceFound() throws Exception { + Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(customer); + Mockito.when(customerServices.deleteCustomer(any())).thenReturn(2); + mockMvc.perform(delete("/myaccount/profile/delete")) + .andExpect(status().isForbidden()); + } + + @WithMockUser + @Test + public void updateCustomerDeleteCustomerGood() throws Exception { + Mockito.when(customerServices.readCustomerByLogin(any())).thenReturn(customer); + Mockito.when(customerServices.deleteCustomer(any())).thenReturn(1); + mockMvc.perform(delete("/myaccount/profile/delete")) + .andExpect(status().isNotFound()); + } + + @WithMockUser + @Test + public void DeleteAccountTestBad() throws Exception { + Mockito.when(customerServices.removeAccount(any(),any())).thenReturn(customer); + mockMvc.perform(delete("/myaccount/{encryptedUrl}/delete","12345")) + .andExpect(status().isOk()); + } +} diff --git a/src/test/java/runner/entities/AccountEntityTest.java b/src/test/java/runner/entities/AccountEntityTest.java new file mode 100644 index 000000000..e08d69913 --- /dev/null +++ b/src/test/java/runner/entities/AccountEntityTest.java @@ -0,0 +1,68 @@ +package runner.entities; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import runner.AppRunner; +import runner.enums.AccountType; + +import javax.persistence.Entity; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) +public class AccountEntityTest { + + Account account1; + Account account2; + Account account3; + Set testAccounts; + Login login; + Customer customer; + Transaction transaction; + Set transactionAccount; + Transaction withdrawalTransaction; + Transaction depositTransaction; + ArrayList myTransactionList; + Address address; + @Before + public void setup(){ + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + account3 = new Account(2L,"56789", AccountType.SAVINGS,100.00,"qwerty", new ArrayList()); + testAccounts = new HashSet(); + testAccounts.add(account1); + testAccounts.add(account2); + login = new Login(1L,"user","password",customer); //customer would be null here due to order of code; + address = new Address(1L,"Address Line 1", "Address Line 2", "Bear","DE","19701"); + customer = new Customer(1L,"John","Doe",address,login,testAccounts); + } + + @Test + public void testClassSignatureAnnotations() { + Assert.assertTrue(Customer.class.isAnnotationPresent(Entity.class)); + } + @Test + public void testCreateJson() throws JsonProcessingException { + ObjectMapper objectMapper= new ObjectMapper(); + // Customer expectedCustomer = new Customer( 1L, "Radha" , "Ramnik","Patel","234324"); + String json = objectMapper.writeValueAsString(account1); + Account actualAccount=objectMapper.readValue(json, Account.class); + Assert.assertEquals(account1.getId(), actualAccount.getId()); + + } + +} + diff --git a/src/test/java/runner/entities/CustomerEntityTest.java b/src/test/java/runner/entities/CustomerEntityTest.java new file mode 100644 index 000000000..49aa39803 --- /dev/null +++ b/src/test/java/runner/entities/CustomerEntityTest.java @@ -0,0 +1,214 @@ +package runner.entities; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import runner.AppRunner; +import runner.enums.AccountType; + +import javax.persistence.Entity; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) +public class CustomerEntityTest { + + Account account1; + Account account2; + Account account3; + Set testAccounts; + Login login; + Customer customer; + Transaction transaction; + Set transactionAccount; + Transaction withdrawalTransaction; + Transaction depositTransaction; + ArrayList myTransactionList; + Address address; + @Before + public void setup(){ + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + account3 = new Account(2L,"56789", AccountType.SAVINGS,100.00,"qwerty", new ArrayList()); + testAccounts = new HashSet(); + testAccounts.add(account1); + testAccounts.add(account2); + login = new Login(1L,"user","password",customer); //customer would be null here due to order of code; + address = new Address(1L,"Address Line 1", "Address Line 2", "Bear","DE","19701"); + customer = new Customer(1L,"John","Doe",address,login,testAccounts); + } + + @Test + public void testClassSignatureAnnotations() { + Assert.assertTrue(Customer.class.isAnnotationPresent(Entity.class)); + } + @Test + public void testCreateJson() throws JsonProcessingException { + ObjectMapper objectMapper= new ObjectMapper(); + // Customer expectedCustomer = new Customer( 1L, "Radha" , "Ramnik","Patel","234324"); + String json = objectMapper.writeValueAsString(customer); + Customer actualCustomer =objectMapper.readValue(json, Customer.class); + Assert.assertEquals(customer.getId(), actualCustomer.getId()); + + } + +// @Before +// public void startUp() +// { +// user= new UserBuilder().createUser(); +// } +// +// @Test +// public void setAndGetIdTest() +// { +// //Given +// Long expected =1L; +// //When +// user.setId(expected); +// //Then +// Long actual = user.getId(); +// Assert.assertEquals(expected,actual); +// } +// +// @Test +// public void setAndGetFirstNameTest() +// { +// //Given +// String expected = "FirstName"; +// //When +// user.setFirstName(expected); +// //Then +// String actual = user.getFirstName(); +// Assert.assertEquals(expected,actual); +// } +// +// +// @Test +// public void setAndGetLastNameTest() +// { +// //Given +// String expected = "LastName"; +// //When +// user.setLastName(expected); +// //Then +// String actual = user.getLastName(); +// Assert.assertEquals(expected,actual); +// } +// +// @Test +// public void setAndGetMiddleNameTest() +// { +// //Given +// String expected = "MiddleName"; +// //When +// user.setMiddleName(expected); +// //Then +// String actual = user.getMiddleName(); +// Assert.assertEquals(expected,actual); +// } +// @Test +// public void setAndGetDOBTest() +// { +// //Given +// LocalDate expected = LocalDate.now(); +// //When +// user.setDateOfBirth(expected); +// //Then +// LocalDate actual = user.getDateOfBirth(); +// Assert.assertEquals(expected,actual); +// } +// @Test +// public void setAndGetSSNTest() +// { +// //Given +// String expected ="234-333-444"; +// //When +// user.setSocialSecurity(expected); +// //Then +// String actual = user.getSocialSecurity(); +// Assert.assertEquals(expected,actual); +// } +// @Test +// public void setAndGetPhoneNumberTest() +// { +// //Given +// String expected ="234-333-4544"; +// //When +// user.setPhoneNumber(expected); +// //Then +// String actual = user.getPhoneNumber(); +// Assert.assertEquals(expected,actual); +// } +// @Test +// public void setAndGetEmailTest() +// { +// //Given +// String expected ="test@gmail.com"; +// //When +// user.setEmail(expected); +// //Then +// String actual = user.getEmail(); +// Assert.assertEquals(expected,actual); +// } +// +// @Test +// public void setAndGetLoginTest() +// { +// //Given +// login = new Login(); +// login.setId(1l);; +// login.setPassword("test"); +// login.setUsername("user"); +// +// //When +// user.setLogin(login); +// //Then +// Login actual = user.getLogin(); +// Assert.assertEquals(login,actual); +// } +// +// @Test +// public void setAndGetAccountTest() +// { +// //Given +// account1 = new Account(); +// account1.setId(1L); +// account1.setAccountType(AccountType.INVESTMENT); +// expectedAccount = new HashSet() ; +// expectedAccount.add(account1); +// //When +// user.setAccounts(expectedAccount); +// //Then +// Set actualAccount = user.getAccounts(); +// Assert.assertEquals(expectedAccount.size(),actualAccount.size()); +// } +// +//@Test +// public void setAndGetAddressTest() +// { +// //Given +// expectedAddress = new Address(); +// expectedAddress.setFirstLine("First Line of Address"); +// expectedAddress.setSecondLIne("Second Line of Address"); +// +// //When +// customer.setAddress(expectedAddress); +// //Then +// Address actualAddress = customer.getAddress(); +// Assert.assertEquals(expectedAddress,actualAddress); +// } +} diff --git a/src/test/java/runner/security/JwtTest.java b/src/test/java/runner/security/JwtTest.java new file mode 100644 index 000000000..84128f562 --- /dev/null +++ b/src/test/java/runner/security/JwtTest.java @@ -0,0 +1,95 @@ +package runner.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.context.support.WithUserDetails; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import runner.AppRunner; +import runner.entities.Customer; +import runner.entities.Login; +import runner.security.controllers.AuthenticationController; +import runner.security.filters.JwtAuthorizationFilter; +import runner.security.utilities.JwtUtil; +import runner.services.LoginServices; +import runner.services.UserDetailServices; + +import java.util.ArrayList; + +import static org.mockito.ArgumentMatchers.any; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@AutoConfigureMockMvc +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) + +public class JwtTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private JwtUtil jwtUtil; + @MockBean + UserDetailServices userDetailServices; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Before + public void before(){ + SecurityContextHolder.clearContext(); + } + + @After + public void after(){ + SecurityContextHolder.clearContext(); + } + + @Test + public void notAuthenticatedTest() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/myaccount/test")).andExpect(status().isForbidden()); + } + + @Test + @WithMockUser + public void AuthenticatedTest() throws Exception{ + mockMvc.perform(MockMvcRequestBuilders.get("/myaccount/test")) + .andExpect(status().isOk()); + } + + @Test + public void AuthenticatedTokenAccess() throws Exception{ + UserDetails user = new User("user2","password", new ArrayList<>()); + String token = jwtUtil.generateToken(user); //bypassing spring security authentication and generate token + Mockito.when(userDetailServices.loadUserByUsername(any())).thenReturn(user); + mockMvc.perform(MockMvcRequestBuilders.get("/myaccount/test") + .header("Authorization", "Bearer "+ token)) + .andExpect(status().isOk()); + } +} diff --git a/src/test/java/runner/services/AccountServiceTest.java b/src/test/java/runner/services/AccountServiceTest.java new file mode 100644 index 000000000..730a9678c --- /dev/null +++ b/src/test/java/runner/services/AccountServiceTest.java @@ -0,0 +1,182 @@ +package runner.services; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import runner.AppRunner; +import runner.entities.Account; +import runner.entities.Customer; +import runner.entities.Login; +import runner.entities.Transaction; +import runner.enums.AccountType; +import runner.repositories.AccountRepo; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import static org.mockito.ArgumentMatchers.any; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@TestPropertySource(properties = { + "DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement" +}) + +public class AccountServiceTest { + @Mock + AccountRepo accountRepo; + @Mock + TransactionServices transactionServices; + @InjectMocks + AccountServices accountServices; + Account account1; + Account account2; + Account account3; + Set testAccounts; + Login login; + Customer customer; + Transaction transaction; + Set transactionAccount; + Transaction withdrawalTransaction; + Transaction depositTransaction; + ArrayList myTransactionList; + + @Before + public void setup(){ + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + account3 = new Account(2L,"56789", AccountType.SAVINGS,100.00,"qwerty", new ArrayList()); + testAccounts = new HashSet(); + testAccounts.add(account1); + testAccounts.add(account2); + login = new Login(1L,"user","password",customer); //customer would be null here due to order of code; + customer = new Customer(1L,"John","Doe",login,testAccounts); + transactionAccount = new HashSet(); + transactionAccount.add(account1); + transaction = new Transaction(1.00,transactionAccount); + + //=============== setup for transfer tests below, also used in deposit and withdraw ==================== + + withdrawalTransaction = new Transaction(String.format("Withdrawal to %s XXXXXXXX%s",account2.getAccountType(), + account2.getAccountNumber().substring(account2.getAccountNumber().length()-4)), + transaction.getTransactionAmount()*(-1), account1.getBalance(), LocalDate.now()); + + depositTransaction = new Transaction(String.format("Deposit from %s XXXXXXXX%s",account1.getAccountType(), + account1.getAccountNumber().substring(account1.getAccountNumber().length()-4)), + transaction.getTransactionAmount()*(-1), account2.getBalance(), LocalDate.now()); + + myTransactionList = new ArrayList(); + myTransactionList.add(withdrawalTransaction); + myTransactionList.add(depositTransaction); + } + + //PREFACE: we know the behavior of the accountRepo, this is unit test for accountServices; therefore, the results are set by the tester fro the repo + + @Test + public void getAllAccountsTest(){ + //given: when accountServices.getAlAccounts calls accountRepo.findAccountsByCustomer_LoginUsername, it will return the test Accounts; + Set expectedAccounts = testAccounts; + Mockito.when(accountRepo.findAccountsByCustomer_LoginUsername(any())).thenReturn(testAccounts); + //when: telling accountServices to get all accounts + Set actualAccounts = accountServices.getAllAccounts(login.getUsername()); + //the two sets should be identical + Assert.assertTrue(actualAccounts.containsAll(expectedAccounts)); + } + + @Test + public void findAccountByEncryptedUrlTest(){ + Account expectedAccount = account1; + Mockito.when(accountRepo.findAccountByEncryptedUrl(any())).thenReturn(account1); + + Account actualAccount = accountServices.getAccountByEncryptedUrl(account1.getEncryptedUrl()); + + Assert.assertTrue(expectedAccount.equals(actualAccount)); + } + +// @Test +// public void createAccountTest() throws Exception { +// Account expectedAccount = account1; +// Mockito.when(accountRepo.findAccountsByCustomer_LoginUsername(any())).thenReturn(testAccounts); +// Mockito.when(accountRepo.save(any())).thenReturn(expectedAccount); +// +// Account actualAccount = accountServices.createAccount(expectedAccount, login.getUsername()); +// +// Assert.assertTrue(expectedAccount.getAccountNumber().length()==10); +// } + + + @Test + public void transferMoneyTestTrue() throws Exception { + Account expectedAccount1 = account1; + Account expectedAccount2 = account2; + expectedAccount1.setBalance(account1.getBalance()-transaction.getTransactionAmount()); + expectedAccount2.setBalance(account2.getBalance()+transaction.getTransactionAmount()); + + Mockito.when(transactionServices.setAllTransactions(any(),any(),any())).thenReturn(myTransactionList); + + Account[] actualAccounts = accountServices.transferMoney(transaction,account1,account2); + + Assert.assertEquals(actualAccounts[0].getBalance(),expectedAccount1.getBalance()); + Assert.assertEquals(actualAccounts[1].getBalance(),expectedAccount2.getBalance()); + Assert.assertTrue(actualAccounts[0].getTransactions().contains(withdrawalTransaction)); + Assert.assertTrue(actualAccounts[1].getTransactions().contains(depositTransaction)); + } + + @Test(expected = Exception.class) //account the money is being withdrawn from has insufficient funds + public void transferMoneyTestFalse() throws Exception { + Mockito.when(transactionServices.setAllTransactions(any(),any(),any())).thenReturn(myTransactionList); + Account[] actualAccounts = accountServices.transferMoney(transaction,account2,account1); + } + + + @Test + public void withdrawTest() throws Exception { + String encryptedUrl = account1.getEncryptedUrl(); + Account expectedAccount = account1; + expectedAccount.setBalance(expectedAccount.getBalance()-transaction.getTransactionAmount()); + Mockito.when(accountRepo.findAccountByEncryptedUrl(any())).thenReturn(account3); + Mockito.when(accountRepo.findAccountByAccountNumber(any())).thenReturn(account1); + Mockito.when(transactionServices.setAllTransactions(any(),any(),any())).thenReturn(myTransactionList); + Mockito.when(accountRepo.save(any())).thenReturn(account3, account1); //first and second instance + + Account actualAccount = accountServices.withdraw(transaction,encryptedUrl); + + Assert.assertEquals(expectedAccount.getBalance(),actualAccount.getBalance()); + } + + @Test + public void depositTest() throws Exception { + String encryptedUrl = account1.getEncryptedUrl(); + Account expectedAccount = account1; + expectedAccount.setBalance(expectedAccount.getBalance()+transaction.getTransactionAmount()); + Mockito.when(accountRepo.findAccountByEncryptedUrl(any())).thenReturn(account3); + Mockito.when(accountRepo.findAccountByAccountNumber(any())).thenReturn(account1); + Mockito.when(transactionServices.setAllTransactions(any(),any(),any())).thenReturn(myTransactionList); + Mockito.when(accountRepo.save(any())).thenReturn(account3, account1); //first and second instance + + Account actualAccount = accountServices.deposit(transaction,encryptedUrl); + + Assert.assertEquals(expectedAccount.getBalance(),actualAccount.getBalance()); + } + + + @Test + public void generateRandomURLTest() throws Exception { + String actual = accountServices.generateRandomUrl(); + Assert.assertTrue(actual.length()!=0); + } + +} diff --git a/src/test/java/runner/services/CustomerServiceTest.java b/src/test/java/runner/services/CustomerServiceTest.java new file mode 100644 index 000000000..0dab1c4ed --- /dev/null +++ b/src/test/java/runner/services/CustomerServiceTest.java @@ -0,0 +1,200 @@ +package runner.services; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import runner.AppRunner; +import runner.entities.*; +import runner.enums.AccountType; +import runner.repositories.CustomerRepo; + +import java.util.*; + +import static org.mockito.ArgumentMatchers.any; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@TestPropertySource(properties = {"DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement"}) +public class CustomerServiceTest { + @Mock (name = "mock2") + BCryptPasswordEncoder bCryptPasswordEncoder; + @Mock (name = "mock3") + AccountServices accountServices; + @Mock (name = "mock1") + CustomerRepo customerRepo; + @InjectMocks + private CustomerServices customerServices; //Calls the mockito + + Account account1; + Account account2; + Account account3; + Set testAccounts; + Login login; + Login login1; + Customer customer; + Address address; + List logins ; + + @Before + public void setup(){ + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + account3 = new Account(2L,"56789", AccountType.SAVINGS,100.00,"qwerty", new ArrayList()); + testAccounts = new HashSet(); + testAccounts.add(account1); + testAccounts.add(account2); + login = new Login(1L,"user1","password",customer); //customer would be null here due to order of code; + login1 = new Login(2L,"user2","password",customer); //customer would be null here due to order of code; + address = new Address(1L,"Address Line 1", "Address Line 2", "Bear","DE","19701"); + customer = new Customer(1L,"John","Doe",address,login,testAccounts); + logins = Arrays.asList(login.getUsername(),login1.getUsername()); + } + +/* @Test + public void readUserByIdTest() { + String expectedName= "John"; + Mockito.when(customerRepo.findCustomerById(1L)).thenReturn(customer); + String testName = customerServices.readCustomer(1L).getFirstName(); + Assert.assertEquals(expectedName, testName); + }*/ + + @Test + public void readUserByLoginTest() { + String expectedName= "John"; + Mockito.when(customerRepo.findCustomerByLoginUsername("user")).thenReturn(customer); + String testName = customerServices.readCustomerByLogin("user").getFirstName(); + Assert.assertEquals(expectedName, testName); + } + + @Test + public void createUserTest() throws Exception { + Customer expectedCustomer = customer; + Mockito.when(bCryptPasswordEncoder.encode(any())).thenReturn("blahblah"); + Mockito.when(accountServices.setUpAccount(any())).thenReturn(account1); + Mockito.doNothing().when(accountServices).transferMoneyToNewAccount(any()); + Mockito.when(customerRepo.save(any())).thenReturn(expectedCustomer); + customerServices.createCustomer(customer); + Assert.assertTrue(expectedCustomer.getId()!=0); + } + + @Test + public void deleteUserTest() { + int expected = 2; + Mockito.when(customerRepo.save(customer)).thenReturn(customer); + Mockito.when(customerRepo.findCustomerById(customer.getId())).thenReturn(customer); + int actual= customerServices.deleteCustomer(customer.getId()); + Assert.assertEquals(expected, actual); + } + + @Test + public void checkAccountBalanceAndDeleteTest() { + int expected = 2; + Mockito.when(customerRepo.save(customer)).thenReturn(customer); + Mockito.when(customerRepo.findCustomerById(customer.getId())).thenReturn(customer); + int actual= customerServices.checkAccountBalanceAndDelete(customer.getId(),customer); + Assert.assertEquals(expected, actual); + } + +/* @Test + public void updateUserTest() throws Exception { + // Customer customer1 = new Customer( 2L, "Radha" , "Ramnik",address,login,testAccounts); + String expectedUpdateName= "Update the First Name"; + Mockito.when(customerRepo.findCustomerById(customer.getId())).thenReturn(customer); + customer.setFirstName(expectedUpdateName); + Mockito.when(customerRepo.save(customer)).thenReturn(customer); + + //Fails as customerService has been autowried to accountServices too... Need to look into this. + String actualUpdatedName= customerServices.updateCustomer(customer.getId(), customer).getFirstName(); + Assert.assertEquals(expectedUpdateName, actualUpdatedName); + }*/ + + @Test + public void updateUserPhoneNumberTest() throws Exception { + Customer customer1 = new Customer(2L, "Radha", "Ramnik", address, login, testAccounts); + Customer customer2 = new Customer(2L, "Radha", "Ramnik", address, login, testAccounts); + String newPhoneNumber = "2151234567"; + customer2.setPhoneNumber(newPhoneNumber); + + Mockito.when(customerRepo.save(customer1)).thenReturn(customer1); + Mockito.when(customerRepo.findCustomerByLoginUsername(any())).thenReturn(customer1); + customerServices.updateCustomerPhoneNumber(customer1.getLogin().getUsername(), customer2); + + Assert.assertTrue(customer1.getPhoneNumber().equals(newPhoneNumber)); + } + + @Test + public void updateUserEmailTest() throws Exception { + Customer customer1 = new Customer( 2L, "Radha" , "Ramnik",address,login,testAccounts); + Customer customer2 = new Customer(2L, "Radha", "Ramnik", address, login, testAccounts); + String newEmail = "test@gmail.com"; + customer2.setEmail(newEmail); + + Mockito.when(customerRepo.findCustomerByLoginUsername(any())).thenReturn(customer1); + customerServices.updateCustomerEmail(customer1.getLogin().getUsername(), customer2); + + Assert.assertTrue(customer1.getEmail().equals(newEmail)); + } + + @Test + public void updateUserAddressTest() throws Exception { + Customer customer1 = new Customer( 2L, "Radha" , "Ramnik",address,login,testAccounts); + Address newAddress = new Address(1L,"123 A st", null, "Philadelphia","PA","19148"); + + Mockito.when(customerRepo.findCustomerByLoginUsername(any())).thenReturn(customer1); + customerServices.updateCustomerAddress(customer1.getLogin().getUsername(), newAddress); + + Assert.assertEquals(newAddress.getFirstLine(), customer1.getAddress().getFirstLine()); + } + + @Test + public void checkLoginTest() throws Exception { + Boolean expected =false; + + Mockito.when(customerRepo.findAllLoginsNative()).thenReturn(logins); + Boolean actual= customerServices.checkLogin(login); + Assert.assertEquals(expected, actual); + } + + @Test + public void getAllAccountsTest() throws Exception { + Mockito.when(customerRepo.findCustomerById(customer.getId())).thenReturn(customer); + Set actualAccounts= customerServices.getAllAccounts(customer.getId()); + Assert.assertEquals(testAccounts.size(), actualAccounts.size()); + } + + @Test + public void removeAccountTestTrue()throws Exception { + String username = customer.getLogin().getUsername(); + String encryptedUrl = account2.getEncryptedUrl(); + Mockito.when(customerRepo.findCustomerByLoginUsername(any())).thenReturn(customer); + Mockito.when(customerRepo.save(any())).thenReturn(customer); + + customerServices.removeAccount(username,encryptedUrl); + + Assert.assertTrue(customer.getAccounts().size()==1); + } + + + @Test(expected = Exception.class) + public void removeAccountTest() throws Exception { + String username = customer.getLogin().getUsername(); + String encryptedUrl = account1.getEncryptedUrl(); + Mockito.when(customerRepo.findCustomerByLoginUsername(any())).thenReturn(customer); + Mockito.when(customerRepo.save(any())).thenReturn(customer); + + customerServices.removeAccount(username,encryptedUrl); + } + +} \ No newline at end of file diff --git a/src/test/java/runner/services/TransactionServicesTest.java b/src/test/java/runner/services/TransactionServicesTest.java new file mode 100644 index 000000000..020c34b17 --- /dev/null +++ b/src/test/java/runner/services/TransactionServicesTest.java @@ -0,0 +1,89 @@ +package runner.services; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import runner.AppRunner; +import runner.entities.Account; +import runner.entities.Customer; +import runner.entities.Login; +import runner.entities.Transaction; +import runner.enums.AccountType; +import runner.repositories.AccountRepo; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +@ActiveProfiles("test") +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = AppRunner.class) +@TestPropertySource(properties = { + "DB_USER=newuser", + "DB_PASS=password", + "DB_URL=jdbc:mysql://localhost:3306/moneymanagement" +}) +public class TransactionServicesTest { + @Autowired + TransactionServices transactionServices; + Account account1; + Account account2; + Transaction transaction; + Set transactionAccount; + + @Before + public void setup(){ + transactionAccount = new HashSet(); + transactionAccount.add(account1); + transaction = new Transaction(1.00,transactionAccount); + account1 = new Account(1L,"12345", AccountType.CHECKING,100.00,"abcdefg", new ArrayList()); + account2 = new Account(2L,"54321", AccountType.SAVINGS,0.00,"gfedcba", new ArrayList()); + } + + @Test + public void setAllTransactionTest(){ + ArrayList actualTransactionList = transactionServices.setAllTransactions(transaction,account1,account2); + Assert.assertTrue(actualTransactionList.size() == 2); + } + + @Test + public void setOneTransactionTestWithdraw(){ + Transaction expected = new Transaction(String.format("Withdrawal to %s XXXXXXXX%s",account2.getAccountType(), + account2.getAccountNumber().substring(account2.getAccountNumber().length()-4)), + transaction.getTransactionAmount()*(-1), account1.getBalance(), LocalDate.now()); + + Transaction actual = transactionServices.setOneTransaction(transaction,account1,account2,true); + + Assert.assertEquals(expected.getTransactionAmount(),actual.getTransactionAmount()); + Assert.assertEquals(expected.getTransactionBalance(),actual.getTransactionBalance()); + Assert.assertEquals(expected.getTransactionDate(),actual.getTransactionDate()); + Assert.assertEquals(expected.getTransactionDescription(),actual.getTransactionDescription()); + } + + @Test + public void setOneTransactionTestDeposit(){ + Transaction expected = new Transaction(String.format("Deposit from %s XXXXXXXX%s",account1.getAccountType(), + account1.getAccountNumber().substring(account1.getAccountNumber().length()-4)), + transaction.getTransactionAmount(), account2.getBalance(), LocalDate.now()); + + Transaction actual = transactionServices.setOneTransaction(transaction,account2,account1,false); + + Assert.assertEquals(expected.getTransactionAmount(),actual.getTransactionAmount()); + Assert.assertEquals(expected.getTransactionBalance(),actual.getTransactionBalance()); + Assert.assertEquals(expected.getTransactionDate(),actual.getTransactionDate()); + Assert.assertEquals(expected.getTransactionDescription(),actual.getTransactionDescription()); + } + +} diff --git a/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar b/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar new file mode 100644 index 000000000..23a9061b9 Binary files /dev/null and b/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar differ diff --git a/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar.original b/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar.original new file mode 100644 index 000000000..af7a1d811 Binary files /dev/null and b/target/FullStack.MicroWebApplication-Server-1.0-SNAPSHOT.jar.original differ diff --git a/target/classes/AppRunner.class b/target/classes/AppRunner.class deleted file mode 100644 index f60264030..000000000 Binary files a/target/classes/AppRunner.class and /dev/null differ diff --git a/target/classes/application.properties b/target/classes/application.properties index 945220da0..df6e3d65c 100644 --- a/target/classes/application.properties +++ b/target/classes/application.properties @@ -1,4 +1,3 @@ -spring.jpa.show-sql=true server.port=8080 spring.h2.console.enabled=true #spring.datasource.generate-unique-name=false @@ -8,9 +7,41 @@ spring.h2.console.enabled=true #spring.jpa.database-platform=org.hibernate.dialect.H2Dialect #spring.h2.console.settings.trace=false #spring.h2.console.settings.web-allow-others=false -spring.datasource.url=jdbc:mysql://localhost:3306/zipcode -spring.datasource.username=gunjan -spring.datasource.password=zipcode0 + +#Stored the values in environment variable +#spring.datasource.url=${JDBC_DATABASE_URL} +spring.datasource.url=${DB_URL} +spring.datasource.username=${DB_USER} +spring.datasource.password=${DB_PASS} +#Another way to encrypt password +#spring.datasource.password=ENC(dTbA3RZ3U1/RJPUcVcJIdkxmopJI1RZP) +#jasypt.encryptor.password=moneymanagement + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ### had to add this because of the .hibernate_sequence doesn't exist errors! -spring.jpa.hibernate.use-new-id-generator-mappings= false \ No newline at end of file +spring.jpa.hibernate.use-new-id-generator-mappings= false + +#set to 'none' to .ddl-auto if you want to create mysql tables from "schema.sql" files instead of from entities +spring.jpa.hibernate.ddl-auto = none +spring.jpa.generate-ddl=true +spring.jpa.show-sql=true +#tells hibernate where to find initial data to import into mysql if .ddl-auto method is used +spring.jpa.properties.hibernate.hbm2ddl.import_files= classpath:db/import.sql +#below is needed for JPA to read SQL language from import.sql +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect +#spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy + +#set to 'always' if you want to create mysql tables from "schema.sql" file instead of from entities +spring.datasource.initialization-mode=never + +#tells hibernate where to find the data and schema file +#spring.datasource.data= classpath:db/data.sql +#spring.datasource.schema = classpath:db/schema.sql + +#Need this for testing to work properly +spring.main.allow-bean-definition-overriding=true + + +#jdbc:mysql://localhost:3306/moneymanagement +#jdbc:mysql://mysql-moneymanagement.cvq8xhrssade.us-east-2.rds.amazonaws.com/moneymanagement + diff --git a/target/classes/controllers/AccountController.class b/target/classes/controllers/AccountController.class deleted file mode 100644 index 2a33e5aa6..000000000 Binary files a/target/classes/controllers/AccountController.class and /dev/null differ diff --git a/target/classes/controllers/LoginController.class b/target/classes/controllers/LoginController.class deleted file mode 100644 index a3c7b6a5f..000000000 Binary files a/target/classes/controllers/LoginController.class and /dev/null differ diff --git a/target/classes/controllers/TransactionController.class b/target/classes/controllers/TransactionController.class deleted file mode 100644 index 24f8dd722..000000000 Binary files a/target/classes/controllers/TransactionController.class and /dev/null differ diff --git a/target/classes/controllers/UserController.class b/target/classes/controllers/UserController.class deleted file mode 100644 index 4f1db4fa3..000000000 Binary files a/target/classes/controllers/UserController.class and /dev/null differ diff --git a/target/classes/db/import.sql b/target/classes/db/import.sql new file mode 100644 index 000000000..41ac5be6a --- /dev/null +++ b/target/classes/db/import.sql @@ -0,0 +1,40 @@ +-- MySQL dump 10.13 Distrib 8.0.22, for macos10.15 (x86_64) +-- +-- Host: localhost Database: moneymanagement +-- ------------------------------------------------------ +-- Server version 8.0.22 + +-- +-- Dumping data for table `account` +-- + +INSERT INTO `account` VALUES (1,'1234567890','CHECKING',999999999999,'2004-01-22',NULL,.2,'091000022',1); +INSERT INTO `account` VALUES (2,'1111111111','CHECKING',0,'2004-01-22',NULL,.2,'091000022',1),(3,'4444444444','SAVINGS',25000,'2004-01-22',NULL,.85,'091000022',1); +# INSERT INTO `account` VALUES (5,'2222222222','CHECKING',0,'2004-01-22',NULL,.2,'091000022',3); +-- +-- Dumping data for table `login` +-- + +INSERT INTO `login` VALUES (1,'$2a$10$DM98Ynu/prVcywurljSHSOko73BKJb29RFW3vCGFYT9DBAW6Jd1W2','user1'); +INSERT INTO `login` VALUES (3,'$2a$10$DM98Ynu/prVcywurljSHSOko73BKJb29RFW3vCGFYT9DBAW6Jd1W2','user3'); +-- +-- Dumping data for table `transaction_history` +-- + + -- INSERT INTO `transaction` VALUES (1,'1245451',10.21,'2004-01-22','testing',1); + +-- +-- Dumping data for table `customer` +-- + +INSERT INTO `customer` VALUES (1,'2012-05-05','tom@gmail.com','Peggy','Patel','G','5122264785','435435345',1); +INSERT INTO `customer` VALUES (3,'2012-05-05','tom@gmail.com','Tom','Walter','G','5122264785','435435345',3); + +-- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +-- +-- Dumping data for table `address` +-- + +INSERT INTO `address` VALUES (1,'Bear','123 A st','Second Line','DE','19801'); +INSERT INTO `address` VALUES (3,'Austin','123 A st','Second Line','Texas','19147'); \ No newline at end of file diff --git a/target/classes/entities/Account.class b/target/classes/entities/Account.class deleted file mode 100644 index eed27af8e..000000000 Binary files a/target/classes/entities/Account.class and /dev/null differ diff --git a/target/classes/entities/Checkings.class b/target/classes/entities/Checkings.class deleted file mode 100644 index c93176702..000000000 Binary files a/target/classes/entities/Checkings.class and /dev/null differ diff --git a/target/classes/entities/Investments.class b/target/classes/entities/Investments.class deleted file mode 100644 index edefce525..000000000 Binary files a/target/classes/entities/Investments.class and /dev/null differ diff --git a/target/classes/entities/Login.class b/target/classes/entities/Login.class deleted file mode 100644 index 4d64c22f8..000000000 Binary files a/target/classes/entities/Login.class and /dev/null differ diff --git a/target/classes/entities/Savings.class b/target/classes/entities/Savings.class deleted file mode 100644 index 41730d579..000000000 Binary files a/target/classes/entities/Savings.class and /dev/null differ diff --git a/target/classes/entities/TransactionHistory.class b/target/classes/entities/TransactionHistory.class deleted file mode 100644 index f04b11539..000000000 Binary files a/target/classes/entities/TransactionHistory.class and /dev/null differ diff --git a/target/classes/entities/User.class b/target/classes/entities/User.class deleted file mode 100644 index 98fd39f56..000000000 Binary files a/target/classes/entities/User.class and /dev/null differ diff --git a/target/classes/rds-combined-ca-bundle.pem b/target/classes/rds-combined-ca-bundle.pem new file mode 100644 index 000000000..864a818dd --- /dev/null +++ b/target/classes/rds-combined-ca-bundle.pem @@ -0,0 +1,720 @@ +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSUwIwYDVQQDDBxBbWF6b24gUkRTIGFwLWVhc3QtMSBSb290IENBMB4XDTE5MDIx +NzAyNDcwMFoXDTIyMDYwMTEyMDAwMFowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6b24g +V2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSAwHgYDVQQD +DBdBbWF6b24gUkRTIGFwLWVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOcJAUofyJuBuPr5ISHi/Ha5ed8h3eGdzn4MBp6rytPOg9NVGRQs +O93fNGCIKsUT6gPuk+1f1ncMTV8Y0Fdf4aqGWme+Khm3ZOP3V1IiGnVq0U2xiOmn +SQ4Q7LoeQC4lC6zpoCHVJyDjZ4pAknQQfsXb77Togdt/tK5ahev0D+Q3gCwAoBoO +DHKJ6t820qPi63AeGbJrsfNjLKiXlFPDUj4BGir4dUzjEeH7/hx37na1XG/3EcxP +399cT5k7sY/CR9kctMlUyEEUNQOmhi/ly1Lgtihm3QfjL6K9aGLFNwX35Bkh9aL2 +F058u+n8DP/dPeKUAcJKiQZUmzuen5n57x8CAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFlqgF4FQlb9yP6c+Q3E +O3tXv+zOMB8GA1UdIwQYMBaAFK9T6sY/PBZVbnHcNcQXf58P4OuPMA0GCSqGSIb3 +DQEBCwUAA4IBAQDeXiS3v1z4jWAo1UvVyKDeHjtrtEH1Rida1eOXauFuEQa5tuOk +E53Os4haZCW4mOlKjigWs4LN+uLIAe1aFXGo92nGIqyJISHJ1L+bopx/JmIbHMCZ +0lTNJfR12yBma5VQy7vzeFku/SisKwX0Lov1oHD4MVhJoHbUJYkmAjxorcIHORvh +I3Vj5XrgDWtLDPL8/Id/roul/L+WX5ir+PGScKBfQIIN2lWdZoqdsx8YWqhm/ikL +C6qNieSwcvWL7C03ri0DefTQMY54r5wP33QU5hJ71JoaZI3YTeT0Nf+NRL4hM++w +Q0veeNzBQXg1f/JxfeA39IDIX1kiCf71tGlT +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEDCCAvigAwIBAgIJAJF3HxEqKM4lMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJEUyBhcC1lYXN0LTEgUm9vdCBDQTAe +Fw0xOTAyMTcwMjQ2MTFaFw0yNDAyMTYwMjQ2MTFaMIGUMQswCQYDVQQGEwJVUzEQ +MA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UECgwZ +QW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEl +MCMGA1UEAwwcQW1hem9uIFJEUyBhcC1lYXN0LTEgUm9vdCBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOCVr1Yj5IW4XWa9QOLGJDSz4pqIM6BAbqQp +gYvzIO4Lv8c8dEnuuuCY8M/zOrJ1iQJ3cDiKGa32HVBVcH+nUdXzw4Jq5jw0hsb6 +/WW2RD2aUe4jCkRD5wNzmeHM4gTgtMZnXNVHpELgKR4wVhSHEfWFTiMsZi35y8mj +PL98Mz/m/nMnB/59EjMvcJMrsUljHO6B9BMEcvNkwvre9xza0BQWKyiVRcbOpoj1 +w4BPtYYZ+dW2QKw9AmYXwAmCLeATsxrHIJ/IbzS7obxv2QN2Eh4pJ3ghRCFv1XM9 +XVkm13oiCjj7jsxAwF7o+VggPl/GG+/Gwk+TLuaTFNAtROpPxL8CAwEAAaNjMGEw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9T6sY/ +PBZVbnHcNcQXf58P4OuPMB8GA1UdIwQYMBaAFK9T6sY/PBZVbnHcNcQXf58P4OuP +MA0GCSqGSIb3DQEBCwUAA4IBAQBBY+KATaT7ndYT3Ky0VWaiwNfyl1u3aDxr+MKP +VeDhtOhlob5u0E+edOXUvEXd4A+ntS+U0HmwvtMXtQbQ2EJbsNRqZnS8KG9YB2Yc +Q99auphW3wMjwHRtflLO5h14aa9SspqJJgcM1R7Z3pAYeq6bpBDxZSGrYtWI64q4 +h4i67qWAGDFcXSTW1kJ00GMlBCIGTeYiu8LYutdsDWzYKkeezJRjx9VR4w7A7e1G +WmY4aUg/8aPxCioY2zEQKNl55Ghg6Dwy+6BxaV6RlV9r9EaSCai11p1bgS568WQn +4WNQK36EGe37l2SOpDB6STrq57/rjREvmq803Ylg/Gf6qqzK +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTA1 +MTAyMTU4NDNaFw0yNTA2MDExMjAwMDBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBtZS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAudOYPZH+ihJAo6hNYMB5izPVBe3TYhnZm8+X3IoaaYiKtsp1 +JJhkTT0CEejYIQ58Fh4QrMUyWvU8qsdK3diNyQRoYLbctsBPgxBR1u07eUJDv38/ +C1JlqgHmMnMi4y68Iy7ymv50QgAMuaBqgEBRI1R6Lfbyrb2YvH5txjJyTVMwuCfd +YPAtZVouRz0JxmnfsHyxjE+So56uOKTDuw++Ho4HhZ7Qveej7XB8b+PIPuroknd3 +FQB5RVbXRvt5ZcVD4F2fbEdBniF7FAF4dEiofVCQGQ2nynT7dZdEIPfPdH3n7ZmE +lAOmwHQ6G83OsiHRBLnbp+QZRgOsjkHJxT20bQIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUOEVDM7VomRH4HVdA +QvIMNq2tXOcwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXdaiqYwDQYJKoZI +hvcNAQELBQADggEBAHhvMssj+Th8IpNePU6RH0BiL6o9c437R3Q4IEJeFdYL+nZz +PW/rELDPvLRUNMfKM+KzduLZ+l29HahxefejYPXtvXBlq/E/9czFDD4fWXg+zVou +uDXhyrV4kNmP4S0eqsAP/jQHPOZAMFA4yVwO9hlqmePhyDnszCh9c1PfJSBh49+b +4w7i/L3VBOMt8j3EKYvqz0gVfpeqhJwL4Hey8UbVfJRFJMJzfNHpePqtDRAY7yjV +PYquRaV2ab/E+/7VFkWMM4tazYz/qsYA2jSH+4xDHvYk8LnsbcrF9iuidQmEc5sb +FgcWaSKG4DJjcI5k7AJLWcXyTDt21Ci43LE+I9Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJANew34ehz5l8MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBtZS1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkwNTEwMjE0ODI3WhcNMjQwNTA4MjE0ODI3WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgbWUtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp7BYV88MukcY+rq0r79+C8UzkT30fEfT +aPXbx1d6M7uheGN4FMaoYmL+JE1NZPaMRIPTHhFtLSdPccInvenRDIatcXX+jgOk +UA6lnHQ98pwN0pfDUyz/Vph4jBR9LcVkBbe0zdoKKp+HGbMPRU0N2yNrog9gM5O8 +gkU/3O2csJ/OFQNnj4c2NQloGMUpEmedwJMOyQQfcUyt9CvZDfIPNnheUS29jGSw +ERpJe/AENu8Pxyc72jaXQuD+FEi2Ck6lBkSlWYQFhTottAeGvVFNCzKszCntrtqd +rdYUwurYsLTXDHv9nW2hfDUQa0mhXf9gNDOBIVAZugR9NqNRNyYLHQIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU54cf +DjgwBx4ycBH8+/r8WXdaiqYwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXda +iqYwDQYJKoZIhvcNAQELBQADggEBAIIMTSPx/dR7jlcxggr+O6OyY49Rlap2laKA +eC/XI4ySP3vQkIFlP822U9Kh8a9s46eR0uiwV4AGLabcu0iKYfXjPkIprVCqeXV7 +ny9oDtrbflyj7NcGdZLvuzSwgl9SYTJp7PVCZtZutsPYlbJrBPHwFABvAkMvRtDB +hitIg4AESDGPoCl94sYHpfDfjpUDMSrAMDUyO6DyBdZH5ryRMAs3lGtsmkkNUrso +aTW6R05681Z0mvkRdb+cdXtKOSuDZPoe2wJJIaz3IlNQNSrB5TImMYgmt6iAsFhv +3vfTSTKrZDNTJn4ybG6pq1zWExoXsktZPylJly6R3RBwV6nwqBM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEETCCAvmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSUwIwYDVQQDDBxBbWF6b24gUkRTIEJldGEgUm9vdCAyMDE5IENBMB4XDTE5MDgy +MDE3MTAwN1oXDTI0MDgxOTE3MzgyNlowgZkxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6b24g +V2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSowKAYDVQQD +DCFBbWF6b24gUkRTIEJldGEgdXMtZWFzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDTNCOlotQcLP8TP82U2+nk0bExVuuMVOgFeVMx +vbUHZQeIj9ikjk+jm6eTDnnkhoZcmJiJgRy+5Jt69QcRbb3y3SAU7VoHgtraVbxF +QDh7JEHI9tqEEVOA5OvRrDRcyeEYBoTDgh76ROco2lR+/9uCvGtHVrMCtG7BP7ZB +sSVNAr1IIRZZqKLv2skKT/7mzZR2ivcw9UeBBTUf8xsfiYVBvMGoEsXEycjYdf6w +WV+7XS7teNOc9UgsFNN+9AhIBc1jvee5E//72/4F8pAttAg/+mmPUyIKtekNJ4gj +OAR2VAzGx1ybzWPwIgOudZFHXFduxvq4f1hIRPH0KbQ/gkRrAgMBAAGjZjBkMA4G +A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTkvpCD +6C43rar9TtJoXr7q8dkrrjAfBgNVHSMEGDAWgBStoQwVpbGx87fxB3dEGDqKKnBT +4TANBgkqhkiG9w0BAQsFAAOCAQEAJd9fOSkwB3uVdsS+puj6gCER8jqmhd3g/J5V +Zjk9cKS8H0e8pq/tMxeJ8kpurPAzUk5RkCspGt2l0BSwmf3ahr8aJRviMX6AuW3/ +g8aKplTvq/WMNGKLXONa3Sq8591J+ce8gtOX/1rDKmFI4wQ/gUzOSYiT991m7QKS +Fr6HMgFuz7RNJbb3Fy5cnurh8eYWA7mMv7laiLwTNsaro5qsqErD5uXuot6o9beT +a+GiKinEur35tNxAr47ax4IRubuIzyfCrezjfKc5raVV2NURJDyKP0m0CCaffAxE +qn2dNfYc3v1D8ypg3XjHlOzRo32RB04o8ALHMD9LSwsYDLpMag== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEDCCAvigAwIBAgIJAKFMXyltvuRdMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTAe +Fw0xOTA4MTkxNzM4MjZaFw0yNDA4MTkxNzM4MjZaMIGUMQswCQYDVQQGEwJVUzEQ +MA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UECgwZ +QW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEl +MCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMkZdnIH9ndatGAcFo+DppGJ1HUt4x+zeO+0 +ZZ29m0sfGetVulmTlv2d5b66e+QXZFWpcPQMouSxxYTW08TbrQiZngKr40JNXftA +atvzBqIImD4II0ZX5UEVj2h98qe/ypW5xaDN7fEa5e8FkYB1TEemPaWIbNXqchcL +tV7IJPr3Cd7Z5gZJlmujIVDPpMuSiNaal9/6nT9oqN+JSM1fx5SzrU5ssg1Vp1vv +5Xab64uOg7wCJRB9R2GC9XD04odX6VcxUAGrZo6LR64ZSifupo3l+R5sVOc5i8NH +skdboTzU9H7+oSdqoAyhIU717PcqeDum23DYlPE2nGBWckE+eT8CAwEAAaNjMGEw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK2hDBWl +sbHzt/EHd0QYOooqcFPhMB8GA1UdIwQYMBaAFK2hDBWlsbHzt/EHd0QYOooqcFPh +MA0GCSqGSIb3DQEBCwUAA4IBAQAO/718k8EnOqJDx6wweUscGTGL/QdKXUzTVRAx +JUsjNUv49mH2HQVEW7oxszfH6cPCaupNAddMhQc4C/af6GHX8HnqfPDk27/yBQI+ +yBBvIanGgxv9c9wBbmcIaCEWJcsLp3HzXSYHmjiqkViXwCpYfkoV3Ns2m8bp+KCO +y9XmcCKRaXkt237qmoxoh2sGmBHk2UlQtOsMC0aUQ4d7teAJG0q6pbyZEiPyKZY1 +XR/UVxMJL0Q4iVpcRS1kaNCMfqS2smbLJeNdsan8pkw1dvPhcaVTb7CvjhJtjztF +YfDzAI5794qMlWxwilKMmUvDlPPOTen8NNHkLwWvyFCH7Doh +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFzCCAv+gAwIBAgICFSUwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSgwJgYDVQQDDB9BbWF6b24gUkRTIFByZXZpZXcgUm9vdCAyMDE5IENBMB4XDTE5 +MDgyMTIyMzk0N1oXDTI0MDgyMTIyMjk0OVowgZwxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6 +b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMS0wKwYD +VQQDDCRBbWF6b24gUkRTIFByZXZpZXcgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0dB/U7qRnSf05wOi7m10Pa2uPMTJv +r6U/3Y17a5prq5Zr4++CnSUYarG51YuIf355dKs+7Lpzs782PIwCmLpzAHKWzix6 +pOaTQ+WZ0+vUMTxyqgqWbsBgSCyP7pVBiyqnmLC/L4az9XnscrbAX4pNaoJxsuQe +mzBo6yofjQaAzCX69DuqxFkVTRQnVy7LCFkVaZtjNAftnAHJjVgQw7lIhdGZp9q9 +IafRt2gteihYfpn+EAQ/t/E4MnhrYs4CPLfS7BaYXBycEKC5Muj1l4GijNNQ0Efo +xG8LSZz7SNgUvfVwiNTaqfLP3AtEAWiqxyMyh3VO+1HpCjT7uNBFtmF3AgMBAAGj +ZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW +BBQtinkdrj+0B2+qdXngV2tgHnPIujAfBgNVHSMEGDAWgBRp0xqULkNh/w2ZVzEI +o2RIY7O03TANBgkqhkiG9w0BAQsFAAOCAQEAtJdqbCxDeMc8VN1/RzCabw9BIL/z +73Auh8eFTww/sup26yn8NWUkfbckeDYr1BrXa+rPyLfHpg06kwR8rBKyrs5mHwJx +bvOzXD/5WTdgreB+2Fb7mXNvWhenYuji1MF+q1R2DXV3I05zWHteKX6Dajmx+Uuq +Yq78oaCBSV48hMxWlp8fm40ANCL1+gzQ122xweMFN09FmNYFhwuW+Ao+Vv90ZfQG +PYwTvN4n/gegw2TYcifGZC2PNX74q3DH03DXe5fvNgRW5plgz/7f+9mS+YHd5qa9 +tYTPUvoRbi169ou6jicsMKUKPORHWhiTpSCWR1FMMIbsAcsyrvtIsuaGCQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFjCCAv6gAwIBAgIJAMzYZJ+R9NBVMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBD +QTAeFw0xOTA4MjEyMjI5NDlaFw0yNDA4MjEyMjI5NDlaMIGXMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBDQTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7kkS6vjgKKQTPynC2NjdN5aPPV +O71G0JJS/2ARVBVJd93JLiGovVJilfWYfwZCs4gTRSSjrUD4D4HyqCd6A+eEEtJq +M0DEC7i0dC+9WNTsPszuB206Jy2IUmxZMIKJAA1NHSbIMjB+b6/JhbSUi7nKdbR/ +brj83bF+RoSA+ogrgX7mQbxhmFcoZN9OGaJgYKsKWUt5Wqv627KkGodUK8mDepgD +S3ZfoRQRx3iceETpcmHJvaIge6+vyDX3d9Z22jmvQ4AKv3py2CmU2UwuhOltFDwB +0ddtb39vgwrJxaGfiMRHpEP1DfNLWHAnA69/pgZPwIggidS+iBPUhgucMp8CAwEA +AaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FGnTGpQuQ2H/DZlXMQijZEhjs7TdMB8GA1UdIwQYMBaAFGnTGpQuQ2H/DZlXMQij +ZEhjs7TdMA0GCSqGSIb3DQEBCwUAA4IBAQC3xz1vQvcXAfpcZlngiRWeqU8zQAMQ +LZPCFNv7PVk4pmqX+ZiIRo4f9Zy7TrOVcboCnqmP/b/mNq0gVF4O+88jwXJZD+f8 +/RnABMZcnGU+vK0YmxsAtYU6TIb1uhRFmbF8K80HHbj9vSjBGIQdPCbvmR2zY6VJ +BYM+w9U9hp6H4DVMLKXPc1bFlKA5OBTgUtgkDibWJKFOEPW3UOYwp9uq6pFoN0AO +xMTldqWFsOF3bJIlvOY0c/1EFZXu3Ns6/oCP//Ap9vumldYMUZWmbK+gK33FPOXV +8BQ6jNC29icv7lLDpRPwjibJBXX+peDR5UK4FdYcswWEB1Tix5X8dYu6 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgICVIYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDQxNzEz +MDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h +em9uIFJEUyBhcC1zb3V0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDUYOz1hGL42yUCrcsMSOoU8AeD/3KgZ4q7gP+vAz1WnY9K/kim +eWN/2Qqzlo3+mxSFQFyD4MyV3+CnCPnBl9Sh1G/F6kThNiJ7dEWSWBQGAB6HMDbC +BaAsmUc1UIz8sLTL3fO+S9wYhA63Wun0Fbm/Rn2yk/4WnJAaMZcEtYf6e0KNa0LM +p/kN/70/8cD3iz3dDR8zOZFpHoCtf0ek80QqTich0A9n3JLxR6g6tpwoYviVg89e +qCjQ4axxOkWWeusLeTJCcY6CkVyFvDAKvcUl1ytM5AiaUkXblE7zDFXRM4qMMRdt +lPm8d3pFxh0fRYk8bIKnpmtOpz3RIctDrZZxAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBT99wKJftD3jb4sHoHG +i3uGlH6W6TAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAZ17hhr3dII3hUfuHQ1hPWGrpJOX/G9dLzkprEIcCidkmRYl+ +hu1Pe3caRMh/17+qsoEErmnVq5jNY9X1GZL04IZH8YbHc7iRHw3HcWAdhN8633+K +jYEB2LbJ3vluCGnCejq9djDb6alOugdLMJzxOkHDhMZ6/gYbECOot+ph1tQuZXzD +tZ7prRsrcuPBChHlPjmGy8M9z8u+kF196iNSUGC4lM8vLkHM7ycc1/ZOwRq9aaTe +iOghbQQyAEe03MWCyDGtSmDfr0qEk+CHN+6hPiaL8qKt4s+V9P7DeK4iW08ny8Ox +AVS7u0OK/5+jKMAMrKwpYrBydOjTUTHScocyNw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIJAMc0ZzaSUK51MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkw +ODIyMTcwODUwWhcNMjQwODIyMTcwODUwWjCBjzELMAkGA1UEBhMCVVMxEDAOBgNV +BAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoMGUFtYXpv +biBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxIDAeBgNV +BAMMF0FtYXpvbiBSRFMgUm9vdCAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEArXnF/E6/Qh+ku3hQTSKPMhQQlCpoWvnIthzX6MK3p5a0eXKZ +oWIjYcNNG6UwJjp4fUXl6glp53Jobn+tWNX88dNH2n8DVbppSwScVE2LpuL+94vY +0EYE/XxN7svKea8YvlrqkUBKyxLxTjh+U/KrGOaHxz9v0l6ZNlDbuaZw3qIWdD/I +6aNbGeRUVtpM6P+bWIoxVl/caQylQS6CEYUk+CpVyJSkopwJlzXT07tMoDL5WgX9 +O08KVgDNz9qP/IGtAcRduRcNioH3E9v981QO1zt/Gpb2f8NqAjUUCUZzOnij6mx9 +McZ+9cWX88CRzR0vQODWuZscgI08NvM69Fn2SQIDAQABo2MwYTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUc19g2LzLA5j0Kxc0LjZa +pmD/vB8wHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJKoZIhvcN +AQELBQADggEBAHAG7WTmyjzPRIM85rVj+fWHsLIvqpw6DObIjMWokpliCeMINZFV +ynfgBKsf1ExwbvJNzYFXW6dihnguDG9VMPpi2up/ctQTN8tm9nDKOy08uNZoofMc +NUZxKCEkVKZv+IL4oHoeayt8egtv3ujJM6V14AstMQ6SwvwvA93EP/Ug2e4WAXHu +cbI1NAbUgVDqp+DRdfvZkgYKryjTWd/0+1fS8X1bBZVWzl7eirNVnHbSH2ZDpNuY +0SBd8dj5F6ld3t58ydZbrTHze7JJOd8ijySAp4/kiu9UfZWuTPABzDa/DSdz9Dk/ +zPW4CXXvhLmE02TA9/HeCw3KEHIwicNuEfw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICQ2QwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDUxODQ2 +MjlaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBzYS1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMMvR+ReRnOzqJzoaPipNTt1Z2VA968jlN1+SYKUrYM3No+Vpz0H +M6Tn0oYB66ByVsXiGc28ulsqX1HbHsxqDPwvQTKvO7SrmDokoAkjJgLocOLUAeld +5AwvUjxGRP6yY90NV7X786MpnYb2Il9DIIaV9HjCmPt+rjy2CZjS0UjPjCKNfB8J +bFjgW6GGscjeyGb/zFwcom5p4j0rLydbNaOr9wOyQrtt3ZQWLYGY9Zees/b8pmcc +Jt+7jstZ2UMV32OO/kIsJ4rMUn2r/uxccPwAc1IDeRSSxOrnFKhW3Cu69iB3bHp7 +JbawY12g7zshE4I14sHjv3QoXASoXjx4xgMCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFI1Fc/Ql2jx+oJPgBVYq +ccgP0pQ8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQB4VVVabVp70myuYuZ3vltQIWqSUMhkaTzehMgGcHjMf9iLoZ/I +93KiFUSGnek5cRePyS9wcpp0fcBT3FvkjpUdCjVtdttJgZFhBxgTd8y26ImdDDMR +4+BUuhI5msvjL08f+Vkkpu1GQcGmyFVPFOy/UY8iefu+QyUuiBUnUuEDd49Hw0Fn +/kIPII6Vj82a2mWV/Q8e+rgN8dIRksRjKI03DEoP8lhPlsOkhdwU6Uz9Vu6NOB2Q +Ls1kbcxAc7cFSyRVJEhh12Sz9d0q/CQSTFsVJKOjSNQBQfVnLz1GwO/IieUEAr4C +jkTntH0r1LX5b/GwN4R887LvjAEdTbg1his7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgIDAIkHMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTA2MTc0 +MDIxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh +c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg +U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt +YXpvbiBSRFMgdXMtd2VzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDD2yzbbAl77OofTghDMEf624OvU0eS9O+lsdO0QlbfUfWa1Kd6 +0WkgjkLZGfSRxEHMCnrv4UPBSK/Qwn6FTjkDLgemhqBtAnplN4VsoDL+BkRX4Wwq +/dSQJE2b+0hm9w9UMVGFDEq1TMotGGTD2B71eh9HEKzKhGzqiNeGsiX4VV+LJzdH +uM23eGisNqmd4iJV0zcAZ+Gbh2zK6fqTOCvXtm7Idccv8vZZnyk1FiWl3NR4WAgK +AkvWTIoFU3Mt7dIXKKClVmvssG8WHCkd3Xcb4FHy/G756UZcq67gMMTX/9fOFM/v +l5C0+CHl33Yig1vIDZd+fXV1KZD84dEJfEvHAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBR+ap20kO/6A7pPxo3+ +T3CfqZpQWjAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAHCJky2tPjPttlDM/RIqExupBkNrnSYnOK4kr9xJ3sl8UF2DA +PAnYsjXp3rfcjN/k/FVOhxwzi3cXJF/2Tjj39Bm/OEfYTOJDNYtBwB0VVH4ffa/6 +tZl87jaIkrxJcreeeHqYMnIxeN0b/kliyA+a5L2Yb0VPjt9INq34QDc1v74FNZ17 +4z8nr1nzg4xsOWu0Dbjo966lm4nOYIGBRGOKEkHZRZ4mEiMgr3YLkv8gSmeitx57 +Z6dVemNtUic/LVo5Iqw4n3TBS0iF2C1Q1xT/s3h+0SXZlfOWttzSluDvoMv5PvCd +pFjNn+aXLAALoihL1MJSsxydtsLjOBro5eK0Vw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICOFAwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAxNzQ2 +MjFaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAzU72e6XbaJbi4HjJoRNjKxzUEuChKQIt7k3CWzNnmjc5 +8I1MjCpa2W1iw1BYVysXSNSsLOtUsfvBZxi/1uyMn5ZCaf9aeoA9UsSkFSZBjOCN +DpKPCmfV1zcEOvJz26+1m8WDg+8Oa60QV0ou2AU1tYcw98fOQjcAES0JXXB80P2s +3UfkNcnDz+l4k7j4SllhFPhH6BQ4lD2NiFAP4HwoG6FeJUn45EPjzrydxjq6v5Fc +cQ8rGuHADVXotDbEhaYhNjIrsPL+puhjWfhJjheEw8c4whRZNp6gJ/b6WEes/ZhZ +h32DwsDsZw0BfRDUMgUn8TdecNexHUw8vQWeC181hwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwW9bWgkWkr0U +lrOsq2kvIdrECDgwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAEugF0Gj7HVhX0ehPZoGRYRt3PBuI2YjfrrJRTZ9X5wc +9T8oHmw07mHmNy1qqWvooNJg09bDGfB0k5goC2emDiIiGfc/kvMLI7u+eQOoMKj6 +mkfCncyRN3ty08Po45vTLBFZGUvtQmjM6yKewc4sXiASSBmQUpsMbiHRCL72M5qV +obcJOjGcIdDTmV1BHdWT+XcjynsGjUqOvQWWhhLPrn4jWe6Xuxll75qlrpn3IrIx +CRBv/5r7qbcQJPOgwQsyK4kv9Ly8g7YT1/vYBlR3cRsYQjccw5ceWUj2DrMVWhJ4 +prf+E3Aa4vYmLLOUUvKnDQ1k3RGNu56V0tonsQbfsaM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgICEzUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAyMDUy +MjVaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h +em9uIFJEUyBjYS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAOxHqdcPSA2uBjsCP4DLSlqSoPuQ/X1kkJLusVRKiQE2zayB +viuCBt4VB9Qsh2rW3iYGM+usDjltGnI1iUWA5KHcvHszSMkWAOYWLiMNKTlg6LCp +XnE89tvj5dIH6U8WlDvXLdjB/h30gW9JEX7S8supsBSci2GxEzb5mRdKaDuuF/0O +qvz4YE04pua3iZ9QwmMFuTAOYzD1M72aOpj+7Ac+YLMM61qOtU+AU6MndnQkKoQi +qmUN2A9IFaqHFzRlSdXwKCKUA4otzmz+/N3vFwjb5F4DSsbsrMfjeHMo6o/nb6Nh +YDb0VJxxPee6TxSuN7CQJ2FxMlFUezcoXqwqXD0CAwEAAaNmMGQwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFDGGpon9WfIpsggE +CxHq8hZ7E2ESMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG +SIb3DQEBCwUAA4IBAQAvpeQYEGZvoTVLgV9rd2+StPYykMsmFjWQcyn3dBTZRXC2 +lKq7QhQczMAOhEaaN29ZprjQzsA2X/UauKzLR2Uyqc2qOeO9/YOl0H3qauo8C/W9 +r8xqPbOCDLEXlOQ19fidXyyEPHEq5WFp8j+fTh+s8WOx2M7IuC0ANEetIZURYhSp +xl9XOPRCJxOhj7JdelhpweX0BJDNHeUFi0ClnFOws8oKQ7sQEv66d5ddxqqZ3NVv +RbCvCtEutQMOUMIuaygDlMn1anSM8N7Wndx8G6+Uy67AnhjGx7jw/0YPPxopEj6x +JXP8j0sJbcT9K/9/fPVLNT25RvQ/93T2+IQL4Ca2 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICYpgwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExNzMx +NDhaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMk3YdSZ64iAYp6MyyKtYJtNzv7zFSnnNf6vv0FB4VnfITTMmOyZ +LXqKAT2ahZ00hXi34ewqJElgU6eUZT/QlzdIu359TEZyLVPwURflL6SWgdG01Q5X +O++7fSGcBRyIeuQWs9FJNIIqK8daF6qw0Rl5TXfu7P9dBc3zkgDXZm2DHmxGDD69 +7liQUiXzoE1q2Z9cA8+jirDioJxN9av8hQt12pskLQumhlArsMIhjhHRgF03HOh5 +tvi+RCfihVOxELyIRTRpTNiIwAqfZxxTWFTgfn+gijTmd0/1DseAe82aYic8JbuS +EMbrDduAWsqrnJ4GPzxHKLXX0JasCUcWyMECAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPLtsq1NrwJXO13C9eHt +sLY11AGwMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQAnWBKj5xV1A1mYd0kIgDdkjCwQkiKF5bjIbGkT3YEFFbXoJlSP +0lZZ/hDaOHI8wbLT44SzOvPEEmWF9EE7SJzkvSdQrUAWR9FwDLaU427ALI3ngNHy +lGJ2hse1fvSRNbmg8Sc9GBv8oqNIBPVuw+AJzHTacZ1OkyLZrz1c1QvwvwN2a+Jd +vH0V0YIhv66llKcYDMUQJAQi4+8nbRxXWv6Gq3pvrFoorzsnkr42V3JpbhnYiK+9 +nRKd4uWl62KRZjGkfMbmsqZpj2fdSWMY1UGyN1k+kDmCSWYdrTRDP0xjtIocwg+A +J116n4hV/5mbA0BaPiS2krtv17YAeHABZcvz +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgICV2YwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExOTM2 +MjBaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h +em9uIFJEUyBldS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMEx54X2pHVv86APA0RWqxxRNmdkhAyp2R1cFWumKQRofoFv +n+SPXdkpIINpMuEIGJANozdiEz7SPsrAf8WHyD93j/ZxrdQftRcIGH41xasetKGl +I67uans8d+pgJgBKGb/Z+B5m+UsIuEVekpvgpwKtmmaLFC/NCGuSsJoFsRqoa6Gh +m34W6yJoY87UatddCqLY4IIXaBFsgK9Q/wYzYLbnWM6ZZvhJ52VMtdhcdzeTHNW0 +5LGuXJOF7Ahb4JkEhoo6TS2c0NxB4l4MBfBPgti+O7WjR3FfZHpt18A6Zkq6A2u6 +D/oTSL6c9/3sAaFTFgMyL3wHb2YlW0BPiljZIqECAwEAAaNmMGQwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFOcAToAc6skWffJa +TnreaswAfrbcMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG +SIb3DQEBCwUAA4IBAQA1d0Whc1QtspK496mFWfFEQNegLh0a9GWYlJm+Htcj5Nxt +DAIGXb+8xrtOZFHmYP7VLCT5Zd2C+XytqseK/+s07iAr0/EPF+O2qcyQWMN5KhgE +cXw2SwuP9FPV3i+YAm11PBVeenrmzuk9NrdHQ7TxU4v7VGhcsd2C++0EisrmquWH +mgIfmVDGxphwoES52cY6t3fbnXmTkvENvR+h3rj+fUiSz0aSo+XZUGHPgvuEKM/W +CBD9Smc9CBoBgvy7BgHRgRUmwtABZHFUIEjHI5rIr7ZvYn+6A0O6sogRfvVYtWFc +qpyrW1YX8mD0VlJ8fGKM3G+aCOsiiPKDV/Uafrm+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgICGAcwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIxODE5 +NDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h +em9uIFJEUyBldS1ub3J0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCiIYnhe4UNBbdBb/nQxl5giM0XoVHWNrYV5nB0YukA98+TPn9v +Aoj1RGYmtryjhrf01Kuv8SWO+Eom95L3zquoTFcE2gmxCfk7bp6qJJ3eHOJB+QUO +XsNRh76fwDzEF1yTeZWH49oeL2xO13EAx4PbZuZpZBttBM5zAxgZkqu4uWQczFEs +JXfla7z2fvWmGcTagX10O5C18XaFroV0ubvSyIi75ue9ykg/nlFAeB7O0Wxae88e +uhiBEFAuLYdqWnsg3459NfV8Yi1GnaitTym6VI3tHKIFiUvkSiy0DAlAGV2iiyJE +q+DsVEO4/hSINJEtII4TMtysOsYPpINqeEzRAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRR0UpnbQyjnHChgmOc +hnlc0PogzTAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAKJD4xVzSf4zSGTBJrmamo86jl1NHQxXUApAZuBZEc8tqC6TI +T5CeoSr9CMuVC8grYyBjXblC4OsM5NMvmsrXl/u5C9dEwtBFjo8mm53rOOIm1fxl +I1oYB/9mtO9ANWjkykuLzWeBlqDT/i7ckaKwalhLODsRDO73vRhYNjsIUGloNsKe +pxw3dzHwAZx4upSdEVG4RGCZ1D0LJ4Gw40OfD69hfkDfRVVxKGrbEzqxXRvovmDc +tKLdYZO/6REoca36v4BlgIs1CbUXJGLSXUwtg7YXGLSVBJ/U0+22iGJmBSNcoyUN +cjPFD9JQEhDDIYYKSGzIYpvslvGc4T5ISXFiuQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICZIEwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIyMTMy +MzJaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALGiwqjiF7xIjT0Sx7zB3764K2T2a1DHnAxEOr+/EIftWKxWzT3u +PFwS2eEZcnKqSdRQ+vRzonLBeNLO4z8aLjQnNbkizZMBuXGm4BqRm1Kgq3nlLDQn +7YqdijOq54SpShvR/8zsO4sgMDMmHIYAJJOJqBdaus2smRt0NobIKc0liy7759KB +6kmQ47Gg+kfIwxrQA5zlvPLeQImxSoPi9LdbRoKvu7Iot7SOa+jGhVBh3VdqndJX +7tm/saj4NE375csmMETFLAOXjat7zViMRwVorX4V6AzEg1vkzxXpA9N7qywWIT5Y +fYaq5M8i6vvLg0CzrH9fHORtnkdjdu1y+0MCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFOhOx1yt3Z7mvGB9jBv +2ymdZwiOMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQBehqY36UGDvPVU9+vtaYGr38dBbp+LzkjZzHwKT1XJSSUc2wqM +hnCIQKilonrTIvP1vmkQi8qHPvDRtBZKqvz/AErW/ZwQdZzqYNFd+BmOXaeZWV0Q +oHtDzXmcwtP8aUQpxN0e1xkWb1E80qoy+0uuRqb/50b/R4Q5qqSfJhkn6z8nwB10 +7RjLtJPrK8igxdpr3tGUzfAOyiPrIDncY7UJaL84GFp7WWAkH0WG3H8Y8DRcRXOU +mqDxDLUP3rNuow3jnGxiUY+gGX5OqaZg4f4P6QzOSmeQYs6nLpH0PiN00+oS1BbD +bpWdZEttILPI+vAYkU4QuBKKDjJL6HbSd+cn +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECDCCAvCgAwIBAgIDAIVCMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV +UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE +CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE +UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTEzMTcw +NjQxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh +c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg +U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt +YXpvbiBSRFMgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDE+T2xYjUbxOp+pv+gRA3FO24+1zCWgXTDF1DHrh1lsPg5k7ht +2KPYzNc+Vg4E+jgPiW0BQnA6jStX5EqVh8BU60zELlxMNvpg4KumniMCZ3krtMUC +au1NF9rM7HBh+O+DYMBLK5eSIVt6lZosOb7bCi3V6wMLA8YqWSWqabkxwN4w0vXI +8lu5uXXFRemHnlNf+yA/4YtN4uaAyd0ami9+klwdkZfkrDOaiy59haOeBGL8EB/c +dbJJlguHH5CpCscs3RKtOOjEonXnKXldxarFdkMzi+aIIjQ8GyUOSAXHtQHb3gZ4 +nS6Ey0CMlwkB8vUObZU9fnjKJcL5QCQqOfwvAgMBAAGjZjBkMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQUPuRHohPxx4VjykmH +6usGrLL1ETAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG +9w0BAQsFAAOCAQEAUdR9Vb3y33Yj6X6KGtuthZ08SwjImVQPtknzpajNE5jOJAh8 +quvQnU9nlnMO85fVDU1Dz3lLHGJ/YG1pt1Cqq2QQ200JcWCvBRgdvH6MjHoDQpqZ +HvQ3vLgOGqCLNQKFuet9BdpsHzsctKvCVaeBqbGpeCtt3Hh/26tgx0rorPLw90A2 +V8QSkZJjlcKkLa58N5CMM8Xz8KLWg3MZeT4DmlUXVCukqK2RGuP2L+aME8dOxqNv +OnOz1zrL5mR2iJoDpk8+VE/eBDmJX40IJk6jBjWoxAO/RXq+vBozuF5YHN1ujE92 +tO8HItgTp37XT8bJBAiAnt5mxw+NLSqtxk2QdQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICY4kwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTMyMDEx +NDJaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1zb3V0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAr5u9OuLL/OF/fBNUX2kINJLzFl4DnmrhnLuSeSnBPgbb +qddjf5EFFJBfv7IYiIWEFPDbDG5hoBwgMup5bZDbas+ZTJTotnnxVJTQ6wlhTmns +eHECcg2pqGIKGrxZfbQhlj08/4nNAPvyYCTS0bEcmQ1emuDPyvJBYDDLDU6AbCB5 +6Z7YKFQPTiCBblvvNzchjLWF9IpkqiTsPHiEt21sAdABxj9ityStV3ja/W9BfgxH +wzABSTAQT6FbDwmQMo7dcFOPRX+hewQSic2Rn1XYjmNYzgEHisdUsH7eeXREAcTw +61TRvaLH8AiOWBnTEJXPAe6wYfrcSd1pD0MXpoB62wIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUytwMiomQOgX5 +Ichd+2lDWRUhkikwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBACf6lRDpfCD7BFRqiWM45hqIzffIaysmVfr+Jr+fBTjP +uYe/ba1omSrNGG23bOcT9LJ8hkQJ9d+FxUwYyICQNWOy6ejicm4z0C3VhphbTPqj +yjpt9nG56IAcV8BcRJh4o/2IfLNzC/dVuYJV8wj7XzwlvjysenwdrJCoLadkTr1h +eIdG6Le07sB9IxrGJL9e04afk37h7c8ESGSE4E+oS4JQEi3ATq8ne1B9DQ9SasXi +IRmhNAaISDzOPdyLXi9N9V9Lwe/DHcja7hgLGYx3UqfjhLhOKwp8HtoZORixAmOI +HfILgNmwyugAbuZoCazSKKBhQ0wgO0WZ66ZKTMG8Oho= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICUYkwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxODIx +MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyB1cy13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANCEZBZyu6yJQFZBJmSUZfSZd3Ui2gitczMKC4FLr0QzkbxY+cLa +uVONIOrPt4Rwi+3h/UdnUg917xao3S53XDf1TDMFEYp4U8EFPXqCn/GXBIWlU86P +PvBN+gzw3nS+aco7WXb+woTouvFVkk8FGU7J532llW8o/9ydQyDIMtdIkKTuMfho +OiNHSaNc+QXQ32TgvM9A/6q7ksUoNXGCP8hDOkSZ/YOLiI5TcdLh/aWj00ziL5bj +pvytiMZkilnc9dLY9QhRNr0vGqL0xjmWdoEXz9/OwjmCihHqJq+20MJPsvFm7D6a +2NKybR9U+ddrjb8/iyLOjURUZnj5O+2+OPcCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEBxMBdv81xuzqcK5TVu +pHj+Aor8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQBZkfiVqGoJjBI37aTlLOSjLcjI75L5wBrwO39q+B4cwcmpj58P +3sivv+jhYfAGEbQnGRzjuFoyPzWnZ1DesRExX+wrmHsLLQbF2kVjLZhEJMHF9eB7 +GZlTPdTzHErcnuXkwA/OqyXMpj9aghcQFuhCNguEfnROY9sAoK2PTfnTz9NJHL+Q +UpDLEJEUfc0GZMVWYhahc0x38ZnSY2SKacIPECQrTI0KpqZv/P+ijCEcMD9xmYEb +jL4en+XKS1uJpw5fIU5Sj0MxhdGstH6S84iAE5J3GM3XHklGSFwwqPYvuTXvANH6 +uboynxRgSae59jIlAK6Jrr6GWMwQRbgcaAlW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICEkYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxOTUz +NDdaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1zb3V0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAufodI2Flker8q7PXZG0P0vmFSlhQDw907A6eJuF/WeMo +GHnll3b4S6nC3oRS3nGeRMHbyU2KKXDwXNb3Mheu+ox+n5eb/BJ17eoj9HbQR1cd +gEkIciiAltf8gpMMQH4anP7TD+HNFlZnP7ii3geEJB2GGXSxgSWvUzH4etL67Zmn +TpGDWQMB0T8lK2ziLCMF4XAC/8xDELN/buHCNuhDpxpPebhct0T+f6Arzsiswt2j +7OeNeLLZwIZvVwAKF7zUFjC6m7/VmTQC8nidVY559D6l0UhhU0Co/txgq3HVsMOH +PbxmQUwJEKAzQXoIi+4uZzHFZrvov/nDTNJUhC6DqwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwaZpaCme+EiV +M5gcjeHZSTgOn4owHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAAR6a2meCZuXO2TF9bGqKGtZmaah4pH2ETcEVUjkvXVz +sl+ZKbYjrun+VkcMGGKLUjS812e7eDF726ptoku9/PZZIxlJB0isC/0OyixI8N4M +NsEyvp52XN9QundTjkl362bomPnHAApeU0mRbMDRR2JdT70u6yAzGLGsUwMkoNnw +1VR4XKhXHYGWo7KMvFrZ1KcjWhubxLHxZWXRulPVtGmyWg/MvE6KF+2XMLhojhUL ++9jB3Fpn53s6KMx5tVq1x8PukHmowcZuAF8k+W4gk8Y68wIwynrdZrKRyRv6CVtR +FZ8DeJgoNZT3y/GT254VqMxxfuy2Ccb/RInd16tEvVk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICOYIwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTcyMDA1 +MjlaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMyAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA4dMak8W+XW8y/2F6nRiytFiA4XLwePadqWebGtlIgyCS +kbug8Jv5w7nlMkuxOxoUeD4WhI6A9EkAn3r0REM/2f0aYnd2KPxeqS2MrtdxxHw1 +xoOxk2x0piNSlOz6yog1idsKR5Wurf94fvM9FdTrMYPPrDabbGqiBMsZZmoHLvA3 +Z+57HEV2tU0Ei3vWeGIqnNjIekS+E06KhASxrkNU5vi611UsnYZlSi0VtJsH4UGV +LhnHl53aZL0YFO5mn/fzuNG/51qgk/6EFMMhaWInXX49Dia9FnnuWXwVwi6uX1Wn +7kjoHi5VtmC8ZlGEHroxX2DxEr6bhJTEpcLMnoQMqwIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUsUI5Cb3SWB8+ +gv1YLN/ABPMdxSAwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAJAF3E9PM1uzVL8YNdzb6fwJrxxqI2shvaMVmC1mXS+w +G0zh4v2hBZOf91l1EO0rwFD7+fxoI6hzQfMxIczh875T6vUXePKVOCOKI5wCrDad +zQbVqbFbdhsBjF4aUilOdtw2qjjs9JwPuB0VXN4/jY7m21oKEOcnpe36+7OiSPjN +xngYewCXKrSRqoj3mw+0w/+exYj3Wsush7uFssX18av78G+ehKPIVDXptOCP/N7W +8iKVNeQ2QGTnu2fzWsGUSvMGyM7yqT+h1ILaT//yQS8er511aHMLc142bD4D9VSy +DgactwPDTShK/PXqhvNey9v/sKXm4XatZvwcc8KYlW4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDDCCAvSgAwIBAgICcEUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNjU2 +MjBaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h +em9uIFJEUyBhcC1ub3J0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAndtkldmHtk4TVQAyqhAvtEHSMb6pLhyKrIFved1WO3S7 ++I+bWwv9b2W/ljJxLq9kdT43bhvzonNtI4a1LAohS6bqyirmk8sFfsWT3akb+4Sx +1sjc8Ovc9eqIWJCrUiSvv7+cS7ZTA9AgM1PxvHcsqrcUXiK3Jd/Dax9jdZE1e15s +BEhb2OEPE+tClFZ+soj8h8Pl2Clo5OAppEzYI4LmFKtp1X/BOf62k4jviXuCSst3 +UnRJzE/CXtjmN6oZySVWSe0rQYuyqRl6//9nK40cfGKyxVnimB8XrrcxUN743Vud +QQVU0Esm8OVTX013mXWQXJHP2c0aKkog8LOga0vobQIDAQABo2YwZDAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQULmoOS1mFSjj+ +snUPx4DgS3SkLFYwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ +KoZIhvcNAQELBQADggEBAAkVL2P1M2/G9GM3DANVAqYOwmX0Xk58YBHQu6iiQg4j +b4Ky/qsZIsgT7YBsZA4AOcPKQFgGTWhe9pvhmXqoN3RYltN8Vn7TbUm/ZVDoMsrM +gwv0+TKxW1/u7s8cXYfHPiTzVSJuOogHx99kBW6b2f99GbP7O1Sv3sLq4j6lVvBX +Fiacf5LAWC925nvlTzLlBgIc3O9xDtFeAGtZcEtxZJ4fnGXiqEnN4539+nqzIyYq +nvlgCzyvcfRAxwltrJHuuRu6Maw5AGcd2Y0saMhqOVq9KYKFKuD/927BTrbd2JVf +2sGWyuPZPCk3gq+5pCjbD0c6DkhcMGI6WwxvM5V/zSM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICJDQwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNzAz +MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyBldS13ZXN0LTMgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL9bL7KE0n02DLVtlZ2PL+g/BuHpMYFq2JnE2RgompGurDIZdjmh +1pxfL3nT+QIVMubuAOy8InRfkRxfpxyjKYdfLJTPJG+jDVL+wDcPpACFVqoV7Prg +pVYEV0lc5aoYw4bSeYFhdzgim6F8iyjoPnObjll9mo4XsHzSoqJLCd0QC+VG9Fw2 +q+GDRZrLRmVM2oNGDRbGpGIFg77aRxRapFZa8SnUgs2AqzuzKiprVH5i0S0M6dWr +i+kk5epmTtkiDHceX+dP/0R1NcnkCPoQ9TglyXyPdUdTPPRfKCq12dftqll+u4mV +ARdN6WFjovxax8EAP2OAUTi1afY+1JFMj+sCAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLfhrbrO5exkCVgxW0x3 +Y2mAi8lNMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQAigQ5VBNGyw+OZFXwxeJEAUYaXVoP/qrhTOJ6mCE2DXUVEoJeV +SxScy/TlFA9tJXqmit8JH8VQ/xDL4ubBfeMFAIAo4WzNWDVoeVMqphVEcDWBHsI1 +AETWzfsapRS9yQekOMmxg63d/nV8xewIl8aNVTHdHYXMqhhik47VrmaVEok1UQb3 +O971RadLXIEbVd9tjY5bMEHm89JsZDnDEw1hQXBb67Elu64OOxoKaHBgUH8AZn/2 +zFsL1ynNUjOhCSAA15pgd1vjwc0YsBbAEBPcHBWYBEyME6NLNarjOzBl4FMtATSF +wWCKRGkvqN8oxYhwR2jf2rR5Mu4DWkK5Q8Ep +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEBzCCAu+gAwIBAgICJVUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTkxODE2 +NTNaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz +aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT +ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h +em9uIFJEUyB1cy1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAM3i/k2u6cqbMdcISGRvh+m+L0yaSIoOXjtpNEoIftAipTUYoMhL +InXGlQBVA4shkekxp1N7HXe1Y/iMaPEyb3n+16pf3vdjKl7kaSkIhjdUz3oVUEYt +i8Z/XeJJ9H2aEGuiZh3kHixQcZczn8cg3dA9aeeyLSEnTkl/npzLf//669Ammyhs +XcAo58yvT0D4E0D/EEHf2N7HRX7j/TlyWvw/39SW0usiCrHPKDLxByLojxLdHzso +QIp/S04m+eWn6rmD+uUiRteN1hI5ncQiA3wo4G37mHnUEKo6TtTUh+sd/ku6a8HK +glMBcgqudDI90s1OpuIAWmuWpY//8xEG2YECAwEAAaNmMGQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPqhoWZcrVY9mU7tuemR +RBnQIj1jMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 +DQEBCwUAA4IBAQB6zOLZ+YINEs72heHIWlPZ8c6WY8MDU+Be5w1M+BK2kpcVhCUK +PJO4nMXpgamEX8DIiaO7emsunwJzMSvavSPRnxXXTKIc0i/g1EbiDjnYX9d85DkC +E1LaAUCmCZBVi9fIe0H2r9whIh4uLWZA41oMnJx/MOmo3XyMfQoWcqaSFlMqfZM4 +0rNoB/tdHLNuV4eIdaw2mlHxdWDtF4oH+HFm+2cVBUVC1jXKrFv/euRVtsTT+A6i +h2XBHKxQ1Y4HgAn0jACP2QSPEmuoQEIa57bEKEcZsBR8SDY6ZdTd2HLRIApcCOSF +MRM8CKLeF658I0XgF8D5EsYoKPsA+74Z+jDH +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJAM2ZN/+nPi27MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBhZi1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkxMDI4MTgwNTU4WhcNMjQxMDI2MTgwNTU4WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgYWYtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR2351uPMZaJk2gMGT+1sk8HE9MQh2rc +/sCnbxGn2p1c7Oi9aBbd/GiFijeJb2BXvHU+TOq3d3Jjqepq8tapXVt4ojbTJNyC +J5E7r7KjTktKdLxtBE1MK25aY+IRJjtdU6vG3KiPKUT1naO3xs3yt0F76WVuFivd +9OHv2a+KHvPkRUWIxpmAHuMY9SIIMmEZtVE7YZGx5ah0iO4JzItHcbVR0y0PBH55 +arpFBddpIVHCacp1FUPxSEWkOpI7q0AaU4xfX0fe1BV5HZYRKpBOIp1TtZWvJD+X +jGUtL1BEsT5vN5g9MkqdtYrC+3SNpAk4VtpvJrdjraI/hhvfeXNnAwIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUEEi/ +WWMcBJsoGXg+EZwkQ0MscZQwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0Ms +cZQwDQYJKoZIhvcNAQELBQADggEBAGDZ5js5Pc/gC58LJrwMPXFhJDBS8QuDm23C +FFUdlqucskwOS3907ErK1ZkmVJCIqFLArHqskFXMAkRZ2PNR7RjWLqBs+0znG5yH +hRKb4DXzhUFQ18UBRcvT6V6zN97HTRsEEaNhM/7k8YLe7P8vfNZ28VIoJIGGgv9D +wQBBvkxQ71oOmAG0AwaGD0ORGUfbYry9Dz4a4IcUsZyRWRMADixgrFv6VuETp26s +/+z+iqNaGWlELBKh3iQCT6Y/1UnkPLO42bxrCSyOvshdkYN58Q2gMTE1SVTqyo8G +Lw8lLAz9bnvUSgHzB3jRrSx6ggF/WRMRYlR++y6LXP4SAsSAaC0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw +MjgxODA2NTNaFw0yNDEwMjgxODA2NTNaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBhZi1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAvtV1OqmFa8zCVQSKOvPUJERLVFtd4rZmDpImc5rIoeBk7w/P +9lcKUJjO8R/w1a2lJXx3oQ81tiY0Piw6TpT62YWVRMWrOw8+Vxq1dNaDSFp9I8d0 +UHillSSbOk6FOrPDp+R6AwbGFqUDebbN5LFFoDKbhNmH1BVS0a6YNKpGigLRqhka +cClPslWtPqtjbaP3Jbxl26zWzLo7OtZl98dR225pq8aApNBwmtgA7Gh60HK/cX0t +32W94n8D+GKSg6R4MKredVFqRTi9hCCNUu0sxYPoELuM+mHiqB5NPjtm92EzCWs+ ++vgWhMc6GxG+82QSWx1Vj8sgLqtE/vLrWddf5QIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuLB4gYVJrSKJj/Gz +pqc6yeA+RcAwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0MscZQwDQYJKoZI +hvcNAQELBQADggEBABauYOZxUhe9/RhzGJ8MsWCz8eKcyDVd4FCnY6Qh+9wcmYNT +LtnD88LACtJKb/b81qYzcB0Em6+zVJ3Z9jznfr6buItE6es9wAoja22Xgv44BTHL +rimbgMwpTt3uEMXDffaS0Ww6YWb3pSE0XYI2ISMWz+xRERRf+QqktSaL39zuiaW5 +tfZMre+YhohRa/F0ZQl3RCd6yFcLx4UoSPqQsUl97WhYzwAxZZfwvLJXOc4ATt3u +VlCUylNDkaZztDJc/yN5XQoK9W5nOt2cLu513MGYKbuarQr8f+gYU8S+qOyuSRSP +NRITzwCRVnsJE+2JmcRInn/NcanB7uOGqTvJ9+c= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEEjCCAvqgAwIBAgIJAJYM4LxvTZA6MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi +MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h +em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBldS1zb3V0aC0xIFJvb3QgQ0Ew +HhcNMTkxMDMwMjAyMDM2WhcNMjQxMDI4MjAyMDM2WjCBlTELMAkGA1UEBhMCVVMx +EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM +GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx +JjAkBgNVBAMMHUFtYXpvbiBSRFMgZXUtc291dGgtMSBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqM921jXCXeqpRNCS9CBPOe5N7gMaEt+D +s5uR3riZbqzRlHGiF1jZihkXfHAIQewDwy+Yz+Oec1aEZCQMhUHxZJPusuX0cJfj +b+UluFqHIijL2TfXJ3D0PVLLoNTQJZ8+GAPECyojAaNuoHbdVqxhOcznMsXIXVFq +yVLKDGvyKkJjai/iSPDrQMXufg3kWt0ISjNLvsG5IFXgP4gttsM8i0yvRd4QcHoo +DjvH7V3cS+CQqW5SnDrGnHToB0RLskE1ET+oNOfeN9PWOxQprMOX/zmJhnJQlTqD +QP7jcf7SddxrKFjuziFiouskJJyNDsMjt1Lf60+oHZhed2ogTeifGwIDAQABo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUFBAF +cgJe/BBuZiGeZ8STfpkgRYQwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkg +RYQwDQYJKoZIhvcNAQELBQADggEBAKAYUtlvDuX2UpZW9i1QgsjFuy/ErbW0dLHU +e/IcFtju2z6RLZ+uF+5A8Kme7IKG1hgt8s+w9TRVQS/7ukQzoK3TaN6XKXRosjtc +o9Rm4gYWM8bmglzY1TPNaiI4HC7546hSwJhubjN0bXCuj/0sHD6w2DkiGuwKNAef +yTu5vZhPkeNyXLykxkzz7bNp2/PtMBnzIp+WpS7uUDmWyScGPohKMq5PqvL59z+L +ZI3CYeMZrJ5VpXUg3fNNIz/83N3G0sk7wr0ohs/kHTP7xPOYB0zD7Ku4HA0Q9Swf +WX0qr6UQgTPMjfYDLffI7aEId0gxKw1eGYc6Cq5JAZ3ipi/cBFc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT +MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK +DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT +MSYwJAYDVQQDDB1BbWF6b24gUkRTIGV1LXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw +MzAyMDIxMzBaFw0yNDEwMzAyMDIxMzBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u +IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE +AwwYQW1hem9uIFJEUyBldS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAtEyjYcajx6xImJn8Vz1zjdmL4ANPgQXwF7+tF7xccmNAZETb +bzb3I9i5fZlmrRaVznX+9biXVaGxYzIUIR3huQ3Q283KsDYnVuGa3mk690vhvJbB +QIPgKa5mVwJppnuJm78KqaSpi0vxyCPe3h8h6LLFawVyWrYNZ4okli1/U582eef8 +RzJp/Ear3KgHOLIiCdPDF0rjOdCG1MOlDLixVnPn9IYOciqO+VivXBg+jtfc5J+L +AaPm0/Yx4uELt1tkbWkm4BvTU/gBOODnYziITZM0l6Fgwvbwgq5duAtKW+h031lC +37rEvrclqcp4wrsUYcLAWX79ZyKIlRxcAdvEhQIDAQABo2YwZDAOBgNVHQ8BAf8E +BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU7zPyc0azQxnBCe7D +b9KAadH1QSEwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkgRYQwDQYJKoZI +hvcNAQELBQADggEBAFGaNiYxg7yC/xauXPlaqLCtwbm2dKyK9nIFbF/7be8mk7Q3 +MOA0of1vGHPLVQLr6bJJpD9MAbUcm4cPAwWaxwcNpxOjYOFDaq10PCK4eRAxZWwF +NJRIRmGsl8NEsMNTMCy8X+Kyw5EzH4vWFl5Uf2bGKOeFg0zt43jWQVOX6C+aL3Cd +pRS5MhmYpxMG8irrNOxf4NVFE2zpJOCm3bn0STLhkDcV/ww4zMzObTJhiIb5wSWn +EXKKWhUXuRt7A2y1KJtXpTbSRHQxE++69Go1tWhXtRiULCJtf7wF2Ksm0RR/AdXT +1uR1vKyH5KBJPX3ppYkQDukoHTFR0CpB+G84NLo= +-----END CERTIFICATE----- diff --git a/target/classes/repositories/AccountRepo.class b/target/classes/repositories/AccountRepo.class deleted file mode 100644 index 2152e09fb..000000000 Binary files a/target/classes/repositories/AccountRepo.class and /dev/null differ diff --git a/target/classes/repositories/LoginRepo.class b/target/classes/repositories/LoginRepo.class deleted file mode 100644 index 55dcba0a2..000000000 Binary files a/target/classes/repositories/LoginRepo.class and /dev/null differ diff --git a/target/classes/repositories/TransactionRepo.class b/target/classes/repositories/TransactionRepo.class deleted file mode 100644 index c146fdf91..000000000 Binary files a/target/classes/repositories/TransactionRepo.class and /dev/null differ diff --git a/target/classes/repositories/UserRepo.class b/target/classes/repositories/UserRepo.class deleted file mode 100644 index aa68c0c08..000000000 Binary files a/target/classes/repositories/UserRepo.class and /dev/null differ diff --git a/target/classes/runner/AppRunner.class b/target/classes/runner/AppRunner.class new file mode 100644 index 000000000..64ec98a6f Binary files /dev/null and b/target/classes/runner/AppRunner.class differ diff --git a/target/classes/runner/controllers/AccountController.class b/target/classes/runner/controllers/AccountController.class new file mode 100644 index 000000000..9661df613 Binary files /dev/null and b/target/classes/runner/controllers/AccountController.class differ diff --git a/target/classes/runner/controllers/CustomerController.class b/target/classes/runner/controllers/CustomerController.class new file mode 100644 index 000000000..8381292bf Binary files /dev/null and b/target/classes/runner/controllers/CustomerController.class differ diff --git a/target/classes/runner/controllers/LoginController.class b/target/classes/runner/controllers/LoginController.class new file mode 100644 index 000000000..6eb211c35 Binary files /dev/null and b/target/classes/runner/controllers/LoginController.class differ diff --git a/target/classes/runner/controllers/TestHomePageDeleteLater.class b/target/classes/runner/controllers/TestHomePageDeleteLater.class new file mode 100644 index 000000000..28b1b04ca Binary files /dev/null and b/target/classes/runner/controllers/TestHomePageDeleteLater.class differ diff --git a/target/classes/runner/controllers/TransactionController.class b/target/classes/runner/controllers/TransactionController.class new file mode 100644 index 000000000..fa6c5824b Binary files /dev/null and b/target/classes/runner/controllers/TransactionController.class differ diff --git a/target/classes/runner/entities/Account.class b/target/classes/runner/entities/Account.class new file mode 100644 index 000000000..035e17ac6 Binary files /dev/null and b/target/classes/runner/entities/Account.class differ diff --git a/target/classes/runner/entities/Address.class b/target/classes/runner/entities/Address.class new file mode 100644 index 000000000..ca5525cd9 Binary files /dev/null and b/target/classes/runner/entities/Address.class differ diff --git a/target/classes/runner/entities/Checking.class b/target/classes/runner/entities/Checking.class new file mode 100644 index 000000000..ba06d6336 Binary files /dev/null and b/target/classes/runner/entities/Checking.class differ diff --git a/target/classes/runner/entities/Customer.class b/target/classes/runner/entities/Customer.class new file mode 100644 index 000000000..7671f3f28 Binary files /dev/null and b/target/classes/runner/entities/Customer.class differ diff --git a/target/classes/runner/entities/Investment.class b/target/classes/runner/entities/Investment.class new file mode 100644 index 000000000..53e0d1e57 Binary files /dev/null and b/target/classes/runner/entities/Investment.class differ diff --git a/target/classes/runner/entities/Login.class b/target/classes/runner/entities/Login.class new file mode 100644 index 000000000..38285ed03 Binary files /dev/null and b/target/classes/runner/entities/Login.class differ diff --git a/target/classes/runner/entities/Savings.class b/target/classes/runner/entities/Savings.class new file mode 100644 index 000000000..ba045a470 Binary files /dev/null and b/target/classes/runner/entities/Savings.class differ diff --git a/target/classes/runner/entities/Transaction.class b/target/classes/runner/entities/Transaction.class new file mode 100644 index 000000000..cbc40e447 Binary files /dev/null and b/target/classes/runner/entities/Transaction.class differ diff --git a/target/classes/runner/enums/AccountType.class b/target/classes/runner/enums/AccountType.class new file mode 100644 index 000000000..165a9687d Binary files /dev/null and b/target/classes/runner/enums/AccountType.class differ diff --git a/target/classes/runner/repositories/AccountRepo.class b/target/classes/runner/repositories/AccountRepo.class new file mode 100644 index 000000000..eec041cc2 Binary files /dev/null and b/target/classes/runner/repositories/AccountRepo.class differ diff --git a/target/classes/runner/repositories/CustomerRepo.class b/target/classes/runner/repositories/CustomerRepo.class new file mode 100644 index 000000000..056cc5528 Binary files /dev/null and b/target/classes/runner/repositories/CustomerRepo.class differ diff --git a/target/classes/runner/repositories/LoginRepo.class b/target/classes/runner/repositories/LoginRepo.class new file mode 100644 index 000000000..ab6bf78bf Binary files /dev/null and b/target/classes/runner/repositories/LoginRepo.class differ diff --git a/target/classes/runner/repositories/TransactionRepo.class b/target/classes/runner/repositories/TransactionRepo.class new file mode 100644 index 000000000..db217d53f Binary files /dev/null and b/target/classes/runner/repositories/TransactionRepo.class differ diff --git a/target/classes/runner/security/config/WebSecurityConfig$1.class b/target/classes/runner/security/config/WebSecurityConfig$1.class new file mode 100644 index 000000000..8f222988c Binary files /dev/null and b/target/classes/runner/security/config/WebSecurityConfig$1.class differ diff --git a/target/classes/runner/security/config/WebSecurityConfig.class b/target/classes/runner/security/config/WebSecurityConfig.class new file mode 100644 index 000000000..8019643ec Binary files /dev/null and b/target/classes/runner/security/config/WebSecurityConfig.class differ diff --git a/target/classes/runner/security/controllers/AuthenticationController.class b/target/classes/runner/security/controllers/AuthenticationController.class new file mode 100644 index 000000000..8f4ba3e68 Binary files /dev/null and b/target/classes/runner/security/controllers/AuthenticationController.class differ diff --git a/target/classes/runner/security/filters/JwtAuthorizationFilter.class b/target/classes/runner/security/filters/JwtAuthorizationFilter.class new file mode 100644 index 000000000..0854b94d1 Binary files /dev/null and b/target/classes/runner/security/filters/JwtAuthorizationFilter.class differ diff --git a/target/classes/runner/security/models/AuthenticationResponse.class b/target/classes/runner/security/models/AuthenticationResponse.class new file mode 100644 index 000000000..c1f805011 Binary files /dev/null and b/target/classes/runner/security/models/AuthenticationResponse.class differ diff --git a/target/classes/runner/security/utilities/JwtUtil.class b/target/classes/runner/security/utilities/JwtUtil.class new file mode 100644 index 000000000..269583f6d Binary files /dev/null and b/target/classes/runner/security/utilities/JwtUtil.class differ diff --git a/target/classes/runner/services/AccountServices.class b/target/classes/runner/services/AccountServices.class new file mode 100644 index 000000000..197e7839f Binary files /dev/null and b/target/classes/runner/services/AccountServices.class differ diff --git a/target/classes/runner/services/CustomerServices.class b/target/classes/runner/services/CustomerServices.class new file mode 100644 index 000000000..7196e8a1b Binary files /dev/null and b/target/classes/runner/services/CustomerServices.class differ diff --git a/target/classes/runner/services/LoginServices.class b/target/classes/runner/services/LoginServices.class new file mode 100644 index 000000000..335b7023b Binary files /dev/null and b/target/classes/runner/services/LoginServices.class differ diff --git a/target/classes/runner/services/TransactionServices.class b/target/classes/runner/services/TransactionServices.class new file mode 100644 index 000000000..bbf5933b6 Binary files /dev/null and b/target/classes/runner/services/TransactionServices.class differ diff --git a/target/classes/runner/services/UserDetailServices.class b/target/classes/runner/services/UserDetailServices.class new file mode 100644 index 000000000..f1beb489c Binary files /dev/null and b/target/classes/runner/services/UserDetailServices.class differ diff --git a/target/classes/runner/views/Views$AccountActions.class b/target/classes/runner/views/Views$AccountActions.class new file mode 100644 index 000000000..9eea03fa7 Binary files /dev/null and b/target/classes/runner/views/Views$AccountActions.class differ diff --git a/target/classes/runner/views/Views$AccountDetails.class b/target/classes/runner/views/Views$AccountDetails.class new file mode 100644 index 000000000..ab15cd14f Binary files /dev/null and b/target/classes/runner/views/Views$AccountDetails.class differ diff --git a/target/classes/runner/views/Views$AccountNumber.class b/target/classes/runner/views/Views$AccountNumber.class new file mode 100644 index 000000000..e1a6befdc Binary files /dev/null and b/target/classes/runner/views/Views$AccountNumber.class differ diff --git a/target/classes/runner/views/Views$AccountOpening.class b/target/classes/runner/views/Views$AccountOpening.class new file mode 100644 index 000000000..7b441f291 Binary files /dev/null and b/target/classes/runner/views/Views$AccountOpening.class differ diff --git a/target/classes/runner/views/Views$AccountSpecific.class b/target/classes/runner/views/Views$AccountSpecific.class new file mode 100644 index 000000000..25328011d Binary files /dev/null and b/target/classes/runner/views/Views$AccountSpecific.class differ diff --git a/target/classes/runner/views/Views$AccountType.class b/target/classes/runner/views/Views$AccountType.class new file mode 100644 index 000000000..bec16886c Binary files /dev/null and b/target/classes/runner/views/Views$AccountType.class differ diff --git a/target/classes/runner/views/Views$Address.class b/target/classes/runner/views/Views$Address.class new file mode 100644 index 000000000..3e3d188de Binary files /dev/null and b/target/classes/runner/views/Views$Address.class differ diff --git a/target/classes/runner/views/Views$AllAccounts.class b/target/classes/runner/views/Views$AllAccounts.class new file mode 100644 index 000000000..2afd089a2 Binary files /dev/null and b/target/classes/runner/views/Views$AllAccounts.class differ diff --git a/target/classes/runner/views/Views$Email.class b/target/classes/runner/views/Views$Email.class new file mode 100644 index 000000000..7a871efc1 Binary files /dev/null and b/target/classes/runner/views/Views$Email.class differ diff --git a/target/classes/runner/views/Views$PhoneNumber.class b/target/classes/runner/views/Views$PhoneNumber.class new file mode 100644 index 000000000..660f91a58 Binary files /dev/null and b/target/classes/runner/views/Views$PhoneNumber.class differ diff --git a/target/classes/runner/views/Views$Profile.class b/target/classes/runner/views/Views$Profile.class new file mode 100644 index 000000000..b8929cffc Binary files /dev/null and b/target/classes/runner/views/Views$Profile.class differ diff --git a/target/classes/runner/views/Views$RoutingNumber.class b/target/classes/runner/views/Views$RoutingNumber.class new file mode 100644 index 000000000..e05ed754e Binary files /dev/null and b/target/classes/runner/views/Views$RoutingNumber.class differ diff --git a/target/classes/runner/views/Views.class b/target/classes/runner/views/Views.class new file mode 100644 index 000000000..e67495d15 Binary files /dev/null and b/target/classes/runner/views/Views.class differ diff --git a/target/classes/services/AccountServices.class b/target/classes/services/AccountServices.class deleted file mode 100644 index aeca95dc3..000000000 Binary files a/target/classes/services/AccountServices.class and /dev/null differ diff --git a/target/classes/services/LoginServices.class b/target/classes/services/LoginServices.class deleted file mode 100644 index 1a624af1a..000000000 Binary files a/target/classes/services/LoginServices.class and /dev/null differ diff --git a/target/classes/services/TransactionServices.class b/target/classes/services/TransactionServices.class deleted file mode 100644 index 7972de76b..000000000 Binary files a/target/classes/services/TransactionServices.class and /dev/null differ diff --git a/target/classes/services/UserServices.class b/target/classes/services/UserServices.class deleted file mode 100644 index ca3be5afa..000000000 Binary files a/target/classes/services/UserServices.class and /dev/null differ diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 000000000..52a1debf6 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=FullStack.MicroWebApplication-Server +groupId=groupId +version=1.0-SNAPSHOT diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 000000000..78bc8c233 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,39 @@ +runner/enums/AccountType.class +runner/repositories/AccountRepo.class +runner/repositories/LoginRepo.class +runner/controllers/CustomerController.class +runner/entities/Transaction.class +runner/security/controllers/AuthenticationController.class +runner/views/Views$AccountSpecific.class +runner/services/AccountServices.class +runner/controllers/TestHomePageDeleteLater.class +runner/views/Views$PhoneNumber.class +runner/views/Views$AccountActions.class +runner/views/Views.class +runner/AppRunner.class +runner/security/config/WebSecurityConfig.class +runner/views/Views$AccountDetails.class +runner/controllers/TransactionController.class +runner/views/Views$Email.class +runner/entities/Login.class +runner/repositories/TransactionRepo.class +runner/repositories/CustomerRepo.class +runner/views/Views$AccountType.class +runner/entities/Address.class +runner/security/utilities/JwtUtil.class +runner/views/Views$Profile.class +runner/services/LoginServices.class +runner/controllers/AccountController.class +runner/entities/Investment.class +runner/services/TransactionServices.class +runner/entities/Customer.class +runner/controllers/LoginController.class +runner/services/CustomerServices.class +runner/security/filters/JwtAuthorizationFilter.class +runner/views/Views$AccountNumber.class +runner/entities/Checking.class +runner/entities/Account.class +runner/views/Views$Address.class +runner/views/Views$AllAccounts.class +runner/entities/Savings.class +runner/security/models/AuthenticationResponse.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 000000000..beb375fe6 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,29 @@ +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/security/controllers/AuthenticationController.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/controllers/TestHomePageDeleteLater.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/repositories/TransactionRepo.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/enums/AccountType.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/controllers/CustomerController.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Investment.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/services/TransactionServices.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/repositories/CustomerRepo.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/controllers/AccountController.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/controllers/TransactionController.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/controllers/LoginController.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/security/utilities/JwtUtil.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Customer.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/repositories/AccountRepo.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/views/Views.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Savings.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/security/filters/JwtAuthorizationFilter.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/services/LoginServices.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/security/config/WebSecurityConfig.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Account.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/services/CustomerServices.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/repositories/LoginRepo.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/services/AccountServices.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Transaction.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/security/models/AuthenticationResponse.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Checking.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/AppRunner.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Address.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/main/java/runner/entities/Login.java diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 000000000..7004bd28b --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1,9 @@ +runner/configuration/CustomerServiceTestConfiguration.class +runner/security/JwtTest.class +runner/controllers/CustomerControllerTest.class +runner/controllers/AccountControllerTest.class +runner/services/CustomerServiceTest.class +runner/entities/AccountEntityTest.class +runner/configuration/AccountServiceTestConfiguration.class +runner/services/AccountServiceTest.class +runner/entities/CustomerEntityTest.class diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 000000000..4724d8dcf --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1,9 @@ +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/controllers/AccountControllerTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/services/CustomerServiceTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/entities/AccountEntityTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/services/AccountServiceTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/entities/CustomerEntityTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/configuration/CustomerServiceTestConfiguration.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/controllers/CustomerControllerTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/security/JwtTest.java +/Users/gunjan/Dev/FullStack.MicroWebApplication-Server/src/test/java/runner/configuration/AccountServiceTestConfiguration.java diff --git a/target/test-classes/runner/configuration/AccountServiceTestConfiguration.class b/target/test-classes/runner/configuration/AccountServiceTestConfiguration.class new file mode 100644 index 000000000..f2c67c3d5 Binary files /dev/null and b/target/test-classes/runner/configuration/AccountServiceTestConfiguration.class differ diff --git a/target/test-classes/runner/configuration/CustomerServiceTestConfiguration.class b/target/test-classes/runner/configuration/CustomerServiceTestConfiguration.class new file mode 100644 index 000000000..84bb4f833 Binary files /dev/null and b/target/test-classes/runner/configuration/CustomerServiceTestConfiguration.class differ diff --git a/target/test-classes/runner/controllers/AccountControllerTest.class b/target/test-classes/runner/controllers/AccountControllerTest.class new file mode 100644 index 000000000..bffcf71cb Binary files /dev/null and b/target/test-classes/runner/controllers/AccountControllerTest.class differ diff --git a/target/test-classes/runner/controllers/CustomerControllerTest.class b/target/test-classes/runner/controllers/CustomerControllerTest.class new file mode 100644 index 000000000..3d2d77074 Binary files /dev/null and b/target/test-classes/runner/controllers/CustomerControllerTest.class differ diff --git a/target/test-classes/runner/entities/AccountEntityTest.class b/target/test-classes/runner/entities/AccountEntityTest.class new file mode 100644 index 000000000..deae30da3 Binary files /dev/null and b/target/test-classes/runner/entities/AccountEntityTest.class differ diff --git a/target/test-classes/runner/entities/CustomerEntityTest.class b/target/test-classes/runner/entities/CustomerEntityTest.class new file mode 100644 index 000000000..baeaa1142 Binary files /dev/null and b/target/test-classes/runner/entities/CustomerEntityTest.class differ diff --git a/target/test-classes/runner/security/JwtTest.class b/target/test-classes/runner/security/JwtTest.class new file mode 100644 index 000000000..93726e066 Binary files /dev/null and b/target/test-classes/runner/security/JwtTest.class differ diff --git a/target/test-classes/runner/services/AccountServiceTest.class b/target/test-classes/runner/services/AccountServiceTest.class new file mode 100644 index 000000000..40c518141 Binary files /dev/null and b/target/test-classes/runner/services/AccountServiceTest.class differ diff --git a/target/test-classes/runner/services/CustomerServiceTest.class b/target/test-classes/runner/services/CustomerServiceTest.class new file mode 100644 index 000000000..8e0d5a0d4 Binary files /dev/null and b/target/test-classes/runner/services/CustomerServiceTest.class differ diff --git a/target/test-classes/runner/services/TransactionServicesTest.class b/target/test-classes/runner/services/TransactionServicesTest.class new file mode 100644 index 000000000..943152d62 Binary files /dev/null and b/target/test-classes/runner/services/TransactionServicesTest.class differ