simple authentication in DEV profile

This commit is contained in:
Michele Artini 2020-11-23 12:02:33 +01:00
parent 843fc1f93f
commit 3ff5ef9bd6
14 changed files with 253 additions and 65 deletions

View File

@ -0,0 +1,103 @@
package eu.dnetlib.organizations;
import javax.sql.DataSource;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
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.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import eu.dnetlib.organizations.controller.UserInfo;
import eu.dnetlib.organizations.utils.OpenOrgsConstants;
@Profile("dev")
@Configuration
@EnableWebSecurity
public class MockSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Value("${openaire.api.valid.subnet}")
private String openaireApiValidSubnet;
private static final String DEFAULT_PASSWORD = "dnet";
private static Logger logger = LoggerFactory.getLogger(MockSecurityConfig.class);
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/", "/api/**")
.hasAnyRole(OpenOrgsConstants.VALID_ROLES)
.antMatchers("/registration_api/**")
.hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE)
.antMatchers("/resources/**", "/webjars/**")
.permitAll()
.antMatchers("/oa_api/**")
.hasIpAddress(openaireApiValidSubnet)
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler());
}
private AccessDeniedHandler accessDeniedHandler() {
return (req, res, e) -> {
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
logger
.warn(String.format("User '%s' (%s) attempted to access the protected URL: %s", auth.getName(), req.getRemoteAddr(), req.getRequestURI()));
}
if (UserInfo.isNotAuthorized(auth)) {
res.sendRedirect(req.getContextPath() + "/authorizationRequest");
} else {
res.sendRedirect(req.getContextPath() + "/alreadyRegistered");
}
};
}
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select ?, '{MD5}" + DigestUtils.md5Hex(DEFAULT_PASSWORD) + "', true")
.authoritiesByUsernameQuery("with const as (SELECT ? as email) "
+ "select c.email, 'ROLE_" + OpenOrgsConstants.OPENORGS_ROLE_PREFIX + "'||coalesce(u.role, '"
+ OpenOrgsConstants.NOT_AUTORIZED_ROLE
+ "') from const c left outer join users u on (u.email = c.email)");
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}

View File

@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
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;
@ -28,12 +29,13 @@ import org.springframework.security.web.access.AccessDeniedHandler;
import eu.dnetlib.organizations.controller.UserInfo;
import eu.dnetlib.organizations.controller.UserRole;
import eu.dnetlib.organizations.model.User;
import eu.dnetlib.organizations.utils.AuthenticationUtils;
import eu.dnetlib.organizations.utils.DatabaseUtils;
import eu.dnetlib.organizations.utils.OpenOrgsConstants;
@Profile("!dev")
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DatabaseUtils databaseUtils;
@ -44,17 +46,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${openaire.api.valid.subnet}")
private String openaireApiValidSubnet;
private static String OPENORGS_ROLE_PREFIX = "OPENORGS_";
private static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
private static final String[] VALID_ROLES = {
OPENORGS_ROLE_PREFIX + UserRole.ADMIN,
OPENORGS_ROLE_PREFIX + UserRole.NATIONAL_ADMIN,
OPENORGS_ROLE_PREFIX + UserRole.USER
};
private static final String NOT_AUTORIZED_ROLE = OPENORGS_ROLE_PREFIX + UserRole.NOT_AUTHORIZED;
private static Logger logger = LoggerFactory.getLogger(OAuth2WebSecurityConfig.class);
@Override
protected void configure(final HttpSecurity http) throws Exception {
@ -62,9 +54,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.disable()
.authorizeRequests()
.antMatchers("/main", "/api/**")
.hasAnyRole(VALID_ROLES)
.hasAnyRole(OpenOrgsConstants.VALID_ROLES)
.antMatchers("/registration_api/**")
.hasRole(NOT_AUTORIZED_ROLE)
.hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE)
.antMatchers("/", "/resources/**", "/webjars/**")
.permitAll()
.antMatchers("/oa_api/**")
@ -86,7 +78,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
logger.warn(String
.format("User '%s' (%s) attempted to access the protected URL: %s", AuthenticationUtils.extractEmail(authentication), req
.format("User '%s' (%s) attempted to access the protected URL: %s", UserInfo.getEmail(authentication), req
.getRemoteAddr(), req.getRequestURI()));
}
@ -114,7 +106,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
return (userRequest) -> {
final OidcUser oidcUser = delegate.loadUser(userRequest);
final String role = "ROLE_" + OPENORGS_ROLE_PREFIX + databaseUtils.findUser(oidcUser.getEmail())
final String role = "ROLE_" + OpenOrgsConstants.OPENORGS_ROLE_PREFIX + databaseUtils.findUser(oidcUser.getEmail())
.map(User::getRole)
.filter(StringUtils::isNotBlank)
.orElse(UserRole.NOT_AUTHORIZED.toString());

View File

@ -1,14 +1,22 @@
package eu.dnetlib.organizations.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class HomeController {
@Autowired
private Environment env;
@GetMapping("/")
public String home() {
return "home";
return env.acceptsProfiles(Profiles.of("dev")) ? "redirect:main" : "home";
}
@GetMapping("/main")
@ -31,6 +39,11 @@ public class HomeController {
return "alreadyRegistered";
}
@ModelAttribute("email")
public String getUserEmail(final Authentication authentication) {
return authentication != null ? UserInfo.getEmail(authentication) : null;
}
@GetMapping({
"/doc", "/swagger"
})

View File

@ -41,7 +41,6 @@ import eu.dnetlib.organizations.repository.readonly.OrganizationInfoViewReposito
import eu.dnetlib.organizations.repository.readonly.OrganizationSimpleViewRepository;
import eu.dnetlib.organizations.repository.readonly.OrganizationViewRepository;
import eu.dnetlib.organizations.repository.readonly.SuggestionInfoViewByCountryRepository;
import eu.dnetlib.organizations.utils.AuthenticationUtils;
import eu.dnetlib.organizations.utils.DatabaseUtils;
import eu.dnetlib.organizations.utils.OrganizationStatus;
@ -78,9 +77,9 @@ public class OrganizationController {
} else if (StringUtils.isBlank(org.getType())) {
throw new RuntimeException("Missing field: type");
} else if (UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), AuthenticationUtils.extractEmail(authentication))) {
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), UserInfo.getEmail(authentication))) {
final String orgId =
databaseUtils.insertOrUpdateOrganization(org, AuthenticationUtils.extractEmail(authentication), UserInfo.isSimpleUser(authentication));
databaseUtils.insertOrUpdateOrganization(org, UserInfo.getEmail(authentication), UserInfo.isSimpleUser(authentication));
return Arrays.asList(orgId);
} else {
throw new RuntimeException("User not authorized");
@ -99,7 +98,7 @@ public class OrganizationController {
if (UserInfo.isSuperAdmin(authentication)) {
suggestionInfoViewByCountryRepository.findAll().forEach(info::add);
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
userCountryRepository.getCountriesForUser(AuthenticationUtils.extractEmail(authentication))
userCountryRepository.getCountriesForUser(UserInfo.getEmail(authentication))
.stream()
.map(suggestionInfoViewByCountryRepository::findById)
.filter(Optional::isPresent)
@ -114,7 +113,7 @@ public class OrganizationController {
final OrganizationView org = organizationViewRepository.findById(id).get();
if (UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), AuthenticationUtils.extractEmail(authentication))) {
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), UserInfo.getEmail(authentication))) {
return org;
} else {
throw new RuntimeException("User not authorized");
@ -123,7 +122,7 @@ public class OrganizationController {
@GetMapping("/conflicts")
public List<OrganizationConflict> conflicts(@RequestParam final String id, final Authentication authentication) {
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, AuthenticationUtils.extractEmail(authentication))) {
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, UserInfo.getEmail(authentication))) {
return databaseUtils.listConflictsForId(id);
} else {
throw new RuntimeException("User not authorized");
@ -132,7 +131,7 @@ public class OrganizationController {
@GetMapping("/duplicates")
public List<OpenaireDuplicateView> duplicates(@RequestParam final String id, final Authentication authentication) {
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, AuthenticationUtils.extractEmail(authentication))) {
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, UserInfo.getEmail(authentication))) {
return openaireDuplicateViewRepository.findByLocalId(id);
} else {
throw new RuntimeException("User not authorized");
@ -145,7 +144,7 @@ public class OrganizationController {
if (UserInfo.isSuperAdmin(authentication)) {
return groupConflicts(conflictGroupViewRepository.findByCountry1OrCountry2(country, country).stream());
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
final Stream<ConflictGroupView> list = userCountryRepository.getCountriesForUser(AuthenticationUtils.extractEmail(authentication))
final Stream<ConflictGroupView> list = userCountryRepository.getCountriesForUser(UserInfo.getEmail(authentication))
.stream()
.filter(country::equalsIgnoreCase)
.map(c -> conflictGroupViewRepository.findByCountry1OrCountry2(c, c).stream())
@ -164,7 +163,7 @@ public class OrganizationController {
if (UserInfo.isSuperAdmin(authentication)) {
return duplicateGroupViewRepository.findByCountry(country);
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
return userCountryRepository.getCountriesForUser(AuthenticationUtils.extractEmail(authentication))
return userCountryRepository.getCountriesForUser(UserInfo.getEmail(authentication))
.stream()
.filter(country::equalsIgnoreCase)
.map(duplicateGroupViewRepository::findByCountry)
@ -197,10 +196,10 @@ public class OrganizationController {
|| simrels.stream()
.map(OpenaireDuplicate::getLocalId)
.distinct()
.allMatch(id -> userCountryRepository.verifyAuthorizationForId(id, AuthenticationUtils.extractEmail(authentication)));
.allMatch(id -> userCountryRepository.verifyAuthorizationForId(id, UserInfo.getEmail(authentication)));
if (b) {
databaseUtils.saveDuplicates(simrels, AuthenticationUtils.extractEmail(authentication));
databaseUtils.saveDuplicates(simrels, UserInfo.getEmail(authentication));
return openaireDuplicateViewRepository.findByLocalId(simrels.get(0).getLocalId());
} else {
throw new RuntimeException("User not authorized");
@ -226,7 +225,7 @@ public class OrganizationController {
return UserInfo.isSuperAdmin(authentication)
? organizationSimpleViewRepository.search(q, statuses, PageRequest.of(page, size))
: organizationSimpleViewRepository.searchForUser(q, AuthenticationUtils.extractEmail(authentication), statuses, PageRequest.of(page, size));
: organizationSimpleViewRepository.searchForUser(q, UserInfo.getEmail(authentication), statuses, PageRequest.of(page, size));
}
@ -237,7 +236,7 @@ public class OrganizationController {
@PathVariable final int size,
final Authentication authentication) {
if (UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForCountry(code, AuthenticationUtils.extractEmail(authentication))) {
|| userCountryRepository.verifyAuthorizationForCountry(code, UserInfo.getEmail(authentication))) {
if (status.equalsIgnoreCase("all")) {
return organizationSimpleViewRepository.findByCountryOrderByName(code, PageRequest.of(page, size));
} else {
@ -253,7 +252,7 @@ public class OrganizationController {
@PathVariable final String code,
final Authentication authentication) {
if (UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForCountry(code, AuthenticationUtils.extractEmail(authentication))) {
|| userCountryRepository.verifyAuthorizationForCountry(code, UserInfo.getEmail(authentication))) {
if (status.equalsIgnoreCase("all")) {
return organizationSimpleViewRepository.findByCountryOrderByName(code);
} else {
@ -279,10 +278,10 @@ public class OrganizationController {
}
} else {
if (status.equalsIgnoreCase("all")) {
return organizationSimpleViewRepository.findByTypeForUser(type, AuthenticationUtils.extractEmail(authentication), PageRequest.of(page, size));
return organizationSimpleViewRepository.findByTypeForUser(type, UserInfo.getEmail(authentication), PageRequest.of(page, size));
} else {
return organizationSimpleViewRepository
.findByTypeAndStatusForUser(type, status, AuthenticationUtils.extractEmail(authentication), PageRequest.of(page, size));
.findByTypeAndStatusForUser(type, status, UserInfo.getEmail(authentication), PageRequest.of(page, size));
}
}
@ -292,21 +291,21 @@ public class OrganizationController {
public List<BrowseEntry> browseCountries(final Authentication authentication) {
return UserInfo.isSuperAdmin(authentication)
? databaseUtils.browseCountries()
: databaseUtils.browseCountriesForUser(AuthenticationUtils.extractEmail(authentication));
: databaseUtils.browseCountriesForUser(UserInfo.getEmail(authentication));
}
@GetMapping("/browse/types")
public List<BrowseEntry> browseOrganizationTypes(final Authentication authentication) {
return UserInfo.isSuperAdmin(authentication)
? databaseUtils.browseTypes()
: databaseUtils.browseTypesForUser(AuthenticationUtils.extractEmail(authentication));
: databaseUtils.browseTypesForUser(UserInfo.getEmail(authentication));
}
@PostMapping("/conflicts/fix/similar")
public List<String> fixConflictSim(final Authentication authentication, @RequestBody final List<String> ids) {
if (ids.size() > 1 && UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForId(ids.get(0), AuthenticationUtils.extractEmail(authentication))) {
final String newOrgId = databaseUtils.fixConflictSimilars(ids, AuthenticationUtils.extractEmail(authentication));
|| userCountryRepository.verifyAuthorizationForId(ids.get(0), UserInfo.getEmail(authentication))) {
final String newOrgId = databaseUtils.fixConflictSimilars(ids, UserInfo.getEmail(authentication));
return Arrays.asList(newOrgId);
} else {
return new ArrayList<>();
@ -316,8 +315,8 @@ public class OrganizationController {
@PostMapping("/conflicts/fix/different")
public List<String> fixConflictDiff(final Authentication authentication, @RequestBody final List<String> ids) {
if (ids.size() > 1 && UserInfo.isSuperAdmin(authentication)
|| userCountryRepository.verifyAuthorizationForId(ids.get(0), AuthenticationUtils.extractEmail(authentication))) {
databaseUtils.fixConflictDifferents(ids, AuthenticationUtils.extractEmail(authentication));
|| userCountryRepository.verifyAuthorizationForId(ids.get(0), UserInfo.getEmail(authentication))) {
databaseUtils.fixConflictDifferents(ids, UserInfo.getEmail(authentication));
return ids;
} else {
return new ArrayList<>();

View File

@ -20,7 +20,6 @@ import eu.dnetlib.organizations.model.utils.VocabularyTerm;
import eu.dnetlib.organizations.model.view.UserView;
import eu.dnetlib.organizations.repository.UserRepository;
import eu.dnetlib.organizations.repository.readonly.UserViewRepository;
import eu.dnetlib.organizations.utils.AuthenticationUtils;
import eu.dnetlib.organizations.utils.DatabaseUtils;
@RestController
@ -37,7 +36,7 @@ public class UserController {
@PostMapping(value = "/registration_api/newUser")
public Map<String, Integer> newUser(final @RequestBody List<String> countries, final Authentication authentication) {
final String email = AuthenticationUtils.extractEmail(authentication);
final String email = UserInfo.getEmail(authentication);
final Map<String, Integer> res = new HashMap<>();
@ -58,7 +57,7 @@ public class UserController {
// IMPORTANT: a national admin can manage ONLY the users where ALL the countries are under his control
final List<UserView> res = new ArrayList<>();
final List<String> myCountries = dbUtils.listCountriesForUser(AuthenticationUtils.extractEmail(authentication))
final List<String> myCountries = dbUtils.listCountriesForUser(UserInfo.getEmail(authentication))
.stream()
.map(VocabularyTerm::getValue)
.collect(Collectors.toList());
@ -76,14 +75,14 @@ public class UserController {
@PostMapping("/api/users")
public Iterable<UserView> save(@RequestBody final UserView userView, final Authentication authentication) {
if (AuthenticationUtils.extractEmail(authentication).equals(userView.getEmail())) { throw new RuntimeException("You can't edit your own user"); }
if (UserInfo.getEmail(authentication).equals(userView.getEmail())) { throw new RuntimeException("You can't edit your own user"); }
dbUtils.saveUser(userView);
return users(authentication);
}
@DeleteMapping("/api/users")
public Iterable<UserView> delete(final @RequestParam String email, final Authentication authentication) {
if (AuthenticationUtils.extractEmail(authentication).equals(email)) { throw new RuntimeException("You can't delete your own user"); }
if (UserInfo.getEmail(authentication).equals(email)) { throw new RuntimeException("You can't delete your own user"); }
dbUtils.deleteUser(email);
return users(authentication);
}

View File

@ -4,8 +4,7 @@ import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import eu.dnetlib.organizations.utils.AuthenticationUtils;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
public class UserInfo {
@ -39,7 +38,7 @@ public class UserInfo {
}
public static UserInfo generate(final Authentication authentication) {
return new UserInfo(AuthenticationUtils.extractEmail(authentication), findRole(authentication));
return new UserInfo(getEmail(authentication), findRole(authentication));
}
public static UserRole findRole(final Authentication authentication) {
@ -88,4 +87,9 @@ public class UserInfo {
return false;
}
public static String getEmail(final Authentication authentication) {
final Object user = authentication.getPrincipal();
return user instanceof DefaultOidcUser ? ((DefaultOidcUser) user).getEmail() : authentication.getName();
}
}

View File

@ -13,7 +13,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.organizations.model.utils.VocabularyTerm;
import eu.dnetlib.organizations.utils.AuthenticationUtils;
import eu.dnetlib.organizations.utils.DatabaseUtils;
import eu.dnetlib.organizations.utils.DatabaseUtils.VocabularyTable;
import eu.dnetlib.organizations.utils.RelationType;
@ -40,7 +39,7 @@ public class VocabulariesController {
.collect(Collectors.toList()));
if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
vocs.put("countries", databaseUtils.listCountriesForUser(AuthenticationUtils.extractEmail(authentication)));
vocs.put("countries", databaseUtils.listCountriesForUser(UserInfo.getEmail(authentication)));
} else if (UserInfo.isSuperAdmin(authentication)) {
vocs.put("countries", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.countries));
} else {

View File

@ -1,12 +0,0 @@
package eu.dnetlib.organizations.utils;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
public class AuthenticationUtils {
public static String extractEmail(final Authentication authentication) {
final Object user = authentication.getPrincipal();
return user instanceof DefaultOidcUser ? ((DefaultOidcUser) user).getEmail() : authentication.getName();
}
}

View File

@ -1,8 +1,20 @@
package eu.dnetlib.organizations.utils;
import eu.dnetlib.organizations.controller.UserRole;
public class OpenOrgsConstants {
public static final String OPENORGS_PREFIX = "openorgs____::";
public static final String OPENORGS_MESH_PREFIX = "openorgsmesh::";
public static final String OPENORGS_ROLE_PREFIX = "OPENORGS_";
public static final String[] VALID_ROLES = {
OPENORGS_ROLE_PREFIX + UserRole.ADMIN,
OPENORGS_ROLE_PREFIX + UserRole.NATIONAL_ADMIN,
OPENORGS_ROLE_PREFIX + UserRole.USER
};
public static final String NOT_AUTORIZED_ROLE = OPENORGS_ROLE_PREFIX + UserRole.NOT_AUTHORIZED;
}

View File

@ -1,5 +1,7 @@
server.port=8480
#spring.profiles.active=dev
spring.main.banner-mode = off
logging.level.root = INFO

View File

@ -29,7 +29,7 @@
<div class="card-body">
<h5 class="card-title">Already registered</h5>
<p class="card-text" th:inline="text">
Hello <b sec:authentication="principal.email" id="current_user"></b>,<br />
Hello <b th:text="${email}" id="current_user"></b>,<br />
<span sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN') or hasRole('ROLE_OPENORGS_USER')">
You are already registered.
</span>

View File

@ -34,7 +34,7 @@
<div class="card-body">
<h5 class="card-title">Authorization request</h5>
<p class="card-text" th:inline="text">
Hello '<span sec:authentication="principal.email" id="current_user"></span>', you don't have a role yet <br />
Hello '<span th:text="${email}" id="current_user"></span>', you don't have a role yet <br />
To apply as data curator compile the form below, an administrator will authorize you as soon as possible.
</p>

View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="Cache-Control"
content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="resources/css/bootstrap.min.css" />
<title>Organizations Database: Login</title>
</head>
<body>
<div>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<a class="navbar-brand" href="#">
<img src="resources/images/openaire_logo_small.png" width="30" height="30" alt="OpenOrgs Database"> OpenOrgs Database
</a>
</nav>
</div>
<div class="container-fluid">
<div class="row" style="margin-top: 20px">
<div class="col-xs-12 col-sm-10 col-md-8 col-lg-4 offset-sm-1 offset-md-2 offset-lg-4">
<div class="card">
<div class="card-header">
<ul id="tabList" class="nav nav-tabs card-header-tabs">
<li class="nav-item"><a href="#tabLogin" class="nav-link active">Sign In</a></li>
</ul>
</div>
<div class="card-body">
<div class="tab-content">
<div class="tab-pane active" id="tabLogin">
<form th:action="@{/login}" method="post">
<div th:if="${param.error}">
<div class="alert alert-danger">Invalid username and password.</div>
</div>
<div th:if="${param.logout}">
<div class="alert alert-info">You have been logged out.</div>
</div>
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg" placeholder="Email" required="true" autofocus="true" />
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg" placeholder="Password" required="true" />
</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Sign In" />
</div>
<div class="col-xs-6 col-sm-6 col-md-6"></div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="resources/js/jquery-3.4.1.min.js"></script>
<script src="resources/js/popper.min.js"></script>
<script src="resources/js/bootstrap.min.js"></script>
</body>
</html>

View File

@ -111,7 +111,7 @@ fieldset > legend { font-size : 1.2rem !important; }
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown"><i class="fa fa-user"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<p class="px-4 pt-2 text-muted small">
<b>Logged as:</b><br /><span sec:authentication="principal.email" id="current_user"></span><br />
<b>Logged as:</b><br /><span th:text="${email}" id="current_user"></span><br />
<b>Role:</b><br />
<span sec:authorize="hasRole('ROLE_OPENORGS_ADMIN')">Super Admin</span>
<span sec:authorize="hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">National Admin</span>