diff --git a/README.md b/README.md new file mode 100644 index 00000000..c812b277 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Do curso devsuperiro desafio do modulo 5 MovieFlix + +## Descrição + +Este projeto é uma aplicação Spring Boot que implementa uma coleção de filmes com as seguintes características: + +* **Domínio e ORM:** Usa um modelo de domínio rico para representar filmes, gêneros, atores e outras entidades relacionadas. O mapeamento objeto-relacional é feito com o Hibernate. +* **Autorizações:** Implementa autenticação e autorização com base em JWT. Os usuários podem ter diferentes perfis de acesso, como administrador, editor e visualizador. + +## Funcionalidades + +* **Gerenciamento de filmes:** Adicionar, editar, remover e pesquisar filmes. +* **Gerenciamento de gêneros:** Adicionar, editar e remover gêneros. +* **Gerenciamento de atores:** Adicionar, editar e remover atores. +* **Autenticação e autorização:** Login, logout e controle de acesso a diferentes recursos da aplicação. + +## Tecnologias + +* **Spring Boot:** Framework Java para desenvolvimento de aplicações web de alto desempenho. +* **Hibernate:** Framework ORM para mapeamento objeto-relacional. +* **JWT:** Padrão para autenticação e autorização de APIs. +* **MySQL:** Banco de dados relacional. diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 00000000..549e00a2 --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/bin/.mvn/wrapper/MavenWrapperDownloader.class b/bin/.mvn/wrapper/MavenWrapperDownloader.class new file mode 100644 index 00000000..79d7e3ad Binary files /dev/null and b/bin/.mvn/wrapper/MavenWrapperDownloader.class differ diff --git a/bin/.mvn/wrapper/maven-wrapper.jar b/bin/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 00000000..2cc7d4a5 Binary files /dev/null and b/bin/.mvn/wrapper/maven-wrapper.jar differ diff --git a/bin/.mvn/wrapper/maven-wrapper.properties b/bin/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..ffdc10e5 --- /dev/null +++ b/bin/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/bin/mvnw b/bin/mvnw new file mode 100644 index 00000000..a16b5431 --- /dev/null +++ b/bin/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/bin/mvnw.cmd b/bin/mvnw.cmd new file mode 100644 index 00000000..c8d43372 --- /dev/null +++ b/bin/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/bin/pom.xml b/bin/pom.xml new file mode 100644 index 00000000..700cdb2f --- /dev/null +++ b/bin/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.4.4 + + + com.devsuperior + bds05 + 0.0.1-SNAPSHOT + bds05 + Bootcamp Spring React DevSuperior + + + 11 + Hoxton.SR8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + diff --git a/bin/src/main/java/com/devsuperior/movieflix/MovieflixApplication.class b/bin/src/main/java/com/devsuperior/movieflix/MovieflixApplication.class new file mode 100644 index 00000000..2f0beb8d Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/MovieflixApplication.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/Genre.class b/bin/src/main/java/com/devsuperior/movieflix/entities/Genre.class new file mode 100644 index 00000000..ea9acadb Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/Genre.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/Movie.class b/bin/src/main/java/com/devsuperior/movieflix/entities/Movie.class new file mode 100644 index 00000000..0e7655da Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/Movie.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/Review.class b/bin/src/main/java/com/devsuperior/movieflix/entities/Review.class new file mode 100644 index 00000000..2091ad38 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/Review.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/Role.class b/bin/src/main/java/com/devsuperior/movieflix/entities/Role.class new file mode 100644 index 00000000..abdf313f Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/Role.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/User.class b/bin/src/main/java/com/devsuperior/movieflix/entities/User.class new file mode 100644 index 00000000..a850c6cf Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/User.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.class b/bin/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.class new file mode 100644 index 00000000..45870335 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.class b/bin/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.class new file mode 100644 index 00000000..9a3728c1 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.class b/bin/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.class new file mode 100644 index 00000000..47295ad4 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.class b/bin/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.class new file mode 100644 index 00000000..941acb8a Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.class b/bin/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.class new file mode 100644 index 00000000..df92f56d Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.class b/bin/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.class new file mode 100644 index 00000000..17f32f66 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/AuthService.class b/bin/src/main/java/com/devsuperior/movieflix/services/AuthService.class new file mode 100644 index 00000000..78bb4fcc Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/AuthService.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/UserService.class b/bin/src/main/java/com/devsuperior/movieflix/services/UserService.class new file mode 100644 index 00000000..6ff3103c Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/UserService.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.class b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.class new file mode 100644 index 00000000..b268a8ab Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.class b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.class new file mode 100644 index 00000000..5758213b Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.class b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.class new file mode 100644 index 00000000..3cf41301 Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.class differ diff --git a/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.class b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.class new file mode 100644 index 00000000..dc94d87a Binary files /dev/null and b/bin/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.class differ diff --git a/bin/src/main/resources/application-test.properties b/bin/src/main/resources/application-test.properties new file mode 100644 index 00000000..c81c681e --- /dev/null +++ b/bin/src/main/resources/application-test.properties @@ -0,0 +1,6 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.username=sa +spring.datasource.password= + +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console diff --git a/bin/src/main/resources/application.properties b/bin/src/main/resources/application.properties new file mode 100644 index 00000000..a7dcd8af --- /dev/null +++ b/bin/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.profiles.active=test + +spring.jpa.open-in-view=false diff --git a/bin/src/test/java/com/devsuperior/movieflix/controllers/UserControllerIT.class b/bin/src/test/java/com/devsuperior/movieflix/controllers/UserControllerIT.class new file mode 100644 index 00000000..99b07fe2 Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/controllers/UserControllerIT.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/entities/GenreTests.class b/bin/src/test/java/com/devsuperior/movieflix/entities/GenreTests.class new file mode 100644 index 00000000..d006bb08 Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/entities/GenreTests.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/entities/MovieTests.class b/bin/src/test/java/com/devsuperior/movieflix/entities/MovieTests.class new file mode 100644 index 00000000..85437c2d Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/entities/MovieTests.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/entities/ReviewTests.class b/bin/src/test/java/com/devsuperior/movieflix/entities/ReviewTests.class new file mode 100644 index 00000000..6f3983c5 Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/entities/ReviewTests.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/entities/RoleTests.class b/bin/src/test/java/com/devsuperior/movieflix/entities/RoleTests.class new file mode 100644 index 00000000..07ab8834 Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/entities/RoleTests.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/entities/UserTests.class b/bin/src/test/java/com/devsuperior/movieflix/entities/UserTests.class new file mode 100644 index 00000000..e3412a4c Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/entities/UserTests.class differ diff --git a/bin/src/test/java/com/devsuperior/movieflix/tests/TokenUtil.class b/bin/src/test/java/com/devsuperior/movieflix/tests/TokenUtil.class new file mode 100644 index 00000000..e61a9805 Binary files /dev/null and b/bin/src/test/java/com/devsuperior/movieflix/tests/TokenUtil.class differ diff --git a/src/main/java/com/devsuperior/movieflix/components/JwtTokenEnhancer.java b/src/main/java/com/devsuperior/movieflix/components/JwtTokenEnhancer.java new file mode 100644 index 00000000..6db4d22e --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/components/JwtTokenEnhancer.java @@ -0,0 +1,36 @@ +package com.devsuperior.movieflix.components; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.TokenEnhancer; +import org.springframework.stereotype.Component; + +import com.devsuperior.movieflix.entities.User; +import com.devsuperior.movieflix.repositories.UserRepository; + +@Component +public class JwtTokenEnhancer implements TokenEnhancer{ + + @Autowired + private UserRepository userRepository; + + @Override + public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + User user = userRepository.findByEmail(authentication.getName()); + + Map map = new HashMap<>(); + map.put("userId", user.getId()); + + DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken; + + token.setAdditionalInformation(map); + + return accessToken; + } + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/config/AppConfig.java b/src/main/java/com/devsuperior/movieflix/config/AppConfig.java new file mode 100644 index 00000000..55bb740f --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/config/AppConfig.java @@ -0,0 +1,34 @@ +package com.devsuperior.movieflix.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; + +@Configuration +public class AppConfig { + + @Value("${jwt.secret}") + private String jwtSecret; + + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public JwtAccessTokenConverter accessTokenConverter() { + JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter(); + tokenConverter.setSigningKey(jwtSecret); + return tokenConverter; + } + + @Bean + public JwtTokenStore tokenStore() { + return new JwtTokenStore(accessTokenConverter()); + } + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/config/AuthorizationServerConfig.java b/src/main/java/com/devsuperior/movieflix/config/AuthorizationServerConfig.java new file mode 100644 index 00000000..bb06fc91 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/config/AuthorizationServerConfig.java @@ -0,0 +1,83 @@ +package com.devsuperior.movieflix.config; + +import java.util.Arrays; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; + +import com.devsuperior.movieflix.components.JwtTokenEnhancer; + +@Configuration +@EnableAuthorizationServer +public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{ + + @Value("${security.oauth2.client.client-id}") + private String clientId; + + @Value("${security.oauth2.client.client-secret}") + private String clientSecret; + + @Value("${jwt.duration}") + private Integer jwtDuration; + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + + @Autowired + private JwtAccessTokenConverter accessTokenConverter; + + @Autowired + private JwtTokenStore tokenStore; + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private JwtTokenEnhancer tokenEnhancer; + + @Autowired + private UserDetailsService userDetailsService; + + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory() + .withClient(clientId) + .secret(passwordEncoder.encode(clientSecret)) + .scopes("read", "write") + .authorizedGrantTypes("password", "refresh_token") + .accessTokenValiditySeconds(jwtDuration) + .refreshTokenValiditySeconds(jwtDuration); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + TokenEnhancerChain chain = new TokenEnhancerChain(); + chain.setTokenEnhancers(Arrays.asList(accessTokenConverter, tokenEnhancer)); + + endpoints.authenticationManager(authenticationManager) + .tokenStore(tokenStore) + .accessTokenConverter(accessTokenConverter) + .tokenEnhancer(chain) + .userDetailsService(userDetailsService); + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/config/ResourceServerConfig.java b/src/main/java/com/devsuperior/movieflix/config/ResourceServerConfig.java new file mode 100644 index 00000000..a87878e0 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/config/ResourceServerConfig.java @@ -0,0 +1,46 @@ +package com.devsuperior.movieflix.config; + +import java.util.Arrays; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; + +@Configuration +@EnableResourceServer +public class ResourceServerConfig extends ResourceServerConfigurerAdapter{ + + @Autowired + private Environment env; + + @Autowired + private JwtTokenStore tokenStore; + + private static final String[] PUBLIC = { "/oauth/token", "/h2-console/**" }; + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.tokenStore(tokenStore); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + + //H2 + if(Arrays.asList(env.getActiveProfiles()).contains("test")) { + http.headers().frameOptions().disable(); + } + + http.authorizeRequests() + .antMatchers(PUBLIC).permitAll() + .anyRequest().authenticated(); + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/config/WebSecurityConfig.java b/src/main/java/com/devsuperior/movieflix/config/WebSecurityConfig.java new file mode 100644 index 00000000..bf41c631 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/config/WebSecurityConfig.java @@ -0,0 +1,43 @@ +package com.devsuperior.movieflix.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.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + + @Autowired + private UserDetailsService userDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/actuator/**"); + } + + @Override + @Bean + protected AuthenticationManager authenticationManager() throws Exception { + return super.authenticationManager(); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/entities/Genre.java b/src/main/java/com/devsuperior/movieflix/entities/Genre.java new file mode 100644 index 00000000..b3c27dfc --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/Genre.java @@ -0,0 +1,82 @@ +package com.devsuperior.movieflix.entities; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name="tb_genre") +public class Genre implements Serializable{ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + + + @OneToMany(mappedBy = "genre") + private List movies = new ArrayList<>(); + + public Genre() { + } + + public Genre(Long id, String name) { + this.id = id; + this.name = name; + } + + 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 getMovies() { + return movies; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Genre other = (Genre) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + +} diff --git a/src/main/java/com/devsuperior/movieflix/entities/Movie.java b/src/main/java/com/devsuperior/movieflix/entities/Movie.java new file mode 100644 index 00000000..22277bd0 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/Movie.java @@ -0,0 +1,140 @@ +package com.devsuperior.movieflix.entities; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name="tb_movie") +public class Movie implements Serializable{ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String title; + private String subTitle; + private Integer year; + private String imgUrl; + private String synopsis; + + @OneToMany(mappedBy = "movie") + private List reviews = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name = "genre_id") + private Genre genre; + + public Movie() { + } + + public Movie(Long id, String title, String subTitle, Integer year, String imgUrl, String synopsis, + List reviews, Genre genre) { + this.id = id; + this.title = title; + this.subTitle = subTitle; + this.year = year; + this.imgUrl = imgUrl; + this.synopsis = synopsis; + this.reviews = reviews; + this.genre = genre; + } + + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSubTitle() { + return subTitle; + } + + public void setSubTitle(String subTitle) { + this.subTitle = subTitle; + } + + public Integer getYear() { + return year; + } + + public void setYear(Integer year) { + this.year = year; + } + + public String getImgUrl() { + return imgUrl; + } + + public void setImgUrl(String imgUrl) { + this.imgUrl = imgUrl; + } + + public String getSynopsis() { + return synopsis; + } + + public void setSynopsis(String synopsis) { + this.synopsis = synopsis; + } + + public List getReviews() { + return reviews; + } + + public Genre getGenre() { + return genre; + } + + public void setGenre(Genre genre) { + this.genre = genre; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Movie other = (Movie) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + +} diff --git a/src/main/java/com/devsuperior/movieflix/entities/Review.java b/src/main/java/com/devsuperior/movieflix/entities/Review.java new file mode 100644 index 00000000..24a436bb --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/Review.java @@ -0,0 +1,98 @@ +package com.devsuperior.movieflix.entities; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name="tb_review") +public class Review implements Serializable{ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String text; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne + @JoinColumn(name= "movie_id") + private Movie movie; + + public Review() { + } + + public Review(Long id, String text) { + super(); + this.id = id; + this.text = text; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Movie getMovie() { + return movie; + } + + public void setMovie(Movie movie) { + this.movie = movie; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Review other = (Review) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/entities/Role.java b/src/main/java/com/devsuperior/movieflix/entities/Role.java new file mode 100644 index 00000000..0c2e7954 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/Role.java @@ -0,0 +1,70 @@ +package com.devsuperior.movieflix.entities; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="tb_role") +public class Role implements Serializable{ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String authority; + + public Role() { + } + + public Role(Long id, String authority) { + this.id = id; + this.authority = authority; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAuthority() { + return authority; + } + + public void setAuthority(String authority) { + this.authority = authority; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Role other = (Role) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/entities/User.java b/src/main/java/com/devsuperior/movieflix/entities/User.java new file mode 100644 index 00000000..16ea3f9a --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/User.java @@ -0,0 +1,160 @@ +package com.devsuperior.movieflix.entities; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +@Entity +@Table(name="tb_user") +public class User implements UserDetails, Serializable{ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private String email; + private String password; + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name="tb_user_role", + joinColumns = @JoinColumn (name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "role_id")) + private Set roles = new HashSet<>(); + + @OneToMany(mappedBy = "user") + private List reviews = new ArrayList<>(); + + public User() { + } + + public User(Long id, String name, String email, String password) { + this.id = id; + this.name = name; + this.email = email; + this.password = password; + } + + 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 String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Set getRoles() { + return roles; + } + + public List getReviews() { + return reviews; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public Collection getAuthorities() { + return roles.stream().map(role -> new SimpleGrantedAuthority(role.getAuthority())).collect(Collectors.toList()); + } + + @Override + public String getUsername() { + return email; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + public boolean hasHole(String roleName) { + for(Role role: roles) { + if(role.getAuthority().equals(roleName)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.java b/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.java new file mode 100644 index 00000000..f09bdad1 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/entities/dtos/UserDTO.java @@ -0,0 +1,54 @@ +package com.devsuperior.movieflix.entities.dtos; + +import java.io.Serializable; + +import com.devsuperior.movieflix.entities.User; + +public class UserDTO implements Serializable{ +private static final long serialVersionUID = 1L; + + private Long id; + private String name; + private String email; + + public UserDTO() { + } + + public UserDTO(Long id, String name, String email) { + this.id = id; + this.name = name; + this.email = email; + } + + public UserDTO(User entity) { + id = entity.getId(); + name = entity.getName(); + email = entity.getEmail(); + } + + 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 String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.java b/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.java new file mode 100644 index 00000000..243fdb0b --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/repositories/GenreRepository.java @@ -0,0 +1,9 @@ +package com.devsuperior.movieflix.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.devsuperior.movieflix.entities.Genre; + +public interface GenreRepository extends JpaRepository{ + +} diff --git a/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.java b/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.java new file mode 100644 index 00000000..28d84448 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/repositories/MovieRepository.java @@ -0,0 +1,9 @@ +package com.devsuperior.movieflix.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.devsuperior.movieflix.entities.Movie; + +public interface MovieRepository extends JpaRepository{ + +} diff --git a/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.java b/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.java new file mode 100644 index 00000000..14eb5254 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/repositories/ReviewRepository.java @@ -0,0 +1,9 @@ +package com.devsuperior.movieflix.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.devsuperior.movieflix.entities.Review; + +public interface ReviewRepository extends JpaRepository{ + +} diff --git a/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.java b/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.java new file mode 100644 index 00000000..1ad8037c --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/repositories/RoleRepository.java @@ -0,0 +1,9 @@ +package com.devsuperior.movieflix.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.devsuperior.movieflix.entities.Role; + +public interface RoleRepository extends JpaRepository{ + +} diff --git a/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.java b/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.java new file mode 100644 index 00000000..5b89a2bc --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/repositories/UserRepository.java @@ -0,0 +1,9 @@ +package com.devsuperior.movieflix.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.devsuperior.movieflix.entities.User; + +public interface UserRepository extends JpaRepository{ + User findByEmail(String email); +} diff --git a/src/main/java/com/devsuperior/movieflix/resources/UserResource.java b/src/main/java/com/devsuperior/movieflix/resources/UserResource.java new file mode 100644 index 00000000..d259bf0e --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/UserResource.java @@ -0,0 +1,33 @@ +package com.devsuperior.movieflix.resources; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.devsuperior.movieflix.entities.dtos.UserDTO; +import com.devsuperior.movieflix.services.UserService; + +@RestController +@RequestMapping(value = "/users") +public class UserResource { + + @Autowired + private UserService service; + + @GetMapping(value = "/{id}") + public ResponseEntity findById(@PathVariable Long id){ + UserDTO dto = service.findById(id); + + return ResponseEntity.ok().body(dto); + } + + @GetMapping(value = "/profile") + public ResponseEntity notificationsForCurrentUser(){ + UserDTO page = service.userForCurrentUser(); + + return ResponseEntity.ok().body(page); + } +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/resources/exceptions/FieldMessage.java b/src/main/java/com/devsuperior/movieflix/resources/exceptions/FieldMessage.java new file mode 100644 index 00000000..f7d4362e --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/exceptions/FieldMessage.java @@ -0,0 +1,38 @@ +package com.devsuperior.movieflix.resources.exceptions; + +import java.io.Serializable; + +public class FieldMessage implements Serializable{ + private static final long serialVersionUID = 1L; + + private String fieldName; + private String message; + + public FieldMessage() { + } + + public FieldMessage(String fieldName, String message) { + super(); + this.fieldName = fieldName; + this.message = message; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/resources/exceptions/OAuthCustomError.java b/src/main/java/com/devsuperior/movieflix/resources/exceptions/OAuthCustomError.java new file mode 100644 index 00000000..0c387555 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/exceptions/OAuthCustomError.java @@ -0,0 +1,41 @@ +package com.devsuperior.movieflix.resources.exceptions; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class OAuthCustomError implements Serializable{ + private static final long serialVersionUID = 1L; + + private String error; + + @JsonProperty("error_description") + private String errorDescription; + + public OAuthCustomError() { + } + + public OAuthCustomError(String error, String errorDescription) { + super(); + this.error = error; + this.errorDescription = errorDescription; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getErrorDescription() { + return errorDescription; + } + + public void setErrorDescription(String errorDescription) { + this.errorDescription = errorDescription; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/resources/exceptions/ResourceExceptionHandler.java b/src/main/java/com/devsuperior/movieflix/resources/exceptions/ResourceExceptionHandler.java new file mode 100644 index 00000000..0fcf005d --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/exceptions/ResourceExceptionHandler.java @@ -0,0 +1,74 @@ +package com.devsuperior.movieflix.resources.exceptions; + +import java.time.Instant; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import com.devsuperior.movieflix.services.exceptions.DatabaseException; +import com.devsuperior.movieflix.services.exceptions.ForbiddenException; +import com.devsuperior.movieflix.services.exceptions.ResourceNotFoundException; +import com.devsuperior.movieflix.services.exceptions.UnauthorizedException; + +@ControllerAdvice +public class ResourceExceptionHandler { + + @ExceptionHandler(ResourceNotFoundException.class) + public ResponseEntity entityNotFound(ResourceNotFoundException e, HttpServletRequest request){ + StandardError err = new StandardError(); + err.setTimestamp(Instant.now()); + err.setStatus(HttpStatus.NOT_FOUND.value()); + err.setError("Resource not found"); + err.setMessage(e.getMessage()); + err.setPath(request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(err); + } + + @ExceptionHandler(DatabaseException.class) + public ResponseEntity database(DatabaseException e, HttpServletRequest request){ + StandardError err = new StandardError(); + err.setTimestamp(Instant.now()); + err.setStatus(HttpStatus.BAD_REQUEST.value()); + err.setError("Database exception"); + err.setMessage(e.getMessage()); + err.setPath(request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(err); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity validation(MethodArgumentNotValidException e, HttpServletRequest request){ + ValidationError err = new ValidationError(); + err.setTimestamp(Instant.now()); + err.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value()); + err.setError("Validation exception"); + err.setMessage(e.getMessage()); + err.setPath(request.getRequestURI()); + + for(FieldError f : e.getBindingResult().getFieldErrors()) { + err.addError(f.getField(), f.getDefaultMessage()); + } + + return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(err); + } + + @ExceptionHandler(ForbiddenException.class) + public ResponseEntity forbidden(ForbiddenException e, HttpServletRequest request){ + OAuthCustomError err = new OAuthCustomError("Forbidden", e.getMessage()); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(err); + } + + @ExceptionHandler(UnauthorizedException.class) + public ResponseEntity unauthorized(UnauthorizedException e, HttpServletRequest request){ + OAuthCustomError err = new OAuthCustomError("Unauthorized", e.getMessage()); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(err); + } + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/resources/exceptions/StandardError.java b/src/main/java/com/devsuperior/movieflix/resources/exceptions/StandardError.java new file mode 100644 index 00000000..ed38ea47 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/exceptions/StandardError.java @@ -0,0 +1,61 @@ +package com.devsuperior.movieflix.resources.exceptions; + +import java.io.Serializable; +import java.time.Instant; + +public class StandardError implements Serializable{ + private static final long serialVersionUID = 1L; + + private Instant timestamp; + private Integer status; + private String error; + private String message; + private String path; + + public StandardError() { + } + + + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/resources/exceptions/ValidationError.java b/src/main/java/com/devsuperior/movieflix/resources/exceptions/ValidationError.java new file mode 100644 index 00000000..e3aaff48 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/resources/exceptions/ValidationError.java @@ -0,0 +1,18 @@ +package com.devsuperior.movieflix.resources.exceptions; + +import java.util.ArrayList; +import java.util.List; + +public class ValidationError extends StandardError{ + private static final long serialVersionUID = 1L; + + private List errors = new ArrayList<>(); + + public List getErrors() { + return errors; + } + + public void addError(String fieldName, String message) { + errors.add(new FieldMessage(fieldName, message)); + } +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/services/AuthService.java b/src/main/java/com/devsuperior/movieflix/services/AuthService.java new file mode 100644 index 00000000..a9eb3318 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/AuthService.java @@ -0,0 +1,37 @@ +package com.devsuperior.movieflix.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.devsuperior.movieflix.entities.User; +import com.devsuperior.movieflix.repositories.UserRepository; +import com.devsuperior.movieflix.services.exceptions.ForbiddenException; +import com.devsuperior.movieflix.services.exceptions.UnauthorizedException; + +@Service +public class AuthService { + + @Autowired + private UserRepository repository; + + @Transactional(readOnly = true) + public User authenticated() { + try { + String username = SecurityContextHolder.getContext().getAuthentication().getName(); + return repository.findByEmail(username); + }catch(Exception e) { + throw new UnauthorizedException("Invalid user"); + } + } + + public void validateSelf(Long userId) { + User user = authenticated(); + if(!user.getId().equals(userId)) { + throw new ForbiddenException("Access denied"); + }else { + + } + } +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/services/UserService.java b/src/main/java/com/devsuperior/movieflix/services/UserService.java new file mode 100644 index 00000000..5b7204a9 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/UserService.java @@ -0,0 +1,60 @@ +package com.devsuperior.movieflix.services; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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 org.springframework.transaction.annotation.Transactional; + +import com.devsuperior.movieflix.entities.User; +import com.devsuperior.movieflix.entities.dtos.UserDTO; +import com.devsuperior.movieflix.repositories.UserRepository; +import com.devsuperior.movieflix.services.exceptions.ResourceNotFoundException; + +@Service +public class UserService implements UserDetailsService{ + + private static Logger logger = LoggerFactory.getLogger(UserService.class); + + @Autowired + private UserRepository repository; + + @Autowired + private AuthService authService; + + + @Transactional(readOnly = true) + public UserDTO findById(Long id) { + authService.validateSelf(id); + Optional obj = repository.findById(id); + User entity = obj.orElseThrow(() -> new ResourceNotFoundException("Entity not found")); + return new UserDTO(entity); + } + + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = repository.findByEmail(username); + if(user == null) { + logger.error("User not found: " + username); + throw new UsernameNotFoundException("Email not found"); + } + logger.info("User found: " + username); + return user; + } + + @Transactional(readOnly = true) + public UserDTO userForCurrentUser(){ + User user = authService.authenticated(); + Optional obj = repository.findById(user.getId()); + User entity = obj.orElseThrow(() -> new ResourceNotFoundException("Entity not found")); + + return new UserDTO(entity); + } + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.java b/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.java new file mode 100644 index 00000000..08fde32d --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/exceptions/DatabaseException.java @@ -0,0 +1,12 @@ +package com.devsuperior.movieflix.services.exceptions; + +public class DatabaseException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public DatabaseException(String msg) { + super(msg); + } + + +} diff --git a/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.java b/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.java new file mode 100644 index 00000000..34a1d405 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/exceptions/ForbiddenException.java @@ -0,0 +1,12 @@ +package com.devsuperior.movieflix.services.exceptions; + +public class ForbiddenException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ForbiddenException(String msg) { + super(msg); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.java b/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.java new file mode 100644 index 00000000..6802833e --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/exceptions/ResourceNotFoundException.java @@ -0,0 +1,12 @@ +package com.devsuperior.movieflix.services.exceptions; + +public class ResourceNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ResourceNotFoundException(String msg) { + super(msg); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.java b/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.java new file mode 100644 index 00000000..5b3867e7 --- /dev/null +++ b/src/main/java/com/devsuperior/movieflix/services/exceptions/UnauthorizedException.java @@ -0,0 +1,12 @@ +package com.devsuperior.movieflix.services.exceptions; + +public class UnauthorizedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public UnauthorizedException(String msg) { + super(msg); + } + + +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a7dcd8af..de5668d0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,9 @@ -spring.profiles.active=test +spring.profiles.active=${APP_PROFILE:test} spring.jpa.open-in-view=false + +security.oauth2.client.client-id=${CLIENT_ID:myclientid} +security.oauth2.client.client-secret=${CLIENT_SECRET:myclientsecret} + +jwt.secret=${JWT_SECRET:MY-JWT-SECRET} +jwt.duration=${JWT_DURATION:86400} \ No newline at end of file diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql new file mode 100644 index 00000000..f5c4c266 --- /dev/null +++ b/src/main/resources/import.sql @@ -0,0 +1,8 @@ +INSERT INTO tb_user (name, email, password) VALUES ('Ana Green', 'ana@gmail.com', '$2a$10$eACCYoNOHEqXve8aIWT8Nu3PkMXWBaOxJ9aORUYzfMQCbVBIhZ8tG'); +INSERT INTO tb_user (name, email, password) VALUES ('Bob Brown', 'bob@gmail.com', '$2a$10$eACCYoNOHEqXve8aIWT8Nu3PkMXWBaOxJ9aORUYzfMQCbVBIhZ8tG'); + +INSERT INTO tb_role (authority) VALUES ('ROLE_MEMBER'); +INSERT INTO tb_role (authority) VALUES ('ROLE_VISITOR'); + +INSERT INTO tb_user_role (user_id, role_id) VALUES (1, 1); +INSERT INTO tb_user_role (user_id, role_id) VALUES (2, 2); \ No newline at end of file