Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Matúš Valko
Online Gaming Management System
Commits
98cf26de
Commit
98cf26de
authored
May 20, 2022
by
Marek Kadlečík
Browse files
Merge branch 'security' into 'main'
Security See merge request
!28
parents
e682f12b
a9478aa1
Pipeline
#141827
passed with stage
in 1 minute and 5 seconds
Changes
22
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
gaming-api/src/main/java/cz/muni/fi/pa165/dto/PersonAuthenticateDTO.java
0 → 100644
View file @
98cf26de
package
cz.muni.fi.pa165.dto
;
public
class
PersonAuthenticateDTO
{
private
String
userId
;
private
String
password
;
public
String
getUserId
()
{
return
userId
;
}
public
void
setUserId
(
String
userId
)
{
this
.
userId
=
userId
;
}
public
String
getPassword
()
{
return
password
;
}
public
void
setPassword
(
String
password
)
{
this
.
password
=
password
;
}
}
gaming-api/src/main/java/cz/muni/fi/pa165/dto/PersonDTO.java
View file @
98cf26de
...
...
@@ -17,4 +17,8 @@ public class PersonDTO extends BaseDTO {
private
LocalDate
dateOfBirth
;
private
CountryEnum
country
;
private
String
passwordHash
;
private
String
username
;
}
gaming-api/src/main/java/cz/muni/fi/pa165/facade/PersonFacade.java
0 → 100644
View file @
98cf26de
package
cz.muni.fi.pa165.facade
;
import
cz.muni.fi.pa165.dto.PersonAuthenticateDTO
;
import
cz.muni.fi.pa165.dto.PersonDTO
;
import
java.util.List
;
public
interface
PersonFacade
{
List
<
PersonDTO
>
findAllPeople
();
PersonDTO
getPersonById
(
String
uuid
);
PersonDTO
getPersonByUsername
(
String
username
);
void
delete
(
String
uuid
);
boolean
authenticate
(
PersonAuthenticateDTO
person
);
boolean
isAdmin
(
PersonDTO
person
);
}
gaming-persistence/pom.xml
View file @
98cf26de
...
...
@@ -107,6 +107,10 @@
<artifactId>
assertj-core
</artifactId>
<version>
3.21.0
</version>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-crypto
</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
gaming-persistence/src/main/java/cz/muni/fi/pa165/PersistenceSampleApplicationContext.java
View file @
98cf26de
...
...
@@ -13,6 +13,8 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import
org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
;
import
org.springframework.orm.jpa.JpaTransactionManager
;
import
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
;
import
org.springframework.security.crypto.argon2.Argon2PasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
...
...
gaming-persistence/src/main/java/cz/muni/fi/pa165/dao/person/PersonDao.java
View file @
98cf26de
...
...
@@ -7,4 +7,5 @@ import cz.muni.fi.pa165.entity.PersonEntity;
* @author Dominik Kozubík
*/
public
interface
PersonDao
extends
BaseDao
<
PersonEntity
>
{
PersonEntity
findByUsername
(
String
username
);
}
gaming-persistence/src/main/java/cz/muni/fi/pa165/dao/person/PersonDaoImpl.java
View file @
98cf26de
package
cz.muni.fi.pa165.dao.person
;
import
cz.muni.fi.pa165.dao.BaseDaoImpl
;
import
cz.muni.fi.pa165.dao.exceptions.DaoDataAccessException
;
import
cz.muni.fi.pa165.entity.PersonEntity
;
import
org.springframework.stereotype.Repository
;
...
...
@@ -19,4 +20,14 @@ public class PersonDaoImpl extends BaseDaoImpl<PersonEntity> implements PersonDa
public
PersonDaoImpl
()
{
super
(
PersonEntity
.
class
);
}
@Override
public
PersonEntity
findByUsername
(
String
username
)
{
try
{
return
em
.
createQuery
(
"select e from "
+
entityClass
.
getName
()
+
" e where e.username like :username"
,
entityClass
)
.
setParameter
(
"username"
,
username
).
getSingleResult
();
}
catch
(
Exception
e
)
{
return
null
;
}
}
}
gaming-persistence/src/main/java/cz/muni/fi/pa165/entity/PersonEntity.java
View file @
98cf26de
...
...
@@ -22,6 +22,12 @@ public class PersonEntity extends BaseEntity {
private
CountryEnum
country
;
private
String
username
;
private
String
passwordHash
;
private
boolean
admin
;
public
PersonEntity
()
{
}
...
...
gaming-sample-data/pom.xml
View file @
98cf26de
...
...
@@ -46,5 +46,11 @@
<artifactId>
gaming-service
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
<version>
31.0.1-jre
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
</project>
gaming-sample-data/src/main/java/cz/muni/fi/pa165/sampledata/SampleDataLoadingFacadeImpl.java
View file @
98cf26de
package
cz.muni.fi.pa165.sampledata
;
import
com.google.common.hash.Hashing
;
import
cz.muni.fi.pa165.entity.PlayerEntity
;
import
cz.muni.fi.pa165.entity.TeamEntity
;
import
cz.muni.fi.pa165.enums.CountryEnum
;
...
...
@@ -8,10 +9,13 @@ import cz.muni.fi.pa165.services.team.TeamService;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.crypto.argon2.Argon2PasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.stereotype.Component
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
/**
* @author Adrián Piaček
...
...
@@ -31,23 +35,26 @@ public class SampleDataLoadingFacadeImpl implements SampleDataLoadingFacade {
@Override
@SuppressWarnings
(
"unused"
)
public
void
loadData
()
throws
IOException
{
TeamEntity
g2_esports
=
team
(
"g2_esports"
,
CountryEnum
.
GERMANY
);
TeamEntity
skt_t1
=
team
(
"skt_t1"
,
CountryEnum
.
SOUTH_KOREA
);
PlayerEntity
crimsix
=
player
(
"9384b466-badf-40ca-bbeb-4d8f6eb98042"
,
"Ian Porter"
,
CountryEnum
.
AFGHANISTAN
,
g2_esports
,
5
,
6
,
7
);
PlayerEntity
crimsix
=
player
(
"9384b466-badf-40ca-bbeb-4d8f6eb98042"
,
"Ian Porter"
,
"poter"
,
"heslo"
,
true
,
CountryEnum
.
AFGHANISTAN
,
g2_esports
,
5
,
6
,
7
);
PlayerEntity
JJoNak
=
player
(
"6e374a4e-5213-4581-847c-45f9e73ffe90"
,
"Bang Seong-hyun "
,
CountryEnum
.
ALBANIA
,
skt_t1
,
5
,
6
,
7
);
PlayerEntity
JJoNak
=
player
(
"6e374a4e-5213-4581-847c-45f9e73ffe90"
,
"Bang Seong-hyun "
,
"bang"
,
"heslo"
,
true
,
CountryEnum
.
ALBANIA
,
skt_t1
,
15
,
25
,
100
);
log
.
info
(
"Loaded Sample Players."
);
}
private
PlayerEntity
player
(
String
uuid
,
String
name
,
CountryEnum
country
,
TeamEntity
team
,
int
killStat
,
int
deathStat
,
int
assistStat
)
{
private
PlayerEntity
player
(
String
uuid
,
String
name
,
String
username
,
String
password
,
boolean
admin
,
CountryEnum
country
,
TeamEntity
team
,
int
killStat
,
int
deathStat
,
int
assistStat
)
{
PlayerEntity
player
=
new
PlayerEntity
();
player
.
setId
(
uuid
);
player
.
setName
(
name
);
player
.
setUsername
(
username
);
String
sha256hex
=
Hashing
.
sha256
().
hashString
(
password
,
StandardCharsets
.
UTF_8
).
toString
();
player
.
setPasswordHash
(
sha256hex
);
player
.
setAdmin
(
admin
);
player
.
setCountry
(
country
);
player
.
setTeam
(
team
);
player
.
setKillStat
(
killStat
);
...
...
gaming-service/pom.xml
View file @
98cf26de
...
...
@@ -46,6 +46,12 @@
<version>
1.0-SNAPSHOT
</version>
<scope>
compile
</scope>
</dependency>
<dependency>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
<version>
31.0.1-jre
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
<properties>
...
...
gaming-service/src/main/java/cz/muni/fi/pa165/facade/PersonFacadeImpl.java
0 → 100644
View file @
98cf26de
package
cz.muni.fi.pa165.facade
;
import
cz.muni.fi.pa165.dto.PersonAuthenticateDTO
;
import
cz.muni.fi.pa165.dto.PersonDTO
;
import
cz.muni.fi.pa165.entity.PersonEntity
;
import
cz.muni.fi.pa165.services.BeanMappingService
;
import
cz.muni.fi.pa165.services.person.PersonService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
@Service
@Transactional
public
class
PersonFacadeImpl
implements
PersonFacade
{
@Autowired
private
PersonService
personService
;
@Autowired
private
BeanMappingService
beanMappingService
;
@Override
public
List
<
PersonDTO
>
findAllPeople
()
{
return
beanMappingService
.
mapTo
(
personService
.
findAll
(),
PersonDTO
.
class
);
}
@Override
public
PersonDTO
getPersonById
(
String
uuid
)
{
PersonEntity
person
=
personService
.
findById
(
uuid
);
return
(
person
==
null
)
?
null
:
beanMappingService
.
mapTo
(
person
,
PersonDTO
.
class
);
}
@Override
public
PersonDTO
getPersonByUsername
(
String
username
)
{
PersonEntity
person
=
personService
.
findByUsername
(
username
);
return
(
person
==
null
)
?
null
:
beanMappingService
.
mapTo
(
person
,
PersonDTO
.
class
);
}
@Override
public
void
delete
(
String
uuid
)
{
var
player
=
new
PersonEntity
();
player
.
setId
(
uuid
);
personService
.
remove
(
player
);
}
@Override
public
boolean
authenticate
(
PersonAuthenticateDTO
person
)
{
return
false
;
}
@Override
public
boolean
isAdmin
(
PersonDTO
person
)
{
return
personService
.
isAdmin
(
beanMappingService
.
mapTo
(
person
,
PersonEntity
.
class
));
}
}
gaming-service/src/main/java/cz/muni/fi/pa165/services/person/PersonService.java
View file @
98cf26de
...
...
@@ -15,6 +15,18 @@ public interface PersonService {
PersonEntity
findById
(
String
id
);
PersonEntity
findByUsername
(
String
username
);
/**
* Try to authenticate a user. Return true only if the hashed password matches the records.
*/
boolean
authenticate
(
PersonEntity
person
,
String
password
);
/**
* Check if the given user is admin.
*/
boolean
isAdmin
(
PersonEntity
person
);
String
update
(
PersonEntity
match
);
void
remove
(
PersonEntity
match
);
...
...
gaming-service/src/main/java/cz/muni/fi/pa165/services/person/PersonServiceImpl.java
View file @
98cf26de
package
cz.muni.fi.pa165.services.person
;
import
com.google.common.hash.Hashing
;
import
cz.muni.fi.pa165.dao.person.PersonDao
;
import
cz.muni.fi.pa165.entity.PersonEntity
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.crypto.argon2.Argon2PasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.stereotype.Service
;
import
javax.transaction.Transactional
;
import
java.nio.charset.StandardCharsets
;
import
java.util.List
;
import
java.util.UUID
;
...
...
@@ -40,6 +44,25 @@ public class PersonServiceImpl implements PersonService {
return
personDao
.
findById
(
id
);
}
@Override
public
PersonEntity
findByUsername
(
String
username
)
{
if
(
username
==
null
)
{
throw
new
IllegalArgumentException
(
"Given username is null."
);
}
return
personDao
.
findByUsername
(
username
);
}
@Override
public
boolean
authenticate
(
PersonEntity
person
,
String
password
)
{
String
sha256hex
=
Hashing
.
sha256
().
hashString
(
password
,
StandardCharsets
.
UTF_8
).
toString
();
return
person
.
getPasswordHash
().
equals
(
sha256hex
);
}
@Override
public
boolean
isAdmin
(
PersonEntity
person
)
{
return
findById
(
person
.
getId
()).
isAdmin
();
}
@Override
public
String
update
(
PersonEntity
person
)
{
if
(
person
==
null
)
{
...
...
gaming-spring-mvc/src/main/java/cz/muni/fi/pa165/mvc/config/MyConfig.java
View file @
98cf26de
...
...
@@ -27,7 +27,7 @@ public class MyConfig implements WebMvcConfigurer {
@Override
public
void
addViewControllers
(
ViewControllerRegistry
registry
)
{
registry
.
addViewController
(
"/"
).
setViewName
(
"
index
"
);
registry
.
addViewController
(
"/"
).
setViewName
(
"
home
"
);
}
@Override
...
...
gaming-spring-mvc/src/main/java/cz/muni/fi/pa165/mvc/controllers/LoginController.java
0 → 100644
View file @
98cf26de
package
cz.muni.fi.pa165.mvc.controllers
;
import
cz.muni.fi.pa165.dto.PersonAuthenticateDTO
;
import
cz.muni.fi.pa165.dto.PersonDTO
;
import
cz.muni.fi.pa165.entity.PersonEntity
;
import
cz.muni.fi.pa165.services.BeanMappingService
;
import
cz.muni.fi.pa165.services.person.PersonService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.servlet.mvc.support.RedirectAttributes
;
import
javax.servlet.http.HttpSession
;
import
javax.validation.Valid
;
/**
* @author Jan Hassman
*/
@Controller
@RequestMapping
(
"/security"
)
public
class
LoginController
{
@Autowired
private
PersonService
personService
;
@Autowired
private
BeanMappingService
mapper
;
@GetMapping
(
value
=
"/login"
)
public
String
getLogin
(
Model
model
,
HttpSession
session
)
{
if
(
session
.
getAttribute
(
"authenticatedUser"
)
!=
null
)
{
return
"redirect:/"
;
}
model
.
addAttribute
(
"user"
,
new
PersonAuthenticateDTO
());
return
"/security/login"
;
}
@PostMapping
(
value
=
"/login"
)
public
String
postLogin
(
Model
model
,
HttpSession
session
,
@Valid
@ModelAttribute
(
"user"
)
PersonDTO
personDTO
,
BindingResult
bindingResult
,
RedirectAttributes
redirectAttributes
)
{
if
(
bindingResult
.
hasErrors
())
{
redirectAttributes
.
addFlashAttribute
(
"alert_danger"
,
"Login failed!"
);
return
"security/loginFailed"
;
}
PersonEntity
person
=
personService
.
findByUsername
(
personDTO
.
getUsername
());
if
(
person
==
null
)
{
redirectAttributes
.
addFlashAttribute
(
"alert_danger"
,
"Login failed!"
);
return
"security/loginFailed"
;
}
if
(!
personService
.
authenticate
(
person
,
personDTO
.
getPasswordHash
()))
{
redirectAttributes
.
addFlashAttribute
(
"alert_danger"
,
"Login failed!"
);
return
"security/loginFailed"
;
}
session
.
setAttribute
(
"authenticatedUser"
,
mapper
.
mapTo
(
person
,
PersonDTO
.
class
));
redirectAttributes
.
addFlashAttribute
(
"alert_success"
,
"Login successful!"
);
return
"redirect:/"
;
}
@GetMapping
(
value
=
"/logout"
)
public
String
logout
(
Model
model
,
HttpSession
session
,
RedirectAttributes
redirectAttributes
)
{
if
(
session
.
getAttribute
(
"authenticatedUser"
)
==
null
)
{
return
"redirect:/"
;
}
session
.
removeAttribute
(
"authenticatedUser"
);
redirectAttributes
.
addFlashAttribute
(
"alert_success"
,
"Logout successful!"
);
return
"/security/login"
;
}
@GetMapping
(
value
=
"/wrongAccess"
)
public
String
wrongAccess
(
Model
model
,
HttpSession
httpSession
)
{
PersonDTO
personDTO
=
(
PersonDTO
)
httpSession
.
getAttribute
(
"authenticatedUser"
);
model
.
addAttribute
(
"authenticatedUser"
,
personDTO
);
return
"/security/wrongAccess"
;
}
}
gaming-spring-mvc/src/main/resources/Texts.properties
View file @
98cf26de
...
...
@@ -10,4 +10,6 @@ navigation.coaches = Coaches
navigation.matches
=
Matches
navigation.ranklist.players
=
Ranklist Players
navigation.ranklist.teams
=
Ranklist Teams
navigation.login
=
Login
navigation.logout
=
Logout
gaming-spring-mvc/src/main/webapp/WEB-INF/jsp/security/login.jsp
0 → 100644
View file @
98cf26de
<%@ page
contentType=
"text/html;charset=UTF-8"
pageEncoding=
"utf-8"
trimDirectiveWhitespaces=
"true"
session=
"false"
%>
<%@ taglib
tagdir=
"/WEB-INF/tags"
prefix=
"my"
%>
<%@ taglib
prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<fmt:message
var=
"title"
key=
"navigation.login"
/>
<my:pagetemplate
title=
"
${
title
}
"
>
<jsp:attribute
name=
"body"
>
<form
method=
"POST"
action=
"${pageContext.request.contextPath}/security/login"
>
<table>
<tr>
<td><label
for=
"username-label"
>
Username:
</label></td>
<td><input
id=
"username-label"
type=
"text"
name=
"username"
></td>
</tr>
<tr>
<td><label
for=
"password-label"
>
Password:
</label></td>
<td><input
id=
"password-label"
type=
"password"
name=
"passwordHash"
></td>
</tr>
</table>
<button
type=
"submit"
class=
"btn btn-primary"
>
Login
</button>
</form>
</jsp:attribute>
</my:pagetemplate>
gaming-spring-mvc/src/main/webapp/WEB-INF/jsp/security/loginFailed.jsp
0 → 100644
View file @
98cf26de
<%@ page
contentType=
"text/html;charset=UTF-8"
pageEncoding=
"utf-8"
trimDirectiveWhitespaces=
"true"
session=
"false"
%>
<%@ taglib
tagdir=
"/WEB-INF/tags"
prefix=
"my"
%>
<%@ taglib
prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<my:pagetemplate>
<jsp:attribute
name=
"body"
>
<html>
<head>
<title>
Login failed
</title>
</head>
<body>
<c:if
test=
"
${
not
empty
alert_danger
}
"
>
<div
class=
"alert alert-danger"
role=
"alert"
>
<span
class=
"glyphicon glyphicon-exclamation-sign"
aria-hidden=
"true"
></span>
<c:out
value=
"
${
alert_danger
}
"
/>
Login failed!
</div>
</c:if>
</body>
</html>
</jsp:attribute>
</my:pagetemplate>
gaming-spring-mvc/src/main/webapp/WEB-INF/jsp/security/notFound.jsp
0 → 100644
View file @
98cf26de
<%@ page
contentType=
"text/html;charset=UTF-8"
pageEncoding=
"utf-8"
trimDirectiveWhitespaces=
"true"
session=
"false"
%>
<%@ taglib
tagdir=
"/WEB-INF/tags"
prefix=
"my"
%>
<%@ taglib
prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<my:pagetemplate>
<jsp:attribute
name=
"body"
>
<html>
<head>
<title>
Not found
</title>
</head>
<body>
<p>
${resource} not found
</p>
</body>
</html>
</jsp:attribute>
</my:pagetemplate>
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment