Project

General

Profile

« Previous | Next » 

Revision 57650

new registration form

View differences:

modules/dnet-orgs-database-application/trunk/src/main/resources/templates/403.html
1
<!DOCTYPE HTML>
2
<html xmlns:th="http://www.thymeleaf.org">
3

  
4
<head>
5
	<meta charset="utf-8">
6
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
	<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8
	<meta http-equiv="Pragma" content="no-cache">
9
	<meta http-equiv="Expires" content="0">
10

  
11
	<!-- Bootstrap CSS -->
12
	<link rel="stylesheet" href="resources/css/bootstrap.min.css" />
13
	
14
	<title>Organizations Database: not authorized</title>
15
</head>
16

  
17
<body>
18

  
19
	<div class="container">
20
		<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
21
			<a class="navbar-brand" href="#"> 
22
				<img src="resources/images/openaire_logo_small.png" width="30" height="30" alt="OpenOrgs Database"> OpenOrgs Database
23
			</a>
24
		</nav>
25
	    	    
26
	    <div class="card text-center" style="margin-top: 25px">
27
			<div class="card-body">
28
				<h5 class="card-title">403 - Access is denied</h5>
29
				<p class="card-text" th:inline="text">Hello '[[${#httpServletRequest.remoteUser}]]', you do not have permission to access this page.</p>
30
			</div>
31
		</div>
32
	</div>
33

  
34
	<script src="resources/js/jquery-3.4.1.min.js"></script>
35
	<script src="resources/js/popper.min.js"></script>
36
	<script src="resources/js/bootstrap.min.js"></script>
37

  
38
</body>
39

  
40
</html>
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/model/User.java
20 20
	@Column(name = "email")
21 21
	private String email;
22 22

  
23
	@Column(name = "password")
24
	private String password;
25

  
26 23
	@Column(name = "valid")
27 24
	private boolean valid;
28 25

  
......
37 34
		this.email = email;
38 35
	}
39 36

  
40
	public String getPassword() {
41
		return password;
42
	}
43

  
44
	public void setPassword(final String password) {
45
		this.password = password;
46
	}
47

  
48 37
	public boolean isValid() {
49 38
		return valid;
50 39
	}
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/utils/DatabaseUtils.java
1 1
package eu.dnetlib.organizations.utils;
2 2

  
3 3
import java.time.OffsetDateTime;
4
import java.util.Arrays;
4 5
import java.util.List;
6
import java.util.stream.Collectors;
5 7

  
6 8
import javax.transaction.Transactional;
7 9

  
......
131 133

  
132 134
	@Transactional
133 135
	public void saveUser(@RequestBody final UserView userView) {
134

  
135 136
		final User user = userRepository.findById(userView.getEmail()).orElseThrow(() -> new RuntimeException("User not found"));
136 137
		user.setRole(userView.getRole());
137 138
		user.setValid(userView.isValid());
138 139
		userRepository.save(user);
139

  
140 140
		userCountryRepository.deleteByEmail(userView.getEmail());
141
		for (final String country : userView.getCountries()) {
142
			userCountryRepository.save(new UserCountry(userView.getEmail(), country));
141
		if (userView.getCountries() != null) {
142
			userCountryRepository
143
					.saveAll(Arrays.stream(userView.getCountries()).map(c -> new UserCountry(userView.getEmail(), c)).collect(Collectors.toList()));
143 144
		}
144 145
	}
145 146

  
......
149 150
		userRepository.deleteById(email);
150 151
	}
151 152

  
153
	@Transactional
154
	public void newUser(final String email, final List<String> countries) {
155
		final User user = new User();
156
		user.setEmail(email);
157
		user.setRole(OpenOrgsConstants.pendingRole);
158
		user.setValid(false);
159
		userRepository.save(user);
160
		if (countries != null) {
161
			userCountryRepository.saveAll(countries.stream().map(c -> new UserCountry(email, c)).collect(Collectors.toList()));
162
		}
163
	}
164

  
152 165
}
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/utils/OpenOrgsConstants.java
5 5
	public static final String userRole = "USER";
6 6
	public static final String superUserRole = "SUPERUSER";
7 7
	public static final String pendingRole = "PENDING";
8
	public static final String notAuthorizedRole = "NOTAUTHORIZED";
8 9

  
9 10
	public static final String OPENORGS_PREFIX = "openorgs____::";
10 11
	public static final String OPENORGS_MESH_PREFIX = "openorgsmesh::";
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/controller/UserController.java
1 1
package eu.dnetlib.organizations.controller;
2 2

  
3 3
import java.util.HashMap;
4
import java.util.List;
4 5
import java.util.Map;
5 6

  
6
import org.apache.commons.codec.digest.DigestUtils;
7 7
import org.springframework.beans.factory.annotation.Autowired;
8 8
import org.springframework.security.core.Authentication;
9 9
import org.springframework.web.bind.annotation.DeleteMapping;
......
13 13
import org.springframework.web.bind.annotation.RequestParam;
14 14
import org.springframework.web.bind.annotation.RestController;
15 15

  
16
import eu.dnetlib.organizations.model.User;
17 16
import eu.dnetlib.organizations.model.view.UserView;
18 17
import eu.dnetlib.organizations.repository.UserRepository;
19 18
import eu.dnetlib.organizations.repository.readonly.UserViewRepository;
20 19
import eu.dnetlib.organizations.utils.DatabaseUtils;
21
import eu.dnetlib.organizations.utils.OpenOrgsConstants;
22 20

  
23 21
@RestController
24 22
public class UserController {
25 23

  
26
	private static final String DEFAULT_PASSWORD = "dnet";
27

  
28 24
	@Autowired
29 25
	private UserRepository userRepository;
26

  
30 27
	@Autowired
31 28
	private UserViewRepository userViewRepository;
32 29
	@Autowired
33 30
	private DatabaseUtils dbUtils;
34 31

  
35 32
	@PostMapping(value = "/public_api/newUser")
36
	public Map<String, Integer> newUser(final @RequestParam String email) {
33
	public Map<String, Integer> newUser(final @RequestBody List<String> countries, final Authentication authentication) {
34

  
35
		final String email = authentication.getName();
36

  
37 37
		final Map<String, Integer> res = new HashMap<>();
38
		if (userRepository.existsById(email)) {
38

  
39
		if (!UserInfo.isNotAuthorized(authentication) || userRepository.existsById(email)) {
39 40
			res.put("status", 2);
40 41
		} else {
41
			final User user = new User();
42
			user.setEmail(email);
43
			user.setPassword("{MD5}" + DigestUtils.md5Hex(DEFAULT_PASSWORD));
44
			user.setRole(OpenOrgsConstants.pendingRole);
45
			user.setValid(false);
46
			userRepository.save(user);
42
			dbUtils.newUser(email, countries);
47 43
			res.put("status", 1);
48 44
		}
49 45
		return res;
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/controller/VocabulariesController.java
8 8

  
9 9
import org.springframework.beans.factory.annotation.Autowired;
10 10
import org.springframework.security.core.Authentication;
11
import org.springframework.web.bind.annotation.RequestMapping;
12
import org.springframework.web.bind.annotation.RequestMethod;
11
import org.springframework.web.bind.annotation.GetMapping;
13 12
import org.springframework.web.bind.annotation.RestController;
14 13

  
15 14
import eu.dnetlib.organizations.utils.DatabaseUtils;
......
18 17
import eu.dnetlib.organizations.utils.SimilarityType;
19 18

  
20 19
@RestController
21
@RequestMapping("/api/vocabularies")
22 20
public class VocabulariesController {
23 21

  
24 22
	@Autowired
25 23
	private DatabaseUtils databaseUtils;
26 24

  
27
	@RequestMapping(value = "", method = RequestMethod.GET)
25
	@GetMapping({ "/api/vocabularies", "/public_api/vocabularies" })
28 26
	public Map<String, List<String>> ListVocabularies(final Authentication authentication) {
29 27
		final Map<String, List<String>> vocs = new HashMap<>();
30 28
		vocs.put("orgTypes", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.org_types));
......
34 32
		vocs.put("relTypes", Arrays.stream(RelationType.values()).map(Object::toString).collect(Collectors.toList()));
35 33
		vocs.put("similaritiesType", Arrays.stream(SimilarityType.values()).map(Object::toString).collect(Collectors.toList()));
36 34

  
37
		if (UserInfo.isSuperUser(authentication)) {
35
		if (UserInfo.isSimpleUser(authentication)) {
36
			vocs.put("countries", databaseUtils.listCountriesForUser(authentication.getName()));
37
		} else {
38 38
			vocs.put("countries", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.countries));
39
		} else {
40
			vocs.put("countries", databaseUtils.listCountriesForUser(authentication.getName()));
41 39
		}
42 40

  
43 41
		return vocs;
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/controller/UserInfo.java
42 42

  
43 43
	public static boolean isSuperUser(final Authentication authentication) {
44 44
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
45

  
46 45
			if (aut.getAuthority().equals("ROLE_" + OpenOrgsConstants.superUserRole)) { return true; }
47 46
		}
48 47
		return false;
49 48
	}
50 49

  
50
	public static boolean isSimpleUser(final Authentication authentication) {
51
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
52
			if (aut.getAuthority().equals("ROLE_" + OpenOrgsConstants.userRole)) { return true; }
53
		}
54
		return false;
55
	}
56

  
57
	public static boolean isPending(final Authentication authentication) {
58
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
59
			if (aut.getAuthority().equals("ROLE_" + OpenOrgsConstants.pendingRole)) { return true; }
60
		}
61
		return false;
62
	}
63

  
64
	public static boolean isNotAuthorized(final Authentication authentication) {
65
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
66
			if (aut.getAuthority().equals("ROLE_" + OpenOrgsConstants.notAuthorizedRole)) { return true; }
67
		}
68
		return false;
69
	}
70

  
51 71
}
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/controller/HomeController.java
18 18
		return "/login";
