Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Backend
Commits
bc232ba0
Commit
bc232ba0
authored
Sep 21, 2017
by
Maxym Borodenko
Committed by
Matija Obreza
Sep 22, 2017
Browse files
FTP password
Signed-off-by:
Matija Obreza
<
matija.obreza@croptrust.org
>
parent
73c33a6a
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/main/java/org/genesys2/server/model/impl/User.java
View file @
bc232ba0
...
...
@@ -19,9 +19,11 @@ package org.genesys2.server.model.impl;
import
java.beans.Transient
;
import
javax.persistence.Cacheable
;
import
javax.persistence.Column
;
import
javax.persistence.Entity
;
import
javax.persistence.Table
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
org.genesys.blocks.security.model.BasicUser
;
...
...
@@ -36,6 +38,18 @@ public class User extends BasicUser<UserRole> {
private
static
final
long
serialVersionUID
=
4564013753931115445L
;
@JsonIgnore
@Column
(
length
=
60
)
private
String
ftpPassword
;
public
String
getFtpPassword
()
{
return
ftpPassword
;
}
public
void
setFtpPassword
(
final
String
ftpPassword
)
{
this
.
ftpPassword
=
ftpPassword
;
}
@Override
public
String
toString
()
{
return
"User id="
+
getId
()
+
" email="
+
getEmail
();
...
...
src/main/java/org/genesys2/server/service/UserService.java
View file @
bc232ba0
...
...
@@ -75,4 +75,6 @@ public interface UserService extends BasicUserService<UserRole, User> {
User
setAccountType
(
User
user
,
AccountType
accountType
);
void
setFtpPassword
(
User
user
,
String
ftpPassword
)
throws
PasswordPolicyException
;
}
src/main/java/org/genesys2/server/service/impl/UserServiceImpl.java
View file @
bc232ba0
...
...
@@ -31,6 +31,7 @@ import org.genesys.blocks.security.NotUniqueUserException;
import
org.genesys.blocks.security.SecurityContextUtil
;
import
org.genesys.blocks.security.UserException
;
import
org.genesys.blocks.security.model.BasicUser.AccountType
;
import
org.genesys.blocks.security.service.PasswordPolicy
;
import
org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException
;
import
org.genesys.blocks.security.service.impl.BasicUserServiceImpl
;
import
org.genesys2.server.model.UserRole
;
...
...
@@ -71,6 +72,9 @@ public class UserServiceImpl extends BasicUserServiceImpl<UserRole, User> implem
@Autowired
private
UserRepository
userRepository
;
@Autowired
private
PasswordPolicy
passwordPolicy
;
private
final
List
<
UserRole
>
availableRoles
=
ListUtils
.
unmodifiableList
(
Arrays
.
asList
(
UserRole
.
values
()));
private
EmailValidator
emailValidator
=
EmailValidator
.
getInstance
();
...
...
@@ -406,4 +410,16 @@ public class UserServiceImpl extends BasicUserServiceImpl<UserRole, User> implem
return
userRepository
.
save
(
u
);
}
/**
* Set FTP application password for the user.
*/
@Override
@Transactional
@PreAuthorize
(
"hasRole('ADMINISTRATOR') || principal.user.id == #user.id"
)
public
void
setFtpPassword
(
final
User
user
,
final
String
ftpPassword
)
throws
PasswordPolicyException
{
passwordPolicy
.
assureGoodPassword
(
ftpPassword
);
user
.
setFtpPassword
(
passwordEncoder
.
encode
(
ftpPassword
));
userRepository
.
save
(
user
);
}
}
src/main/java/org/genesys2/server/servlet/controller/UserProfileController.java
View file @
bc232ba0
...
...
@@ -17,6 +17,7 @@
package
org.genesys2.server.servlet.controller
;
import
java.io.IOException
;
import
java.util.Random
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -34,11 +35,15 @@ import org.genesys2.server.service.TokenVerificationService.NoSuchVerificationTo
import
org.genesys2.server.service.TokenVerificationService.TokenExpiredException
;
import
org.genesys2.server.service.UserService
;
import
org.genesys2.spring.ResourceNotFoundException
;
import
org.genesys2.util.RandomPasswordUtil
;
import
org.genesys2.util.ReCaptchaUtil
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.Sort
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.stereotype.Controller
;
...
...
@@ -47,6 +52,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.servlet.mvc.support.RedirectAttributes
;
@Controller
...
...
@@ -92,6 +98,29 @@ public class UserProfileController extends BaseController {
return
"redirect:/profile/"
+
uuid
;
}
@RequestMapping
(
value
=
"/{uuid:.+}/generate-ftp-password"
,
method
=
RequestMethod
.
POST
,
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
@PreAuthorize
(
"hasAnyRole('ADMINISTRATOR', 'VETTEDUSER')"
)
@ResponseBody
public
ResponseEntity
<?>
generateFtpPassword
(
@PathVariable
(
"uuid"
)
String
uuid
)
{
String
generatedPassword
=
RandomPasswordUtil
.
generatePassword
(
new
Random
(),
15
);
final
User
user
=
userService
.
getUserByUuid
(
uuid
);
if
(
user
==
null
)
{
return
new
ResponseEntity
<>(
HttpStatus
.
NOT_FOUND
);
}
final
Object
result
=
new
Object
()
{
@SuppressWarnings
(
"unused"
)
public
String
password
=
generatedPassword
;
};
try
{
userService
.
setFtpPassword
(
user
,
generatedPassword
);
return
new
ResponseEntity
<>(
result
,
HttpStatus
.
OK
);
}
catch
(
PasswordPolicyException
e
)
{
return
new
ResponseEntity
<>(
HttpStatus
.
INTERNAL_SERVER_ERROR
);
}
}
@RequestMapping
(
"/{uuid:.+}"
)
@PreAuthorize
(
"isAuthenticated()"
)
public
String
someProfile
(
ModelMap
model
,
@PathVariable
(
"uuid"
)
String
uuid
)
{
...
...
src/main/java/org/genesys2/spring/config/ApplicationConfig.java
View file @
bc232ba0
...
...
@@ -41,5 +41,4 @@ public class ApplicationConfig {
public
BrAPIService
brapiService
()
{
return
new
BrAPIServiceImpl
();
}
}
src/main/java/org/genesys2/util/RandomPasswordUtil.java
0 → 100644
View file @
bc232ba0
/**
* Copyright 2017 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package
org.genesys2.util
;
import
java.util.Random
;
/**
* @author Maxym Borodenko
*/
public
class
RandomPasswordUtil
{
private
static
final
String
symbols
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$&@?~!%#"
;
/**
* This method generates a random password that consists of at least one special character, one number,
* one lowercase letter and one uppercase letter
*
* @param random
* @param length the password length that should be generated
* @return string with generated password
* @throws IllegalArgumentException if the 'length' parameter is lower than 4 characters
*/
public
static
String
generatePassword
(
final
Random
random
,
final
int
length
)
{
if
(
length
<
4
)
{
throw
new
IllegalArgumentException
(
"Password must be at least 4 characters"
);
}
while
(
true
)
{
char
[]
password
=
new
char
[
length
];
boolean
hasUpper
=
false
,
hasLower
=
false
,
hasDigit
=
false
,
hasSpecial
=
false
;
for
(
int
i
=
0
;
i
<
password
.
length
;
i
++)
{
char
ch
=
symbols
.
charAt
(
random
.
nextInt
(
symbols
.
length
()));
if
(
Character
.
isUpperCase
(
ch
))
hasUpper
=
true
;
else
if
(
Character
.
isLowerCase
(
ch
))
hasLower
=
true
;
else
if
(
Character
.
isDigit
(
ch
))
hasDigit
=
true
;
else
hasSpecial
=
true
;
password
[
i
]
=
ch
;
}
if
(
hasUpper
&&
hasLower
&&
hasDigit
&&
hasSpecial
)
{
return
new
String
(
password
);
}
}
}
}
src/main/resources/content/language.properties
View file @
bc232ba0
...
...
@@ -135,6 +135,7 @@ user.pulldown.heading={0}
user.create-new-account
=
Create an account
user.full-name
=
Full Name
user.email
=
E-mail Address
user.generate-ftp-password
=
Generate FTP password
user.account-status
=
Account Status
user.account-disabled
=
Account disabled
user.account-locked-until
=
Account locked until
...
...
@@ -143,6 +144,7 @@ user.login-type=Login Type
userprofile.page.title
=
User profile
userprofile.page.intro
=
As a community, Genesys relies on its users to be successful. Whether you’re an individual researcher or represent a larger institution, you can update your profile here to show your interests and the data in your collection.
userprofile.update.title
=
Update your profile
userprofile.page.ftp-credentials
=
Your FTP credentials are:
user.page.list.title
=
Registered user accounts
...
...
src/main/resources/liquibase/liquibase-changeLog.yml
View file @
bc232ba0
...
...
@@ -217,3 +217,14 @@ databaseChangeLog:
-
column
:
name
:
doi
type
:
varchar(255)
-
changeSet
:
id
:
1505830865186-1
author
:
maxymborodenko (generated)
changes
:
-
addColumn
:
tableName
:
user
columns
:
-
column
:
name
:
ftpPassword
type
:
varchar(60)
\ No newline at end of file
src/main/webapp/WEB-INF/jsp/user/profile.jsp
View file @
bc232ba0
...
...
@@ -4,7 +4,7 @@
<html>
<head>
<title><spring:message
code=
"userprofile.page.title"
/></title>
<title><spring:message
code=
"userprofile.page.title"
/></title>
</head>
<body>
<cms:informative
-h1 title="userprofile.page.title" fancy="true" info="userprofile.page.intro"
/>
...
...
@@ -15,7 +15,7 @@
</a>
</security:authorize>
<div
class=
"form-horizontal"
>
<div
class=
"form-horizontal"
id=
"user-profile-info"
>
<div
class=
"form-group"
>
<label
for=
"password"
class=
"col-lg-2 control-label"
><spring:message
code=
"user.full-name"
/></label>
<div
class=
"col-lg-5 form-control-static"
><c:out
value=
"
${
user
.
fullName
}
"
/></div>
...
...
@@ -54,6 +54,23 @@
</security:authorize>
<security:authorize
access=
"hasAnyRole('ADMINISTRATOR', 'VETTEDUSER')"
>
<c:if
test=
"
${
user
.
ftpPassword
ne
null
}
"
>
<div
class=
"form-group"
id=
"ftp-credentials"
>
<label
class=
"col-lg-2 control-label"
><spring:message
code=
"userprofile.page.ftp-credentials"
/></label>
<div
class=
"col-lg-5 form-control-static"
>
<div>
<label
for=
"ftp-username"
><spring:message
code=
"login.username"
/></label>
<span
id=
"ftp-username"
><c:out
value=
"
${
user
.
email
}
"
/></span>
</div>
<div>
<label
for=
"ftp-password"
><spring:message
code=
"login.password"
/></label>
<span
id=
"ftp-password"
>
*
</span>
</div>
</div>
</div>
</c:if>
</security:authorize>
</div>
...
...
@@ -77,7 +94,7 @@
</security:authorize>
<security:authorize
access=
"hasRole('ADMINISTRATOR') || principal.id == #user.id"
>
<c:if
test=
"
${
not
user
.
hasRole
(
'VALIDATEDUSER'
)
}
"
>
<a
href=
"
<c:url
value=
"/profile/${user.uuid}/send"
/>
"
class=
"btn btn-default"
/
>
Send validation email
</a>
<a
href=
"
<c:url
value=
"/profile/${user.uuid}/send"
/>
"
class=
"btn btn-default"
>
Send validation email
</a>
</c:if>
</security:authorize>
<security:authorize
access=
"hasAnyRole('VETTEDUSER','ADMINISTRATOR')"
>
...
...
@@ -85,12 +102,15 @@
</security:authorize>
<security:authorize
access=
"hasRole('ADMINISTRATOR')"
>
<c:if
test=
"
${
not
user
.
hasRole
(
'VETTEDUSER'
)
}
"
>
<a
href=
"
<c:url
value=
"/profile/${user.uuid}/vetted-user"
/>
"
class=
"btn btn-default"
/
>
Vetted user
</a>
<a
href=
"
<c:url
value=
"/profile/${user.uuid}/vetted-user"
/>
"
class=
"btn btn-default"
>
Vetted user
</a>
</c:if>
<security:authorize
access=
"isAuthenticated()"
>
<a
href=
"#"
data-toggle=
"modal"
data-target=
"#myModal"
class=
"btn btn-default get_widget"
id=
"get_widget"
>
Get Widget
</a>
</security:authorize>
</security:authorize>
<security:authorize
access=
"hasAnyRole('ADMINISTRATOR', 'VETTEDUSER')"
>
<input
type=
"button"
id=
"generate-ftp-password-btn"
value=
"
<spring:message
code=
"user.generate-ftp-password"
/>
"
class=
"btn btn-default"
/>
</security:authorize>
</div>
<!-- Modal -->
...
...
@@ -134,6 +154,45 @@
}},
false
);
});
</security:authorize>
<security:authorize
access=
"hasAnyRole('ADMINISTRATOR', 'VETTEDUSER')"
>
$
(
'
body
'
).
on
(
'
click
'
,
'
#generate-ftp-password-btn
'
,
function
()
{
$
.
ajax
({
type
:
'
POST
'
,
dataType
:
'
json
'
,
url
:
'
<c:url
value=
"/profile/${user.uuid}/generate-ftp-password"
/>
'
,
contentType
:
'
application/json; charset=utf-8
'
,
beforeSend
:
function
(
xhrObj
){
xhrObj
.
setRequestHeader
(
"
Accept
"
,
"
application/json
"
);
},
success
:
function
(
respObject
)
{
if
(
$
(
'
#ftp-credentials
'
).
length
)
{
$
(
'
#ftp-password
'
).
text
(
'
'
+
respObject
.
password
);
}
else
{
renderUserFtpCredentials
(
respObject
.
password
);
}
},
error
:
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
console
.
log
(
textStatus
);
console
.
log
(
errorThrown
);
}
});
});
function
renderUserFtpCredentials
(
password
)
{
$
(
'
#user-profile-info
'
)
.
append
(
$
(
'
<div id="ftp-credentials" />
'
).
addClass
(
'
form-group
'
)
.
append
(
$
(
'
<label/>
'
).
addClass
(
'
col-lg-2 control-label
'
).
append
(
'
<spring:message
code=
"userprofile.page.ftp-credentials"
/>
'
))
.
append
(
$
(
'
<div />
'
).
addClass
(
'
col-lg-5 form-control-static
'
)
.
append
(
$
(
'
<div />
'
)
.
append
(
$
(
'
<label for="ftp-username" />
'
).
append
(
'
<spring:message
code=
"login.username"
/>
'
))
.
append
(
$
(
'
<span id="ftp-username" />
'
).
append
(
'
<c:out
value=
"
${
user
.
email
}
"
/>
'
)))
.
append
(
$
(
'
<div />
'
)
.
append
(
$
(
'
<label for="ftp-password" />
'
).
append
(
'
<spring:message
code=
"login.password"
/>
'
))
.
append
(
$
(
'
<span id="ftp-password" />
'
).
append
(
'
'
+
password
)))));
}
</security:authorize>
});
</script>
</security:authorize>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment