role remapping

This commit is contained in:
Michele Artini 2020-11-04 12:18:25 +01:00
parent 45015dfe07
commit 7d25ad2928
3 changed files with 56 additions and 56 deletions

View File

@ -1,58 +1,59 @@
package eu.dnetlib.organizations;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
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.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
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 eu.dnetlib.organizations.controller.UserRole;
import eu.dnetlib.organizations.model.User;
import eu.dnetlib.organizations.repository.UserRepository;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// @Autowired
// private DataSource dataSource;
// @Autowired
// private AccessDeniedHandler accessDeniedHandler;
@Autowired
private UserRepository userRepository;
@Value("${openaire.api.valid.subnet}")
private String openaireApiValidSubnet;
// @Autowired
// private ClientRegistrationRepository clientRegistrationRepository;
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
http.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService())));
}
/*
* @Bean public ClientRegistration.Builder clientRegistration() { final Map<String, Object> metadata = new HashMap<>();
* metadata.put("end_session_endpoint", "https://jhipster.org/logout");
*
* return ClientRegistration.withRegistrationId("oidc") .redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
* .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
* .scope("read:user") .authorizationUri("https://jhipster.org/login/oauth/authorize")
* .tokenUri("https://jhipster.org/login/oauth/access_token") .jwkSetUri("https://jhipster.org/oauth/jwk")
* .userInfoUri("https://api.jhipster.org/user") .providerConfigurationMetadata(metadata) .userNameAttributeName("id")
* .clientName("Client Name") .clientId("client-id") .clientSecret("client-secret"); }
*/
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
final OidcUserService delegate = new OidcUserService();
/*
* @Autowired public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication()
* .dataSource(dataSource) .usersByUsernameQuery("select ?, '{MD5}60c4a0eb167dd41e915a885f582414df', true") // TODO: this is a MOCK, the
* user should // be authenticated using the openaire // credentials .authoritiesByUsernameQuery("with const as (SELECT ? as email) " +
* "select c.email, 'ROLE_'||coalesce(u.role, '" + UserRole.NOT_AUTHORIZED +
* "') from const c left outer join users u on (u.email = c.email)"); }
*
* @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }
*/
return (userRequest) -> {
final OidcUser oidcUser = delegate.loadUser(userRequest);
final Optional<User> user = userRepository.findById(oidcUser.getEmail());
final String role = user.isPresent() ? user.get().getRole() : UserRole.PENDING.toString();
final Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_OPENORGS_" + role));
return new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());
};
}
// https://www.baeldung.com/spring-security-openid-connect

View File

@ -44,7 +44,7 @@ public class UserInfo {
return authentication.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.map(s -> StringUtils.substringAfter(s, "ROLE_"))
.map(s -> StringUtils.substringAfter(s, "ROLE_OPENORGS_"))
.filter(s -> EnumUtils.isValidEnum(UserRole.class, s))
.map(UserRole::valueOf)
.findFirst()
@ -53,35 +53,35 @@ public class UserInfo {
public static boolean isSuperAdmin(final Authentication authentication) {
for (final GrantedAuthority aut : authentication.getAuthorities()) {
if (aut.getAuthority().equals("ROLE_" + UserRole.ADMIN)) { return true; }
if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.ADMIN)) { return true; }
}
return false;
}
public static boolean isNationalAdmin(final Authentication authentication) {
for (final GrantedAuthority aut : authentication.getAuthorities()) {
if (aut.getAuthority().equals("ROLE_" + UserRole.NATIONAL_ADMIN)) { return true; }
if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.NATIONAL_ADMIN)) { return true; }
}
return false;
}
public static boolean isSimpleUser(final Authentication authentication) {
for (final GrantedAuthority aut : authentication.getAuthorities()) {
if (aut.getAuthority().equals("ROLE_" + UserRole.USER)) { return true; }
if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.USER)) { return true; }
}
return false;
}
public static boolean isPending(final Authentication authentication) {
for (final GrantedAuthority aut : authentication.getAuthorities()) {
if (aut.getAuthority().equals("ROLE_" + UserRole.PENDING)) { return true; }
if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.PENDING)) { return true; }
}
return false;
}
public static boolean isNotAuthorized(final Authentication authentication) {
for (final GrantedAuthority aut : authentication.getAuthorities()) {
if (aut.getAuthority().equals("ROLE_" + UserRole.NOT_AUTHORIZED)) { return true; }
if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.NOT_AUTHORIZED)) { return true; }
}
return false;
}

View File

@ -67,13 +67,13 @@ fieldset > legend { font-size : 1.2rem !important; }
<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_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">browse by country</a>
<a class="dropdown-item" href="#!/countries/0" sec:authorize="hasRole('ROLE_USER')">browse by country</a>
<a class="dropdown-item" href="#!/types/1" sec:authorize="hasRole('ROLE_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">browse by type</a>
<a class="dropdown-item" href="#!/types/0" sec:authorize="hasRole('ROLE_USER')">browse by type</a>
<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_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">
<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>
@ -81,19 +81,19 @@ fieldset > legend { font-size : 1.2rem !important; }
<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_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">
<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_USER')">
<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_USER')">
<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>
@ -101,7 +101,7 @@ fieldset > legend { font-size : 1.2rem !important; }
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">
<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>
@ -124,28 +124,27 @@ fieldset > legend { font-size : 1.2rem !important; }
</nav>
<p sec:authentication="principal"></p>
<div class="container-fluid small mt-4" ng-view></div>
<script sec:authorize="hasRole('ROLE_ADMIN')">
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN')">
function superAdminMode() { return true; }
</script>
<script sec:authorize="!hasRole('ROLE_ADMIN')">
<script sec:authorize="!hasRole('ROLE_OPENORGS_ADMIN')">
function superAdminMode() { return false; }
</script>
<script sec:authorize="hasRole('ROLE_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">
<script sec:authorize="hasRole('ROLE_OPENORGS_ADMIN') or hasRole('ROLE_OPENORGS_NATIONAL_ADMIN')">
function adminMode() { return true; }
</script>
<script sec:authorize="!hasRole('ROLE_ADMIN') and !hasRole('ROLE_NATIONAL_ADMIN')">
<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;
}
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>