19 19
	}
20 20

  
21
	@GetMapping("/403")
22
	public String error403() {
23
		return "/403";
21
	@GetMapping("/authorizationRequest")
22
	public String authorizationRequest() {
23
		return "/authorizationRequest";
24 24
	}
25 25

  
26 26
	@RequestMapping(value = { "/doc", "/swagger" }, method = RequestMethod.GET)
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/WebSecurityConfig.java
33 33
				.authorizeRequests()
34 34
				.antMatchers("/", "/api/**")
35 35
				.hasAnyRole(OpenOrgsConstants.userRole, OpenOrgsConstants.superUserRole)
36
				.antMatchers("/public_api/**")
37
				.hasRole(OpenOrgsConstants.notAuthorizedRole)
36 38
				.antMatchers("/resources/**", "/webjars/**", "/public_api/**")
37 39
				.permitAll()
38 40
				.anyRequest()
......
56 58
				.usersByUsernameQuery("select ?, '{MD5}60c4a0eb167dd41e915a885f582414df', true")  // TODO: this is a MOCK, the user should
57 59
																								  // be authenticated using the openaire
58 60
																								  // credentials
59
				.authoritiesByUsernameQuery("with const as (SELECT ? as email) select c.email, coalesce(u.role, 'UNAUTHORIZED') from const c left outer join users u on (u.email = c.email)");
61
				.authoritiesByUsernameQuery("with const as (SELECT ? as email) select c.email, 'ROLE_'||coalesce(u.role, 'NOTAUTHORIZED') from const c left outer join users u on (u.email = c.email)");
60 62
	}
61 63

  
62 64
	@Bean
modules/dnet-orgs-database-application/trunk/src/main/java/eu/dnetlib/organizations/MyAccessDeniedHandler.java
29 29
			logger.warn(String.format("User '%s' attempted to access the protected URL: %s", auth.getName(), httpServletRequest.getRequestURI()));
30 30
		}
31 31

  
32
		httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403");
32
		httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/authorizationRequest");
33 33
	}
