logout and homepage
This commit is contained in:
parent
6a5488811e
commit
94637fe6dd
|
@ -1,44 +0,0 @@
|
|||
package eu.dnetlib.organizations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import eu.dnetlib.organizations.controller.UserInfo;
|
||||
import eu.dnetlib.organizations.utils.AuthenticationUtils;
|
||||
|
||||
@Component
|
||||
public class MyAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class);
|
||||
|
||||
@Override
|
||||
public void handle(final HttpServletRequest req, final HttpServletResponse res, final AccessDeniedException e)
|
||||
throws IOException, ServletException {
|
||||
|
||||
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.getRemoteAddr(), req
|
||||
.getRequestURI()));
|
||||
}
|
||||
|
||||
if (UserInfo.isNotAuthorized(authentication)) {
|
||||
res.sendRedirect(req.getContextPath() + "/authorizationRequest");
|
||||
} else {
|
||||
res.sendRedirect(req.getContextPath() + "/alreadyRegistered");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,24 +4,32 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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.Configuration;
|
||||
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.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
|
||||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
||||
import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
||||
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
|
||||
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||
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.repository.UserRepository;
|
||||
import eu.dnetlib.organizations.utils.AuthenticationUtils;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
|
@ -31,13 +39,15 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
private UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
private AccessDeniedHandler accessDeniedHandler;
|
||||
private ClientRegistrationRepository clientRegistrationRepository;
|
||||
|
||||
@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,
|
||||
|
@ -48,15 +58,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
|
||||
http.csrf()
|
||||
.disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/", "/api/**")
|
||||
.antMatchers("/main", "/api/**")
|
||||
.hasAnyRole(VALID_ROLES)
|
||||
.antMatchers("/registration_api/**")
|
||||
.hasRole(NOT_AUTORIZED_ROLE)
|
||||
.antMatchers("/resources/**", "/webjars/**")
|
||||
.antMatchers("/", "/resources/**", "/webjars/**")
|
||||
.permitAll()
|
||||
.antMatchers("/oa_api/**")
|
||||
.hasIpAddress(openaireApiValidSubnet)
|
||||
|
@ -64,10 +73,33 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
.authenticated()
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
.accessDeniedHandler(accessDeniedHandler)
|
||||
.accessDeniedHandler(accessDeniedHandler())
|
||||
.and()
|
||||
.logout()
|
||||
.logoutSuccessHandler(oidcLogoutSuccessHandler())
|
||||
.and()
|
||||
.oauth2Login(oauth2 -> oauth2.userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService())));
|
||||
}
|
||||
|
||||
private AccessDeniedHandler accessDeniedHandler() {
|
||||
return (req, res, e) -> {
|
||||
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
|
||||
.getRemoteAddr(), req.getRequestURI()));
|
||||
}
|
||||
|
||||
if (UserInfo.isNotAuthorized(authentication)) {
|
||||
res.sendRedirect(req.getContextPath() + "/authorizationRequest");
|
||||
} else {
|
||||
res.sendRedirect(req.getContextPath() + "/alreadyRegistered");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() {
|
||||
return new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
|
||||
}
|
||||
|
||||
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
|
||||
|
|
|
@ -11,6 +11,11 @@ public class HomeController {
|
|||
return "home";
|
||||
}
|
||||
|
||||
@GetMapping("/main")
|
||||
public String main() {
|
||||
return "main";
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
return "login";
|
||||
|
|
|
@ -1,229 +1,78 @@
|
|||
<!doctype html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<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 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" />
|
||||
<!-- Icons CSS -->
|
||||
<link rel="stylesheet" href="resources/css/fontawesome-all.min.css">
|
||||
|
||||
<style type="text/css">
|
||||
.table > tbody > tr > td { vertical-align : middle !important; }
|
||||
.card > .table { margin-bottom : 0 !important; }
|
||||
fieldset > legend { font-size : 1.2rem !important; }
|
||||
.overlaydiv {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.grayRectangle {
|
||||
position: absolute;
|
||||
background-color: black;
|
||||
opacity:0.6;
|
||||
top: 30%;
|
||||
left: 40%;
|
||||
width: 20%;
|
||||
height: 20%;
|
||||
z-index: 100;
|
||||
border-radius: 15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<title>Organizations Database</title>
|
||||
|
||||
<title>Organizations Database: Login</title>
|
||||
</head>
|
||||
|
||||
<body ng-app="orgs" sec:authorize="isAuthenticated()">
|
||||
<body>
|
||||
|
||||
<div id="spinnerdiv" class="overlaydiv">
|
||||
<span class="grayRectangle"><!--The spinner is added on loading here--></span>
|
||||
<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>
|
||||
<li class="nav-item"><a href="#tabRegister" class="nav-link">Info</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active text-center p-5" id="tabLogin">
|
||||
<a href="./main" class="btn btn-lg btn-primary">Access using OpenAIRE credentials</a>
|
||||
</div>
|
||||
<div class="tab-pane" id="tabRegister">
|
||||
<h4 class="card-title">Access Guide</h4>
|
||||
<div id="registerMessage">
|
||||
<p class="card-text mb-4">
|
||||
To use this service you have to perform the following steps:
|
||||
<ol>
|
||||
<li>Register on the OpenAIRE portal.</li>
|
||||
<li>Login using the OpenAIRE credentials</li>
|
||||
<li>Compile the Authorization Request Form</li>
|
||||
<li>An administrator will authorize you as soon as possible</li>
|
||||
</ol>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary" ng-controller="menuCtrl">
|
||||
<a class="navbar-brand" href="#"> <img
|
||||
src="resources/images/openaire_logo_small.png" width="30" height="30" alt="OpenOrgs Database">
|
||||
OpenOrgs Database
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarSupportedContent">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse w-100 order-1" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Search</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/search">simple search</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#!/countries/1" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">browse by country</a>
|
||||
<a class="dropdown-item" href="#!/countries/0" sec:authorize="hasRole('ROLE_OPENORGS_USER')">browse by country</a>
|
||||
<a class="dropdown-item" href="#!/types/1" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">browse by type</a>
|
||||
<a class="dropdown-item" href="#!/types/0" sec:authorize="hasRole('ROLE_OPENORGS_USER')">browse by type</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Curation</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/pendings/_"><span class="pr-2">suggested</span><span class="badge badge-primary badge-pill">{{info.data.total.nPendingOrgs}}</span></a>
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">new duplicates</span><span class="badge badge-primary badge-pill">{{info.data.total.nDuplicates}}</span></a>
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/conflicts/_"><span class="pr-2">potential conflicts</span><span class="badge badge-danger badge-pill">{{info.data.total.nConflicts}}</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">New</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/new">new organization</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_USER')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Curation</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">new duplicates</span><span class="badge badge-primary badge-pill">{{info.data.total.nDuplicates}}</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_USER')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Suggest</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/new">suggest a new organization</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown"><i class="fa fa-cog"></i></a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item" href="#!/users">manage users</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<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>Role:</b><br /><span sec:authentication="principal.authorities"></span>
|
||||
</p>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" th:href="@{/logout}">Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" href="doc" target="_blank">API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid small mt-4" ng-view></div>
|
||||
|
||||
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN')">
|
||||
function superAdminMode() { return true; }
|
||||
</script>
|
||||
<script sec:authorize="!hasRole('ROLE_OPENORGS_ADMIN')">
|
||||
function superAdminMode() { return false; }
|
||||
</script>
|
||||
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
function adminMode() { return true; }
|
||||
</script>
|
||||
<script sec:authorize="!hasRole('ROLE_OPENORGS_ADMIN') and !hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
function adminMode() { return false; }
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function currentUser() { return document.getElementById('current_user').textContent; }
|
||||
</script>
|
||||
|
||||
<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>
|
||||
<script src="resources/js/angular.min.js"></script>
|
||||
<script src="resources/js/angular-route.min.js"></script>
|
||||
<script src='resources/js/checklist-model.js'></script>
|
||||
<script src="resources/js/organizations.js"></script>
|
||||
<script src="resources/js/spin.js"></script>
|
||||
|
||||
<script>
|
||||
// Spinner show/hide methods ~ Andrea Mannocci
|
||||
var spinnerOpts = {
|
||||
lines: 15,
|
||||
length: 16,
|
||||
width: 5,
|
||||
radius: 25,
|
||||
color: '#eeeeee',
|
||||
className: 'spinner',
|
||||
top: '40%'
|
||||
};
|
||||
|
||||
var spinnerTarget = document.getElementById('spinnerdiv');
|
||||
|
||||
var spinner;
|
||||
|
||||
function showSpinner() {
|
||||
spinner = new Spinner(spinnerOpts).spin(spinnerTarget);
|
||||
spinnerTarget.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
function hideSpinner() {
|
||||
spinnerTarget.style.visibility = 'hidden';
|
||||
spinner.stop();
|
||||
}
|
||||
|
||||
function call_http_get($http, url, onSuccess) {
|
||||
showSpinner();
|
||||
$http.get(url).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
|
||||
function call_http_post($http, url, obj, onSuccess) {
|
||||
showSpinner();
|
||||
$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
|
||||
$http.post(url, obj).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if ((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
|
||||
function call_http_delete($http, url, onSuccess) {
|
||||
showSpinner();
|
||||
$http.delete(url).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if ((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
$('#tabList a').on('click', function (e) {
|
||||
e.preventDefault()
|
||||
$(this).tab('show')
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,98 +0,0 @@
|
|||
<!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>
|
||||
<li class="nav-item"><a href="#tabRegister" class="nav-link">Register</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="tabLogin">
|
||||
<h4 class="card-title">Please Sign In</h4>
|
||||
<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 class="tab-pane" id="tabRegister">
|
||||
<h4 class="card-title">Register</h4>
|
||||
<div id="registerMessage">
|
||||
<p class="card-text mb-4">
|
||||
To use this service you have to perform the following steps:
|
||||
<ol>
|
||||
<li>Register on the OpenAIRE portal.</li>
|
||||
<li>Login using the OpenAIRE credentials</li>
|
||||
<li>Compile the Authorization Request Form</li>
|
||||
<li>An administrator will authorize you as soon as possible</li>
|
||||
</ol>
|
||||
</p>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<script>
|
||||
$('#tabList a').on('click', function (e) {
|
||||
e.preventDefault()
|
||||
$(this).tab('show')
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,229 @@
|
|||
<!doctype html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<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" />
|
||||
<!-- Icons CSS -->
|
||||
<link rel="stylesheet" href="resources/css/fontawesome-all.min.css">
|
||||
|
||||
<style type="text/css">
|
||||
.table > tbody > tr > td { vertical-align : middle !important; }
|
||||
.card > .table { margin-bottom : 0 !important; }
|
||||
fieldset > legend { font-size : 1.2rem !important; }
|
||||
.overlaydiv {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.grayRectangle {
|
||||
position: absolute;
|
||||
background-color: black;
|
||||
opacity:0.6;
|
||||
top: 30%;
|
||||
left: 40%;
|
||||
width: 20%;
|
||||
height: 20%;
|
||||
z-index: 100;
|
||||
border-radius: 15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<title>Organizations Database</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body ng-app="orgs" sec:authorize="isAuthenticated()">
|
||||
|
||||
<div id="spinnerdiv" class="overlaydiv">
|
||||
<span class="grayRectangle"><!--The spinner is added on loading here--></span>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary" ng-controller="menuCtrl">
|
||||
<a class="navbar-brand" href="#"> <img
|
||||
src="resources/images/openaire_logo_small.png" width="30" height="30" alt="OpenOrgs Database">
|
||||
OpenOrgs Database
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarSupportedContent">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse w-100 order-1" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Search</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/search">simple search</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#!/countries/1" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">browse by country</a>
|
||||
<a class="dropdown-item" href="#!/countries/0" sec:authorize="hasRole('ROLE_OPENORGS_USER')">browse by country</a>
|
||||
<a class="dropdown-item" href="#!/types/1" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">browse by type</a>
|
||||
<a class="dropdown-item" href="#!/types/0" sec:authorize="hasRole('ROLE_OPENORGS_USER')">browse by type</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Curation</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/pendings/_"><span class="pr-2">suggested</span><span class="badge badge-primary badge-pill">{{info.data.total.nPendingOrgs}}</span></a>
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">new duplicates</span><span class="badge badge-primary badge-pill">{{info.data.total.nDuplicates}}</span></a>
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/conflicts/_"><span class="pr-2">potential conflicts</span><span class="badge badge-danger badge-pill">{{info.data.total.nConflicts}}</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">New</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/new">new organization</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_USER')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Curation</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">new duplicates</span><span class="badge badge-primary badge-pill">{{info.data.total.nDuplicates}}</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_USER')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Suggest</a>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#!/new">suggest a new organization</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown"><i class="fa fa-cog"></i></a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item" href="#!/users">manage users</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<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>Role:</b><br /><span sec:authentication="principal.authorities"></span>
|
||||
</p>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" th:href="@{/logout}">Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" href="doc" target="_blank">API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid small mt-4" ng-view></div>
|
||||
|
||||
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN')">
|
||||
function superAdminMode() { return true; }
|
||||
</script>
|
||||
<script sec:authorize="!hasRole('ROLE_OPENORGS_ADMIN')">
|
||||
function superAdminMode() { return false; }
|
||||
</script>
|
||||
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
function adminMode() { return true; }
|
||||
</script>
|
||||
<script sec:authorize="!hasRole('ROLE_OPENORGS_ADMIN') and !hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
|
||||
function adminMode() { return false; }
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function currentUser() { return document.getElementById('current_user').textContent; }
|
||||
</script>
|
||||
|
||||
<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>
|
||||
<script src="resources/js/angular.min.js"></script>
|
||||
<script src="resources/js/angular-route.min.js"></script>
|
||||
<script src='resources/js/checklist-model.js'></script>
|
||||
<script src="resources/js/organizations.js"></script>
|
||||
<script src="resources/js/spin.js"></script>
|
||||
|
||||
<script>
|
||||
// Spinner show/hide methods ~ Andrea Mannocci
|
||||
var spinnerOpts = {
|
||||
lines: 15,
|
||||
length: 16,
|
||||
width: 5,
|
||||
radius: 25,
|
||||
color: '#eeeeee',
|
||||
className: 'spinner',
|
||||
top: '40%'
|
||||
};
|
||||
|
||||
var spinnerTarget = document.getElementById('spinnerdiv');
|
||||
|
||||
var spinner;
|
||||
|
||||
function showSpinner() {
|
||||
spinner = new Spinner(spinnerOpts).spin(spinnerTarget);
|
||||
spinnerTarget.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
function hideSpinner() {
|
||||
spinnerTarget.style.visibility = 'hidden';
|
||||
spinner.stop();
|
||||
}
|
||||
|
||||
function call_http_get($http, url, onSuccess) {
|
||||
showSpinner();
|
||||
$http.get(url).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
|
||||
function call_http_post($http, url, obj, onSuccess) {
|
||||
showSpinner();
|
||||
$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
|
||||
$http.post(url, obj).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if ((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
|
||||
function call_http_delete($http, url, onSuccess) {
|
||||
showSpinner();
|
||||
$http.delete(url).then(function successCallback(res) {
|
||||
hideSpinner();
|
||||
if ((typeof res.data) == 'string') {
|
||||
alert("Session expired !"); location.reload(true);
|
||||
} else {
|
||||
onSuccess(res);
|
||||
}
|
||||
}, function errorCallback(res) {
|
||||
hideSpinner();
|
||||
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue