diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6161bf863 --- /dev/null +++ b/.gitignore @@ -0,0 +1,562 @@ + +# Created by https://www.gitignore.io/api/eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio +# Edit at https://www.gitignore.io/?templates=eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +target +target/ +target/* +*.iml +.idea +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### NetBeans ### +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### NotepadPP ### +# Notepad++ backups # + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# End of https://www.gitignore.io/api/eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio diff --git a/MyREADME.md b/MyREADME.md new file mode 100644 index 000000000..30b897957 --- /dev/null +++ b/MyREADME.md @@ -0,0 +1,78 @@ +# Fired Chat Web APplication +> A web TCP full stack application that clients can send and recieve messages. + +[![NPM Version][npm-image]][npm-url] +[![Build Status][travis-image]][travis-url] +[![Downloads Stats][npm-downloads]][npm-url] + +Fired is a small full stack web application that enables it's users to chat with other clients. The application allows users to post on board without signing up. + +![](header.png) + +## How to Access Fired + +Safari, Chrome, Firfox: + +```sh +Andriod, Install from Android app store +``` + +iOs: + +```sh +install from appstore +``` + +## Usage example + +A few motivating and useful examples of how your product can be used. Spice this up with code blocks and potentially more screenshots. + +_For more examples and usage, please refer to the [Wiki][wiki]._ + +## Development setup + +Describe how to install all development dependencies and how to run an automated test-suite of some kind. Potentially do this for multiple platforms. + +```sh +make install +npm test +``` + +## Release History + +* 0.2.1 + * CHANGE: Update docs (module code remains unchanged) +* 0.2.0 + * CHANGE: Remove `setDefaultXYZ()` + * ADD: Add `init()` +* 0.1.1 + * FIX: Crash when calling `baz()` (Thanks @GenerousContributorName!) +* 0.1.0 + * The first proper release + * CHANGE: Rename `foo()` to `bar()` +* 0.0.1 + * Work in progress + +## Meta + +Emmanuel Orubele – [@YourTwitter](https://twitter.com/####) – emmanuel.orubele@gmail.com + +Distributed under the Orubele.Inc license. See ``LICENSE`` for more information. + +[https://github.com/da7tysixers/](https://github.com/dbader/) + +## Contributing + +1. Fork it () +2. Create your feature branch (`git checkout -b feature/fooBar`) +3. Commit your changes (`git commit -am 'Add some fooBar'`) +4. Push to the branch (`git push origin feature/fooBar`) +5. Create a new Pull Request + + +[npm-image]: https://img.shields.io/npm/v/datadog-metrics.svg?style=flat-square +[npm-url]: https://npmjs.org/package/datadog-metrics +[npm-downloads]: https://img.shields.io/npm/dm/datadog-metrics.svg?style=flat-square +[travis-image]: https://img.shields.io/travis/dbader/node-datadog-metrics/master.svg?style=flat-square +[travis-url]: https://travis-ci.org/dbader/node-datadog-metrics +[wiki]: https://github.com/yourname/yourproject/wiki diff --git a/README.md b/README.md index 8cdfa1bdd..41de4aec2 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,67 @@ # Full Stack Web Application - * **Objective** - to create an implementation of a web service * **Purpose** - to demonstrate the construction of a full-stacked web-application * **Description** - * This Case Study is your first foray into building a full-stack application. You'll be building a Spring MVC based application, which means you'll learn about what it takes to build a functional application from the ground up yourself. - * This is exciting! It's a lot, but we've given you the tools to be able to build what you need, and you get to decide what you do with it. You also get to be creative in choosing what sort of application you want to build! - * You will be working individually to design your app. We hope you'll exercise creativity on this project, sketch some wireframes before you start, make sure you have time to run these ideas by your instructors to get their feedback before you dive too deep into coding! Remember to keep things small and focus on mastering the fundamentals. + * This Case Study is my first foray into building a full-stack application. I was able to demonstrate how to use Spring MVC to develop a simple todo-list web application. + * This project was exciting! Thanks to my classmates, my instructor (Leon Hunter), for all the learning and applying what I've learned into building something amazing. + * UML Diagram of my classes: + ![](./pic/caseStudyUML.png) + + * **Additional Resources** - * [The Original Case Study Document](./case-study.pdf) * [Case Study Outline](./case-study-outline.pdf) - * [Case Study Deliverables](./README_deliverables.md) * [Identifying Plagiarism](./README_plagiarism.md) - * [Suggested Project Topics](./README_suggested-project-topics.md) + * [Reference and Credits](./README_Reference.md) -## Minimum Features -* `RESTful` web service which consumes requests from a front-end web application and caches each request and the respective response to a database. +## User Requirement to run this web Application +* This web application is not deployed yet. Please check back from time to time to see updates and deployment to AWS (Amazon Web Services). * The application must support a login functionality. -## Developmental Notes +## Software Specifications Notes -### Tech Stack Selection -* Select at least 1 technology from each of the following categories: +### Required +* I advise that you make install each of the following technologies to ensure that the program works smoothly: * **Version Control System** - 1. Github - 2. Bitbucket + 1.Must have a Java SDK, JRE installed + 2. Must have Maven installed on PC. + 3. Optional to install Spring Boot CLI (Command Line Tool) + 4. Optional have an IDE (Integrated Development Environment) or go with option 3. - * **Wireframe** - 1. Mockflow - 2. Balsamiq + * **Languages and Tools Used To Develop This Program** + 1. Java + 2. SQL (H2 Database) 3. Lucidcharts - - * **Frontend** - 1. Java Server Pages + 4. Java Server Pages + 5. Spring MVC + 6. HTML5, CSS, JavaScript, BootStrap + 7. Trello Board [a link](https://trello.com/invite/b/pwHfeBUk/9a907e606482ebb03b85ff3d62005e69/todo-list-web-application) + + * **How To Run The Application** + 1. Fork the project and download the file as zip. + 2. Open with Intellij or using any other IDE. + 3. Run as springboot application. - * **Business Logic** - 1. Java - 2. TypeScript - - * **WebServer Implementation** - 1. Spring Boot - 2. At least 1 [backing service](https://12factor.net/backing-services) API + * **Web Link** + 1. On your web browser type localhost:8080/home or click this link [Access Site](localhost:8080/home) + 2. The home page will open. + ![](./pic/pics1.png) + 3. From the home page click signup to get access to the todo-list web application + ![](./pic/pics2.png) + 4. On your home page you can create a todo-list. + ![](./pic/pics5.png) + 5. You can add as many list as you want and manage it. + 6. The web application is also mobile responsive. Please try it on chrome to get the best experience. + ![](./pic/mobile.png) - * **Data Layer** - 1. MySQL - 2. PostgreSQL - 3. MariaDB - - * **Web Server Cloud Deployment** - 1. Heroku - 2. AWS EC2 Instance - * **Web Application Cloud Deployment** - 1. Netlify - 2. AWS EC2 Instance - -### Installation -* It is advised that you make install each of the following technologies to ensure that are at least accessible - * Install [NodeJs](https://nodejs.org/en/). - * Install [Angular](http://angular.io/). - * Install [AngularCli](https://cli.angular.io/). +### Note +* It is advised that you please report any issues you encounter with the application so I can rectify the issue. +* Thank you for using my application. It means so much to me for developing my first ever application. \ No newline at end of file diff --git a/README_Reference.md b/README_Reference.md new file mode 100644 index 000000000..9c02df872 --- /dev/null +++ b/README_Reference.md @@ -0,0 +1,27 @@ +# Reference +* **Reference** + * This Case Study is my first foray into building a full-stack application. I was able to demonstrate how to use Spring MVC to develop a simple todo-list web application. + * This project was exciting! Thanks to my classmates, my instructor (Leon Hunter), for all the learning and applying what I've learned into building something amazing. + + * MDBootStrap + * © 2020 Copyright: MDBootstrap.com + * https://getbootstrap.com/docs/4.0/examples/cover/ + + * Stack Overflow + * https://stackoverflow.com/questions/8781558/neither-bindingresult-nor-plain-target-object-for-bean-name-available-as-request + + * GetBootstrap + * https://getbootstrap.com/docs/4.0/components/navbar/#nav + + * PerScholas + * PerScholas BootCamp: Instructor: Leon Hunter + + * Pixels Pictures Used + * https://www.pexels.com/photo/white-printer-paper-beside-silver-laptop-computer-4101346/ + + * Todo Management Tutorial: Author: Ramesh Fadatare , 2018 + * Java-Guide Spring MVC(javaguide.net/2018/09/mini-todo-management-project-using-spring-boot) + + # I want to send all my gratitude to all my classmate + # that made it possible for me to be better at software development + # You guys are the best. I learned a lot from each and everyone of you. \ No newline at end of file diff --git a/README_deliverables.md b/README_deliverables.md deleted file mode 100644 index 4bb20a97f..000000000 --- a/README_deliverables.md +++ /dev/null @@ -1,52 +0,0 @@ -## Deliverables - -### Trello Board -* To begin your case study, create a Trello board -* Please ensure the instructor has access to this Trello board. -* This board will be used to track progress and evaluate required effort of tasks. -* Ensure the board has at least 5 columns accounting for each of the following - * `Ideation` - * This column will first contain cards describing a potential application to be built. - * Upon concept approval, this column will be re-purposed to describe potential features of the approved application. - * `Backlog` - * This column will contain cards describing work that **will not be** done in a near-future, but **must be done** eventually for the product to be considered completed - * `Upcoming` - * This column will contain cards describing work that **will not be** done in the current-sprint commitment, but **will be committed to** in the upcoming-sprint commitment. - * `Current` - * This column will contain cards describing work that **will be** done in the current-sprint commitment. - * `In Review - * This column will contain cards describing work that **need to be reviewed** to be considered **done**. - * `Completed` - * This column will contain cards describing work that has been reviewed and is considered completed - -### Database -* MariaDB is the suggested dialect -* This deliverable includes creating a database that reflects the website you have decided to create -* Schema diagram: a visual representation of your database -* Database file creation (`.sql`): Queries used to create the database - - -### Core Java & JPA -* This deliverable includes creating a back-end environment that is composed of different Java classes - * Models: Java classes that represent an entity and are used to transfer data related to an entity, create multiple queries, and represent the database as an object-oriented model - * Persistence.xml: This file configures the Java classes that are going to be using JPA to interact with the database. - * Persistence Java Class: A static class that allows the application to create a persistent object which can be used to interact with the database. - * Service Class or Data Access Objects (DAO): Java classes that are composed of one or more functions and have direct access to the database by using JPA persistent object. Each function in a DAO class interacts with the database differently. - * Custom Exceptions: Java classes that allow you to describe an error while the application is running. - * Utilizes: Java classes that hold constant variables (Variables that never change from its initial value). The value of these variables can be requested parameters, Database queries used in the DAO, name of HTML pages, or URL patterns to forward a request to. - - -### HTML5/CSS3 -* This deliverable includes creating every page required by the given case study -* HTML5: Use HTML for static and dynamic pages and markup the structure of every page. -* CSS3: Use CSS3 to style your HTML pages and make sure to take into consideration the knowledge acquired from the visual design lessons. - - -### Spring MVC -* This deliverable includes connecting no. 1, 2 and 3 deliverables to function together - * Spring MVC: Responsible for responding to a request made by the user. This can be login, registration, etc. When using Spring MVC make sure to use at least the following functionalities: different type of session management, annotation-based controller, exception handling, models, model attributes. - - -### Junit (Test all DAO classes) -* This deliverable includes creating a test class for each DAO available and creating a test case in the test class for each function inside the DAO - * Junit: A Java framework responsible for performing unit testing against every DAO class available. There should be a test class for every DAO and inside the test classes, there should be at least one test case for every function inside the DAO classes. When using JUnit make sure to use the following functionalities: Suite classes, Runner, Feature life cycle, Test, Parameterized classes, Java Hamcrest library. diff --git a/README_suggested-project-topics.md b/README_suggested-project-topics.md deleted file mode 100644 index 9b2ac965e..000000000 --- a/README_suggested-project-topics.md +++ /dev/null @@ -1,54 +0,0 @@ - -## Suggested Project Topics - -### (Suggested Project Topic 1) 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 - -
- - - - - -### (Suggested Project Topic 2) 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 - -
- - - - - -### (Suggested Project Topic 3) 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 - - - - - -### (Suggested Project Topic 4) Money Management Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can create new accounts - * deposit money to each account - * withdrawl money from each account - * transfer money to and from any 2 accounts diff --git a/caseStudy.ucls b/caseStudy.ucls new file mode 100644 index 000000000..466993308 --- /dev/null +++ b/caseStudy.ucls @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kill-8080.bat b/kill-8080.bat new file mode 100644 index 000000000..44b34ddda --- /dev/null +++ b/kill-8080.bat @@ -0,0 +1 @@ +for /f "tokens=5" %%a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %%a \ No newline at end of file diff --git a/kill-8080.sh b/kill-8080.sh new file mode 100644 index 000000000..2198716e0 --- /dev/null +++ b/kill-8080.sh @@ -0,0 +1 @@ +kill -kill `lsof -t -i tcp:8080` diff --git a/pic/caseStudyUML.png b/pic/caseStudyUML.png new file mode 100644 index 000000000..4b0a2465f Binary files /dev/null and b/pic/caseStudyUML.png differ diff --git a/pic/mobile.png b/pic/mobile.png new file mode 100644 index 000000000..61cd3ca9e Binary files /dev/null and b/pic/mobile.png differ diff --git a/pic/pics1.png b/pic/pics1.png new file mode 100644 index 000000000..8684f118c Binary files /dev/null and b/pic/pics1.png differ diff --git a/pic/pics2.png b/pic/pics2.png new file mode 100644 index 000000000..8c1a550c3 Binary files /dev/null and b/pic/pics2.png differ diff --git a/pic/pics5.png b/pic/pics5.png new file mode 100644 index 000000000..947df5044 Binary files /dev/null and b/pic/pics5.png differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..a5eecd48c --- /dev/null +++ b/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + SpringBootSampleWebApp + 0.0.1-SNAPSHOT + jar + Curriculeon SpringBoot JSP Login Page + Demo project for Spring Boot With Login JSP View + + org.springframework.boot + spring-boot-starter-parent + 2.1.2.RELEASE + + + + UTF-8 + UTF-8 + 1.8 + + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.data + spring-data-jpa + + + javax.servlet + jstl + + + + org.apache.tomcat.embed + tomcat-embed-jasper + + + + org.eclipse.jdt.core.compiler + ecj + 4.6.1 + + + org.webjars + jquery + 3.4.0 + + + org.webjars + bootstrap-datepicker + 1.9.0 + + + org.webjars + bootstrap + 4.5.2 + + + junit + junit + 4.12 + test + + + org.springframework.security + spring-security-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/src/main/java/com/github/curriculeon/MainApplication.java b/src/main/java/com/github/curriculeon/MainApplication.java new file mode 100644 index 000000000..93877b366 --- /dev/null +++ b/src/main/java/com/github/curriculeon/MainApplication.java @@ -0,0 +1,11 @@ +package com.github.curriculeon; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MainApplication { + public static void main(String[] args) { + SpringApplication.run(MainApplication.class, args); + } +} diff --git a/src/main/java/com/github/curriculeon/MyObject.java b/src/main/java/com/github/curriculeon/MyObject.java new file mode 100644 index 000000000..2301f17e8 --- /dev/null +++ b/src/main/java/com/github/curriculeon/MyObject.java @@ -0,0 +1,7 @@ +package com.github.curriculeon; + +public class MyObject implements Runnable { + public void run() { + // TODO + } +} diff --git a/src/main/java/com/github/curriculeon/config/WebSecurityConfig.java b/src/main/java/com/github/curriculeon/config/WebSecurityConfig.java new file mode 100644 index 000000000..66f5b6974 --- /dev/null +++ b/src/main/java/com/github/curriculeon/config/WebSecurityConfig.java @@ -0,0 +1,54 @@ +package com.github.curriculeon.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private UserDetailsService userDetailsService; + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/home").permitAll() + .antMatchers("/resources/**", "/registration").permitAll() + .anyRequest().authenticated() + .and() + .formLogin().defaultSuccessUrl("/resources/**") + .loginPage("/login") + .permitAll() + .and() + .logout() + .permitAll(); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .parentAuthenticationManager(authenticationManagerBean()) + .userDetailsService(userDetailsService) + .passwordEncoder(bCryptPasswordEncoder()); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/curriculeon/controller/ErrorController.java b/src/main/java/com/github/curriculeon/controller/ErrorController.java new file mode 100644 index 000000000..61c6961be --- /dev/null +++ b/src/main/java/com/github/curriculeon/controller/ErrorController.java @@ -0,0 +1,22 @@ +package com.github.curriculeon.controller; + + +import org.springframework.stereotype.Controller; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; + +@Controller("error") +public class ErrorController { + public ModelAndView handleException(HttpServletRequest request, Exception ex){ + ModelAndView modelAndView = new ModelAndView(); + + modelAndView.addObject("exception", ex.getLocalizedMessage()); + modelAndView.addObject("url", request.getRequestURL()); + + modelAndView.setViewName("error"); + + return modelAndView; + } + +} diff --git a/src/main/java/com/github/curriculeon/controller/TodoController.java b/src/main/java/com/github/curriculeon/controller/TodoController.java new file mode 100644 index 000000000..62c70a6e6 --- /dev/null +++ b/src/main/java/com/github/curriculeon/controller/TodoController.java @@ -0,0 +1,98 @@ +package com.github.curriculeon.controller; + + +import com.github.curriculeon.model.Todo; +import com.github.curriculeon.service.TodoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.propertyeditors.CustomDateEditor; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.validation.Valid; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Controller +public class TodoController { + + @Autowired + private TodoService todoService; + + @InitBinder + public void initBinder(WebDataBinder binder){ + // Date - dd/mm/yyyy + SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); + binder.registerCustomEditor(Date.class, + new CustomDateEditor(dateFormat,false)); + } + + @RequestMapping(value = "/list-todos", method = RequestMethod.GET) + public String showTodo(ModelMap model) { + String name = getLoggedInUserName(model); + model.put("todos",todoService.getTodoByUser(name)); + // model insert to do service + return "list-todos"; + } + + private String getLoggedInUserName(ModelMap model) { + Object principal = SecurityContextHolder + .getContext() + .getAuthentication() + .getPrincipal(); + if (principal instanceof UserDetails){ + return ((UserDetails) principal).getUsername(); + } + + return principal.toString(); + } + + @RequestMapping(value = "/add-todo", method = RequestMethod.GET) + public String showAddTodoPage(ModelMap model){ + model.addAttribute("todo", new Todo()); + return "todo"; + } + + @RequestMapping(value = "/delete-todo", method = RequestMethod.GET) + public String deleteTodo(@RequestParam long id){ + todoService.deleteTodo(id); + return "redirect:/list-todos"; + } + + @RequestMapping(value = "/update-todo", method = RequestMethod.GET) + public String showUpdateTodoPage(@RequestParam long id, ModelMap model){ + Todo todo = todoService.getTodoById(id).get(); + model.put("todo", todo); + return "todo"; + } + + @RequestMapping(value = "/update-todo", method = RequestMethod.POST) + public String updateTodo(ModelMap model, @Valid Todo todo, BindingResult result){ + + if (result.hasErrors()) { + return "todo"; + } + + todo.setUserName(getLoggedInUserName(model)); + todoService.updateTodo(todo); + return "redirect:/list-todos"; + } + + @RequestMapping(value = "/add-todo", method = RequestMethod.POST) + public String addTodo(ModelMap model, @Valid Todo todo, BindingResult result){ + if (result.hasErrors()){ + return "todo"; + } + todo.setUserName(getLoggedInUserName(model)); + todoService.saveTodo(todo); + return "redirect:/list-todos"; + } + +} diff --git a/src/main/java/com/github/curriculeon/controller/UserProfileController.java b/src/main/java/com/github/curriculeon/controller/UserProfileController.java new file mode 100644 index 000000000..defc71b53 --- /dev/null +++ b/src/main/java/com/github/curriculeon/controller/UserProfileController.java @@ -0,0 +1,67 @@ +package com.github.curriculeon.controller; + +import com.github.curriculeon.model.UserProfile; +import com.github.curriculeon.service.SecurityServiceImpl; +import com.github.curriculeon.service.UserProfileService; +import com.github.curriculeon.validator.UserProfileValidator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +@Controller +public class UserProfileController { + private UserProfileService userService; + private SecurityServiceImpl securityService; + private UserProfileValidator userValidator; + + @Autowired + public UserProfileController(UserProfileService userService, UserProfileValidator userValidator, SecurityServiceImpl securityService) { + this.userService = userService; + this.userValidator = userValidator; + this.securityService = securityService; + } + + @GetMapping(value = "/registration") + public String registration(Model model) { + model.addAttribute("userForm", new UserProfile()); + return "registration"; + } + + @PostMapping(value = "/registration") + public String registration(@ModelAttribute("userForm") UserProfile userForm, BindingResult bindingResult, Model model) { + userValidator.validate(userForm, bindingResult); + if (bindingResult.hasErrors()) { + return "registration"; + } + userService.save(userForm); + securityService.autologin(userForm.getUsername(), userForm.getPasswordConfirm()); + return "redirect:/welcome"; + } + + // recently added + @GetMapping("/home") + public String getView(Model model) { + model.addAttribute("msg", "Hello there, This message has been injected from the controller method"); + return "home"; + } + + @GetMapping(value = "/login") + public String login(Model model, String error, String logout) { + if (error != null) { + model.addAttribute("error", "Your username and password are invalid."); + } + if (logout != null) { + model.addAttribute("message", "You have logged out successfully."); + } + + return "login"; + } + + @GetMapping(value = {"/", "/welcome"}) + public String welcome(Model model) { + return "welcome"; + } +} diff --git a/src/main/java/com/github/curriculeon/model/Todo.java b/src/main/java/com/github/curriculeon/model/Todo.java new file mode 100644 index 000000000..89c4975b1 --- /dev/null +++ b/src/main/java/com/github/curriculeon/model/Todo.java @@ -0,0 +1,64 @@ +package com.github.curriculeon.model; + + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.util.Date; + +@Entity +@Table(name = "todo_list") +public class Todo { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + private String userName; + + @Size(min = 10, message = "Enter at least 10 Characters...") + private String description; + + private Date targetDate; + + public Todo(){ + super(); + } + + public Todo(String userName,String description, Date targetDate, boolean isDone) { + super(); + this.userName = userName; + this.description = description; + this.targetDate = targetDate; + } + + 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 getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getTargetDate() { + return targetDate; + } + + public void setTargetDate(Date targetDate) { + this.targetDate = targetDate; + } +} diff --git a/src/main/java/com/github/curriculeon/model/UserProfile.java b/src/main/java/com/github/curriculeon/model/UserProfile.java new file mode 100644 index 000000000..833c836c2 --- /dev/null +++ b/src/main/java/com/github/curriculeon/model/UserProfile.java @@ -0,0 +1,60 @@ +package com.github.curriculeon.model; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class UserProfile { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String username; + private String password; + + @Transient // don't persist; not a column + private String passwordConfirm; + + @ManyToMany + @ElementCollection + private List userRoles; + + 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 String getPasswordConfirm() { + return passwordConfirm; + } + + public void setPasswordConfirm(String passwordConfirm) { + this.passwordConfirm = passwordConfirm; + } + + public List getUserRoles() { + return userRoles; + } + + public void setUserRoles(List userRoles) { + this.userRoles = userRoles; + } +} diff --git a/src/main/java/com/github/curriculeon/model/UserProfileRole.java b/src/main/java/com/github/curriculeon/model/UserProfileRole.java new file mode 100644 index 000000000..2838c81d7 --- /dev/null +++ b/src/main/java/com/github/curriculeon/model/UserProfileRole.java @@ -0,0 +1,44 @@ +package com.github.curriculeon.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class UserProfileRole { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; + + @JsonIgnore + @ManyToMany + @ElementCollection + private List users; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } +} diff --git a/src/main/java/com/github/curriculeon/repository/TodoRepository.java b/src/main/java/com/github/curriculeon/repository/TodoRepository.java new file mode 100644 index 000000000..d4132d77a --- /dev/null +++ b/src/main/java/com/github/curriculeon/repository/TodoRepository.java @@ -0,0 +1,11 @@ +package com.github.curriculeon.repository; + +import com.github.curriculeon.model.Todo; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface TodoRepository extends JpaRepository { + + List findByUserName(String user); +} diff --git a/src/main/java/com/github/curriculeon/repository/UserProfileRepository.java b/src/main/java/com/github/curriculeon/repository/UserProfileRepository.java new file mode 100644 index 000000000..ae6bc3828 --- /dev/null +++ b/src/main/java/com/github/curriculeon/repository/UserProfileRepository.java @@ -0,0 +1,8 @@ +package com.github.curriculeon.repository; + +import com.github.curriculeon.model.UserProfile; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserProfileRepository extends JpaRepository { + UserProfile findByUsername(String username); +} diff --git a/src/main/java/com/github/curriculeon/repository/UserProfileRoleRepository.java b/src/main/java/com/github/curriculeon/repository/UserProfileRoleRepository.java new file mode 100644 index 000000000..552c67eb3 --- /dev/null +++ b/src/main/java/com/github/curriculeon/repository/UserProfileRoleRepository.java @@ -0,0 +1,8 @@ +package com.github.curriculeon.repository; + + +import com.github.curriculeon.model.UserProfileRole; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserProfileRoleRepository extends JpaRepository { +} diff --git a/src/main/java/com/github/curriculeon/service/ITodoService.java b/src/main/java/com/github/curriculeon/service/ITodoService.java new file mode 100644 index 000000000..44866d319 --- /dev/null +++ b/src/main/java/com/github/curriculeon/service/ITodoService.java @@ -0,0 +1,21 @@ +package com.github.curriculeon.service; + +import com.github.curriculeon.model.Todo; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +public interface ITodoService { + List getTodoByUser(String user); + + Optional getTodoById(long id); + + void updateTodo(Todo todo); + + void addTodo(String name, String desc, Date targetDate, boolean isDone); + + void deleteTodo(long id); + + void saveTodo(Todo todo); +} diff --git a/src/main/java/com/github/curriculeon/service/SecurityServiceImpl.java b/src/main/java/com/github/curriculeon/service/SecurityServiceImpl.java new file mode 100644 index 000000000..fbe42fd48 --- /dev/null +++ b/src/main/java/com/github/curriculeon/service/SecurityServiceImpl.java @@ -0,0 +1,46 @@ +package com.github.curriculeon.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +@Service +public class SecurityServiceImpl { + private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); + private AuthenticationManager authenticationManager; + + private UserDetailsService userDetailsService; + + @Autowired + public SecurityServiceImpl(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) { + this.authenticationManager = authenticationManager; + this.userDetailsService = userDetailsService; + } + + public String findLoggedInUsername() { + Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails(); + if (userDetails instanceof UserDetails) { + return ((UserDetails) userDetails).getUsername(); + } + + return null; + } + + public void autologin(String username, String password) { + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); + + authenticationManager.authenticate(usernamePasswordAuthenticationToken); + + if (usernamePasswordAuthenticationToken.isAuthenticated()) { + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + logger.debug(String.format("Auto login %s successfully!", username)); + } + } +} diff --git a/src/main/java/com/github/curriculeon/service/TodoService.java b/src/main/java/com/github/curriculeon/service/TodoService.java new file mode 100644 index 000000000..2c1c52955 --- /dev/null +++ b/src/main/java/com/github/curriculeon/service/TodoService.java @@ -0,0 +1,52 @@ +package com.github.curriculeon.service; + + +import com.github.curriculeon.model.Todo; +import com.github.curriculeon.repository.TodoRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +@Service +public class TodoService implements ITodoService { + + @Autowired + private TodoRepository repository; + + @Override + public List getTodoByUser(String user){ + return repository.findByUserName(user); + } + + @Override + public Optional getTodoById(long id){ + return repository.findById(id); + } + + @Override + public void updateTodo(Todo todo){ + repository.save(todo); + } + + @Override + public void addTodo(String name, String desc, Date targetDate, boolean isDone){ + repository.save(new Todo(name, desc, targetDate, isDone)); + } + + @Override + public void deleteTodo(long id){ + Optional todo = repository.findById(id); + if (todo.isPresent()){ + repository.delete(todo.get()); + } + } + + @Override + public void saveTodo(Todo todo){ + repository.save(todo); + } + +} diff --git a/src/main/java/com/github/curriculeon/service/UserProfileService.java b/src/main/java/com/github/curriculeon/service/UserProfileService.java new file mode 100644 index 000000000..e278f01fa --- /dev/null +++ b/src/main/java/com/github/curriculeon/service/UserProfileService.java @@ -0,0 +1,51 @@ +package com.github.curriculeon.service; + +import com.github.curriculeon.model.UserProfile; +import com.github.curriculeon.repository.UserProfileRoleRepository; +import com.github.curriculeon.repository.UserProfileRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +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 org.springframework.transaction.annotation.Transactional; + +import java.util.HashSet; +import java.util.Set; + +@Service +public class UserProfileService implements UserDetailsService { + private UserProfileRepository userRepository; + private UserProfileRoleRepository roleRepository; + private BCryptPasswordEncoder bCryptPasswordEncoder; + + @Autowired + public UserProfileService(UserProfileRepository userRepository, UserProfileRoleRepository roleRepository, BCryptPasswordEncoder bCryptPasswordEncoder) { + this.userRepository = userRepository; + this.roleRepository = roleRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @Override + @Transactional(readOnly = true) + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserProfile user = userRepository.findByUsername(username); + Set grantedAuthorities = new HashSet<>(); + user.getUserRoles().forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()))); + return new User(user.getUsername(), user.getPassword(), grantedAuthorities); + } + + public void save(UserProfile user) { + user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); + user.setUserRoles(roleRepository.findAll()); + userRepository.save(user); + } + + public UserProfile findByUsername(String username) { + return userRepository.findByUsername(username); + } +} diff --git a/src/main/java/com/github/curriculeon/validator/UserProfileValidator.java b/src/main/java/com/github/curriculeon/validator/UserProfileValidator.java new file mode 100644 index 000000000..50b95b417 --- /dev/null +++ b/src/main/java/com/github/curriculeon/validator/UserProfileValidator.java @@ -0,0 +1,42 @@ +package com.github.curriculeon.validator; + +import com.github.curriculeon.model.UserProfile; +import com.github.curriculeon.service.UserProfileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +@Component +public class UserProfileValidator implements Validator { + @Autowired + private UserProfileService userService; + + @Override + public boolean supports(Class aClass) { + return UserProfile.class.equals(aClass); + } + + @Override + public void validate(Object o, Errors errors) { + UserProfile user = (UserProfile) o; + + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "NotEmpty"); + if (user.getUsername().length() < 6 || user.getUsername().length() > 32) { + errors.rejectValue("username", "Size.userForm.username"); + } + if (userService.findByUsername(user.getUsername()) != null) { + errors.rejectValue("username", "Duplicate.userForm.username"); + } + + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty"); + if (user.getPassword().length() < 8 || user.getPassword().length() > 32) { + errors.rejectValue("password", "Size.userForm.password"); + } + + if (!user.getPasswordConfirm().equals(user.getPassword())) { + errors.rejectValue("passwordConfirm", "Diff.userForm.passwordConfirm"); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 000000000..d790e93bf --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,13 @@ +spring.mvc.view.prefix: / +spring.mvc.view.suffix: .jsp +spring.messages.basename=validation + +spring.datasource.username=root +spring.datasource.password=root + +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=update diff --git a/src/main/resources/validation.properties b/src/main/resources/validation.properties new file mode 100644 index 000000000..9309bdf06 --- /dev/null +++ b/src/main/resources/validation.properties @@ -0,0 +1,5 @@ +NotEmpty=This field is required. +Size.userForm.username=Username require between 6 and 32 characters. +Duplicate.userForm.username=Someone is already using this username. +Size.userForm.password=Passwords require at least 8 characters. +Diff.userForm.passwordConfirm=These passwords do not match. \ No newline at end of file diff --git a/src/main/webapp/error.jsp b/src/main/webapp/error.jsp new file mode 100644 index 000000000..6aad14e95 --- /dev/null +++ b/src/main/webapp/error.jsp @@ -0,0 +1,15 @@ + + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + Error + +
+ An exception occurred! Please technical support! +
+ + + \ No newline at end of file diff --git a/src/main/webapp/footer.jsp b/src/main/webapp/footer.jsp new file mode 100644 index 000000000..6ae9806f9 --- /dev/null +++ b/src/main/webapp/footer.jsp @@ -0,0 +1,90 @@ + + + + + + + + + +
+ + + + + + + + + +
+ + + \ No newline at end of file diff --git a/src/main/webapp/head_common.jsp b/src/main/webapp/head_common.jsp new file mode 100644 index 000000000..75d200b79 --- /dev/null +++ b/src/main/webapp/head_common.jsp @@ -0,0 +1,17 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> +<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/head_files.jsp b/src/main/webapp/head_files.jsp new file mode 100644 index 000000000..9c9626c3c --- /dev/null +++ b/src/main/webapp/head_files.jsp @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/home.jsp b/src/main/webapp/home.jsp new file mode 100644 index 000000000..3de54aaef --- /dev/null +++ b/src/main/webapp/home.jsp @@ -0,0 +1,89 @@ +<%@taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%> + + + + + Todo List + + + + + + + + +
+
+
+
+ +
+
+