34 34

  
35 35
}
modules/dnet-orgs-database-application/trunk/src/main/resources/sql/samples.sql
1
INSERT INTO users(email, password, valid, role) VALUES ('michele', '{MD5}'||MD5('dnet'), true, 'SUPERUSER');
2
INSERT INTO users(email, password, valid, role) VALUES ('claudio', '{MD5}'||MD5('dnet'), true, 'SUPERUSER');
3
INSERT INTO users(email, password, valid, role) VALUES ('emma',    '{MD5}'||MD5('dnet'), true, 'USER');
4
INSERT INTO users(email, password, valid, role) VALUES ('paolo',   '{MD5}'||MD5('dnet'), true, 'USER');
5

  
6
INSERT INTO user_countries VALUES ('emma', 'IT');
7
INSERT INTO user_countries VALUES ('paolo', 'IT');
8
INSERT INTO user_countries VALUES ('paolo', 'GR');
9
INSERT INTO user_countries VALUES ('paolo', 'GB');
10
INSERT INTO user_countries VALUES ('paolo', 'US');
1
INSERT INTO users(email, valid, role) VALUES ('michele.artini@isti.cnr.it', '{MD5}'||MD5('dnet'), true, 'SUPERUSER');
modules/dnet-orgs-database-application/trunk/src/main/resources/sql/schema.sql
52 52

  
53 53
CREATE TABLE users (
54 54
	email     text PRIMARY KEY,
55
	password  text NOT NULL,
56 55
	valid     boolean DEFAULT true,
57 56
	role      text NOT NULL default 'USER' REFERENCES user_roles(role)
58 57
);
modules/dnet-orgs-database-application/trunk/src/main/resources/templates/home.html
70 70
					<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown"><i class="fa fa-user"></i></a>
71 71
					<div class="dropdown-menu dropdown-menu-right">
72 72
						<p class="px-4 pt-2 text-muted small">
73
							<b>Logged as:</b><br /><span sec:authentication="name"></span>
73
							<b>Logged as:</b><br /><span sec:authentication="name"></span><br />
74 74
							<b>Role:</b><br /><span sec:authentication="principal.authorities"></span>
75 75
						</p>
76 76
						<div class="dropdown-divider"></div>
modules/dnet-orgs-database-application/trunk/src/main/resources/templates/login.html
66 66
							<div class="tab-pane" id="tabRegister">
67 67
								<h4 class="card-title">Register</h4>
68 68
								<div id="registerMessage">
69
									<p class="card-text mb-4">Insert the email used to access the OpenAIRE portal. An administrator will authorize you as soon as possible.</p>
69
									<p class="card-text mb-4">
70
										To use this service you have to perform the following steps:
71
										<ol>
72
											<li>Register your self on the OpenAIRE portal.</li>
73
											<li>Use the same credentials to access to the this tool</li>
74
											<li>Compile the Authorization Request Form</li>
75
											<li>An administrator will auhorize you as soon as possible</li>
76
										</ol>	
77
									</p>
70 78
								</div>
71
								<form method="post">
72
									<div class="form-group">
73
										<input type="text" name="email" id="email" class="form-control input-lg" placeholder="Email" required="true" autofocus="true" />
74
									</div>
75
									<div class="row">
76
										<div class="col-xs-6 col-sm-6 col-md-6">
77
											<input type="button" id="btnRegister" class="btn btn-lg btn-primary btn-block" value="Register" onclick="register(this.form.email.value)" />
78
										</div>
79
										<div class="col-xs-6 col-sm-6 col-md-6"></div>
80
									</div>
81
								</form>
82 79
							</div>
83 80
						</div>
84 81
					</div>
......
96 93
			e.preventDefault()
97 94
			$(this).tab('show')
98 95
		});
99
	
100
		function register(email) {
101
			$('#btnRegister').attr("disabled", "disabled");
102
			
103
			$.post("public_api/newUser", { 'email': email }, function(data, textStatus) {
104
				if (textStatus == 'success' && data.status == 1) {
105
					$('#registerMessage').html('<div class="alert alert-info">Registration saved !</div>');
106
				} else if (textStatus == 'success' && data.status == 2) {
107
					$('#registerMessage').html('<div class="alert alert-warning">User already registered !</div>');
108
					$('#btnRegister').removeAttr("disabled");
109
				} else {
110
					$('#registerMessage').html('<div class="alert alert-danger">Error saving registration !</div>');
111
				}
112
			}, 'json');
113
		}
114 96
	</script>
115 97
</body>
116 98
</html>
modules/dnet-orgs-database-application/trunk/src/main/resources/templates/authorizationRequest.html
1
<!DOCTYPE HTML>
2
<html xmlns:th="http://www.thymeleaf.org">
3

  
4
<head>
5
	<meta charset="utf-8">
6
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
	<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8
	<meta http-equiv="Pragma" content="no-cache">
9
	<meta http-equiv="Expires" content="0">
10
	
11
	<!-- Bootstrap CSS -->
12
	<link rel="stylesheet" href="resources/css/bootstrap.min.css" />
13
	<!-- Icons CSS -->
14
	<link rel="stylesheet" href="resources/css/fontawesome-all.min.css">
15
	
16
	<title>Organizations Database: authorization request</title>
17
</head>
18

  
19
<body ng-app="authReqApp" ng-controller="authReqCtrl">
20

  
21
	<div class="container">
22
		<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
23
			<a class="navbar-brand" href="#"> 
24
				<img src="resources/images/openaire_logo_small.png" width="30" height="30" alt="OpenOrgs Database"> OpenOrgs Database
25
			</a>
26
		</nav>
27
		
28
		<div ng-if="registrationMessage">
29
			<div class="alert" style="margin-top: 25px" ng-class="{'alert-info': registrationStatus == 1, 'alert-warning': registrationStatus == 2, 'alert-danger': registrationStatus == -1}">{{registrationMessage}}</div>
30
			<a class="btn btn-sm btn-primary" th:href="@{/logout}">return to login form</a>
31
		</div>		
32

  
33
	    <div class="card" style="margin-top: 25px" ng-if="registrationStatus == 0">
34
			<div class="card-body">
35
				<h5 class="card-title">Authorization request</h5>
36
				<p class="card-text" th:inline="text">
37
					Hello '[[${#httpServletRequest.remoteUser}]]', you do not have permission to ... <br />
38
					If you want to contribute to ... compile the form, an administrator will authorize you as soon as possible.
39
				</p>	
40
		
41
				<form class="small">
42
					<div class="card" style="margin-top: 25px">
43
						<div class="card-header">Select your countries</div>
44
							
45
						<div class="card-body">
46
							<div class="form-group row">
47
								<div class="col-sm-2" ng-repeat="c in vocs.countries">
48
									<div class="form-check form-check-inline">
49
										<input class="form-check-input" type="checkbox" checklist-model="countries" checklist-value="c"/>
50
										<label class="form-check-label">{{c}}</label>
51
									</div>
52
								</div>
53
							</div>
54
						</div>
55
							
56
						<div class="card-footer">
57
							<button id="btnRegister" class="btn btn-sm btn-primary" ng-click="register()">send request</button>
58
							<a class="btn btn-sm btn-danger" th:href="@{/logout}">abort request</a>
59
						</div>
60
					</div>
61
				</form>
62

  
63
			</div>
64
		</div>
65
	</div>
66

  
67
	<script src="resources/js/jquery-3.4.1.min.js"></script>
68
	<script src="resources/js/popper.min.js"></script>
69
	<script src="resources/js/bootstrap.min.js"></script>
70
	<script src="resources/js/jquery-3.4.1.min.js"></script>
71
	<script src="resources/js/popper.min.js"></script>
72
	<script src="resources/js/bootstrap.min.js"></script>
73
	<script src="resources/js/angular.min.js"></script>
74
	<script src='resources/js/checklist-model.js'></script>
75

  
76
	<script>
77
	angular.module('authReqApp', ['checklist-model']).controller('authReqCtrl', function($scope, $http) {
78
		$scope.vocs = {};
79
		$scope.countries = [];
80
		$scope.registrationStatus = 0;
81
		$scope.registrationMessage = '';
82
		
83
		$http.get('public_api/vocabularies').then(function successCallback(res) {
84
			$scope.vocs = res.data;
85
		}, function errorCallback(res) {
86
			alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
87
		});
88
		
89
		$scope.register = function (email) {
90
			$('#btnRegister').attr("disabled", "disabled");
91
			$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
92
			$http.post('public_api/newUser', $scope.countries).then(function successCallback(res) {
93
				$scope.registrationStatus = res.data.status;
94
				if (res.data.status == 1) {
95
					$scope.registrationMessage = 'Registration saved !';
96
				} else {
97
					$scope.registrationMessage = 'User already registered !';
98
				}
99
			}, function errorCallback(res) {
100
				$scope.registerStatus = -1;
101
				$scope.registrationMessage = 'Error saving registration !';
102
				alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
103
			});
104
		}
105
	});
106
	</script>
107
	
108
</body>
109

  
110
</html>

Also available in: Unified diff