Create Ideas

+

Welcome to Todowey a place to create and save your ideas.Todowey is a special place where your can put down your ideas or list of thing in writing to learn more click below.

+

Learn more »

+
+
+ +
+ + +
+
+ checklist +

Checklist

+

Create a checklist for your daily task. Todowey comes with call the tools your need to make a list. Set a deadline and review your list. Create, delete, upate your list on the go.

+

Learn More »

+
+
+ list +

List

+

You can create a list for your team, friends, family, or for yourself and manage item from anywhere. Set a date for tasks. Review your tasks. Set deadline for personal projects.

+

Learn More »

+
+
+ ideas +

Ideas

+

Be creative! Save your ideas and track the progess of every single task you have. Write your goals using Todowey and accomplish all of your goals with ease. No limits in creating ideas.

+

Learn More »

+
+
+ + +
+ +
+
+
+ + + diff --git a/src/main/webapp/list-todos.jsp b/src/main/webapp/list-todos.jsp new file mode 100644 index 000000000..441d40659 --- /dev/null +++ b/src/main/webapp/list-todos.jsp @@ -0,0 +1,120 @@ +<%@ include file="head_common.jsp"%> +<%@ include file="head_files.jsp"%> +<%@ include file="navigation.jsp"%> + + My Account + +
+
+ Add Todo +
+
+
+
+

Lists of Todo

+
+
+ + + + + + + + + + + + + + + + + + +
DescriptionTarget Date
${todo.description}Update + Delete
+
+
+ +
+ + + +
+ + + + + + + + + +
diff --git a/src/main/webapp/login.jsp b/src/main/webapp/login.jsp new file mode 100644 index 000000000..ccce5f0c8 --- /dev/null +++ b/src/main/webapp/login.jsp @@ -0,0 +1,35 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + Log in with your account + + + +
+
+
+ + + +
+
+
+ diff --git a/src/main/webapp/navigation.jsp b/src/main/webapp/navigation.jsp new file mode 100644 index 000000000..bc0317cd4 --- /dev/null +++ b/src/main/webapp/navigation.jsp @@ -0,0 +1,37 @@ + + + diff --git a/src/main/webapp/registration.jsp b/src/main/webapp/registration.jsp new file mode 100644 index 000000000..a4e886276 --- /dev/null +++ b/src/main/webapp/registration.jsp @@ -0,0 +1,46 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + Create an account + + + +
+
+
+ + + +
+
+
+ diff --git a/src/main/webapp/resources/css/color.css b/src/main/webapp/resources/css/color.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/webapp/resources/css/login.css b/src/main/webapp/resources/css/login.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/webapp/resources/css/style.css b/src/main/webapp/resources/css/style.css new file mode 100644 index 000000000..b6ae2e598 --- /dev/null +++ b/src/main/webapp/resources/css/style.css @@ -0,0 +1,108 @@ +body { + margin: 0; + font-family: 'Montserrat', "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 15px; + padding-top: 50px; + padding-bottom: 50px; + background-color: #efefef; + color: #2b2b2b; +} +.form-heading { + text-align: center; + text-transform: uppercase; +} +.form-signin { + max-width: 360px; + padding: 15px; + margin: 0 auto; +} +.form-signin .form-control { + position: relative; + height: auto; + padding: 10px; + font-size: 15px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.form-signin .form-control:focus { + z-index: 3; +} +.form-signin input, .form-signin button { + margin-top: 10px; +} +.form-signin .form-signin-heading, .form-signin .checkbox { + margin-bottom: 10px; +} +.form-signin .checkbox { + font-weight: normal; +} +.has-error { + color: #ff0000; + line-height: 1; + font-size: 14px; +} + + +/* Google Fonts*/ + +@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&display=swap'); + + +.mybtn { + text-decoration: none!important; + display: inline-block; + font-size: 1em; + font-family: montserrat, sans-serif; + font-weight: 700; + padding: 1em 2em; + color: #ffffff; + border-radius: 40px; + margin-bottom: 1em; +} + +.mybtn:hover { + color: white; + -webkit-transform: scale(1.05); + transform: scale(1.05); +} + + + +.home-content .button-content { + text-decoration: none!important; + text-align: center; + margin-left: auto; + margin-right: auto; + margin-top: 20px; +} + +.selector-for-some-widget { + box-sizing: content-box; +} + +.logo { + height: 70px; + width: 90px; + margin-top: -30px; + +} + +.nav{ + margin-top: -60px; +} + +.navbar{ + margin-top: -60px; +} + + +/* Navbar*/ + + + + + + + diff --git a/src/main/webapp/resources/img/checklist.jpg b/src/main/webapp/resources/img/checklist.jpg new file mode 100644 index 000000000..1a684713d Binary files /dev/null and b/src/main/webapp/resources/img/checklist.jpg differ diff --git a/src/main/webapp/resources/img/creater.jpg b/src/main/webapp/resources/img/creater.jpg new file mode 100644 index 000000000..233819abd Binary files /dev/null and b/src/main/webapp/resources/img/creater.jpg differ diff --git a/src/main/webapp/resources/img/ideas.jpg b/src/main/webapp/resources/img/ideas.jpg new file mode 100644 index 000000000..bda47e119 Binary files /dev/null and b/src/main/webapp/resources/img/ideas.jpg differ diff --git a/src/main/webapp/resources/img/list.jpg b/src/main/webapp/resources/img/list.jpg new file mode 100644 index 000000000..ba6c778e3 Binary files /dev/null and b/src/main/webapp/resources/img/list.jpg differ diff --git a/src/main/webapp/resources/img/squares.png b/src/main/webapp/resources/img/squares.png new file mode 100644 index 000000000..d3cf0e5df Binary files /dev/null and b/src/main/webapp/resources/img/squares.png differ diff --git a/src/main/webapp/resources/img/todoweylist.png b/src/main/webapp/resources/img/todoweylist.png new file mode 100644 index 000000000..3aff95c73 Binary files /dev/null and b/src/main/webapp/resources/img/todoweylist.png differ diff --git a/src/main/webapp/resources/img/writing-smiley.gif b/src/main/webapp/resources/img/writing-smiley.gif new file mode 100644 index 000000000..651351f6c Binary files /dev/null and b/src/main/webapp/resources/img/writing-smiley.gif differ diff --git a/src/main/webapp/resources/js/function.js b/src/main/webapp/resources/js/function.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/webapp/resources/js/script.js b/src/main/webapp/resources/js/script.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/webapp/resources/js/utils.js b/src/main/webapp/resources/js/utils.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/webapp/todo.jsp b/src/main/webapp/todo.jsp new file mode 100644 index 000000000..2c1d396e2 --- /dev/null +++ b/src/main/webapp/todo.jsp @@ -0,0 +1,109 @@ +<%@ include file="head_common.jsp"%> +<%@ include file="head_files.jsp"%> +<%@ include file="navigation.jsp"%> + +
+
+
+
+
Add Todo
+
+ + +
+ Description + + +
+ +
+ Target Date + + +
+ + +
+
+
+
+
+
+ + +
+ + + + + + + + + +
diff --git a/src/main/webapp/welcome.jsp b/src/main/webapp/welcome.jsp new file mode 100644 index 000000000..3ea7c569f --- /dev/null +++ b/src/main/webapp/welcome.jsp @@ -0,0 +1,145 @@ +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + Create an account + + + + + + + +
+
+
+
+

Welcome ${pageContext.request.userPrincipal.name}

+

From here your can create a list, set date for your list, delete, update list. You can create and save your ideas.

+

+ Todo List +

+
+
+
+
+ + + + + + + diff --git a/src/test/java/com/github/curriculeon/MyObjectTest.java b/src/test/java/com/github/curriculeon/MyObjectTest.java new file mode 100644 index 000000000..2eac71dd4 --- /dev/null +++ b/src/test/java/com/github/curriculeon/MyObjectTest.java @@ -0,0 +1,18 @@ +package com.github.curriculeon; + +import org.junit.Assert; +import org.junit.Test; + +public class MyObjectTest { + @Test + public void testRun() { // TODO + // Given + MyObject myObject = new MyObject(); + + // when + myObject.run(); + + //then + Assert.assertNotNull(myObject.toString()); + } +}