Sanitize user output on frontend

This commit is contained in:
George Kalampokis 2020-07-17 13:19:10 +03:00
parent 4127a05da4
commit ac24143c0d
10 changed files with 237 additions and 36 deletions

View File

@ -31,6 +31,7 @@ import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.helpers.responses.ResponseItem;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.principal.PrincipalModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.ApiMessageCode;
import org.slf4j.Logger;
@ -91,17 +92,17 @@ public class Login {
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/externallogin"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
ResponseEntity<ResponseItem<PrincipalModel>> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
logger.info("Trying To Login With " + credentials.getProvider());
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
}
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/nativelogin"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> nativelogin(@RequestBody Credentials credentials) throws NullEmailException {
ResponseEntity<ResponseItem<PrincipalModel>> nativelogin(@RequestBody Credentials credentials) throws NullEmailException {
logger.info(credentials.getUsername() + " Trying To Login");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
}
@RequestMapping(method = RequestMethod.GET, value = {"/twitterRequestToken"}, produces = "application/json")
@ -148,9 +149,11 @@ public class Login {
@RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> authMe(Principal principal) throws NullEmailException {
ResponseEntity<ResponseItem<PrincipalModel>> authMe(Principal principal) throws NullEmailException {
logger.info(principal + " Getting Me");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().payload(this.nonVerifiedUserAuthenticationService.Touch(principal.getToken())).status(ApiMessageCode.NO_MESSAGE));
Principal principal1 = this.nonVerifiedUserAuthenticationService.Touch(principal.getToken());
PrincipalModel principalModel = PrincipalModel.fromEntity(principal1);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(principalModel).status(ApiMessageCode.NO_MESSAGE));
}
@Transactional

View File

@ -24,6 +24,7 @@ import eu.eudat.models.data.dmp.DataManagementPlan;
import eu.eudat.models.data.doi.DOIRequest;
import eu.eudat.models.data.helpers.common.DataTableData;
import eu.eudat.models.data.login.Credentials;
import eu.eudat.models.data.principal.PrincipalModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.userinfo.UserListingModel;
import eu.eudat.models.data.userinfo.UserProfile;
@ -105,10 +106,11 @@ public class UserManager {
.createOrUpdate(userInfo);
}
public Principal authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException {
public PrincipalModel authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException {
Principal principal = authenticationServiceImpl.Touch(credentials);
if (principal == null) throw new UnauthorisedException("Could not Sign In User");
return principal;
PrincipalModel principalModel = PrincipalModel.fromEntity(principal);
return principalModel;
}
public DataTableData<UserListingModel> getCollaboratorsPaged(UserInfoTableRequestItem userInfoTableRequestItem, Principal principal) throws Exception {

View File

@ -4,6 +4,7 @@ import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.principal.PrincipalModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.logic.security.validators.TokenValidatorFactory;
import org.slf4j.Logger;
@ -22,11 +23,11 @@ public class CustomAuthenticationProvider {
@Autowired
private TokenValidatorFactory tokenValidatorFactory;
public Principal authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
public PrincipalModel authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
String token = credentials.getTicket();
try {
Principal principal = this.tokenValidatorFactory.getProvider(credentials.getProvider()).validateToken(credentials);
return principal;
return PrincipalModel.fromEntity(principal);
} catch (NonValidTokenException e) {
logger.error("Could not validate a user by his token! Reason: " + e.getMessage(), e);
throw new UnauthorisedException("Token validation failed - Not a valid token");

View File

@ -0,0 +1,131 @@
package eu.eudat.models.data.principal;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
public class PrincipalModel {
private UUID id;
private UUID token;
private String name;
private String email;
private Date expiresAt;
private String avatarUrl;
private Set<Authorities> authorities;
private String culture;
private String language;
private String timezone;
private String zenodoEmail;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public UUID getToken() {
return token;
}
public void setToken(UUID token) {
this.token = token;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getExpiresAt() {
return expiresAt;
}
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public Set<Authorities> getAuthz() {
return authorities;
}
public Set<Integer> getAuthorities() {
return authorities.stream().map(authz -> authz.getValue()).collect(Collectors.toSet());
}
public void setAuthorities(Set<Authorities> authorities) {
this.authorities = authorities;
}
public String getCulture() {
return culture;
}
public void setCulture(String culture) {
this.culture = culture;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public String getZenodoEmail() {
return zenodoEmail;
}
public void setZenodoEmail(String zenodoEmail) {
this.zenodoEmail = zenodoEmail;
}
public static PrincipalModel fromEntity(Principal principal) {
PrincipalModel model = new PrincipalModel();
model.setId(principal.getId());
model.setToken(principal.getToken());
model.setAuthorities(principal.getAuthz());
model.setAvatarUrl(principal.getAvatarUrl());
model.setCulture(principal.getCulture());
model.setEmail(principal.getEmail());
model.setExpiresAt(principal.getExpiresAt());
model.setLanguage(principal.getLanguage());
model.setName(principal.getName());
model.setTimezone(principal.getTimezone());
model.setZenodoEmail(principal.getZenodoEmail());
return model;
}
}

View File

@ -22,7 +22,7 @@ public class UserInfo implements DataModel<eu.eudat.data.entities.UserInfo, User
private Date lastloggedin = null;
private String additionalinfo;
// private String additionalinfo;
public UUID getId() {
return id;
@ -88,13 +88,13 @@ public class UserInfo implements DataModel<eu.eudat.data.entities.UserInfo, User
this.lastloggedin = lastloggedin;
}
public String getAdditionalinfo() {
/*public String getAdditionalinfo() {
return additionalinfo;
}
public void setAdditionalinfo(String additionalinfo) {
this.additionalinfo = additionalinfo;
}
}*/
@Override
public UserInfo fromDataModel(eu.eudat.data.entities.UserInfo entity) {
@ -111,7 +111,7 @@ public class UserInfo implements DataModel<eu.eudat.data.entities.UserInfo, User
entity.setId(this.getId());
entity.setEmail(this.getEmail());
entity.setName(this.getName());
entity.setAdditionalinfo(this.getAdditionalinfo());
//entity.setAdditionalinfo(this.getAdditionalinfo());
entity.setAuthorization_level(this.getAuthorization_level());
entity.setCreated(this.getCreated());
entity.setLastloggedin(this.getLastloggedin());

View File

@ -17,7 +17,7 @@ public class UserListingModel implements DataModel<eu.eudat.data.entities.UserIn
private String name;
private Date created;
private Date lastloggedin;
private String additionalinfo;
//private String additionalinfo;
private List<Integer> appRoles;
public UUID getId() {
@ -69,12 +69,12 @@ public class UserListingModel implements DataModel<eu.eudat.data.entities.UserIn
this.lastloggedin = lastloggedin;
}
public String getAdditionalinfo() {
/*public String getAdditionalinfo() {
return additionalinfo;
}
public void setAdditionalinfo(String additionalinfo) {
this.additionalinfo = additionalinfo;
}
}*/
public List<Integer> getAppRoles() {
return appRoles;
@ -92,7 +92,7 @@ public class UserListingModel implements DataModel<eu.eudat.data.entities.UserIn
this.name = entity.getName();
this.created = entity.getCreated();
this.lastloggedin = entity.getLastloggedin();
this.additionalinfo = entity.getAdditionalinfo();
// this.additionalinfo = entity.getAdditionalinfo();
this.appRoles = entity.getUserRoles().stream().map(item -> item.getRole()).collect(Collectors.toList());
return this;
}
@ -107,7 +107,7 @@ public class UserListingModel implements DataModel<eu.eudat.data.entities.UserIn
userInfo.setName(this.name);
userInfo.setCreated(this.created);
userInfo.setLastloggedin(this.lastloggedin);
userInfo.setAdditionalinfo(this.additionalinfo);
// userInfo.setAdditionalinfo(this.additionalinfo);
return userInfo;
}

View File

@ -1,27 +1,37 @@
package eu.eudat.models.data.userinfo;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.*;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dmp.DataManagementPlan;
import net.minidev.json.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by ikalyvas on 8/24/2018.
*/
public class UserProfile implements DataModel<eu.eudat.data.entities.UserInfo, UserProfile> {
private static final Logger logger = LoggerFactory.getLogger(UserProfile.class);
private UUID id;
private String email;
private Short usertype;
private String name;
private Date lastloggedin;
private String additionalinfo;
//private String additionalinfo;
private List<DataManagementPlan> associatedDmps;
private String zenodoEmail;
private Map<String, Object> language;
private String timezone;
private Map<String, Object> culture;
private String avatarUrl;
public UUID getId() {
return id;
@ -63,13 +73,13 @@ public class UserProfile implements DataModel<eu.eudat.data.entities.UserInfo, U
this.lastloggedin = lastloggedin;
}
public String getAdditionalinfo() {
/*public String getAdditionalinfo() {
return additionalinfo;
}
public void setAdditionalinfo(String additionalinfo) {
this.additionalinfo = additionalinfo;
}
}*/
public List<DataManagementPlan> getAssociatedDmps() {
return associatedDmps;
@ -79,6 +89,46 @@ public class UserProfile implements DataModel<eu.eudat.data.entities.UserInfo, U
this.associatedDmps = associatedDmps;
}
public String getZenodoEmail() {
return zenodoEmail;
}
public void setZenodoEmail(String zenodoEmail) {
this.zenodoEmail = zenodoEmail;
}
public Map<String, Object> getLanguage() {
return language;
}
public void setLanguage(Map<String, Object> language) {
this.language = language;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public Map<String, Object> getCulture() {
return culture;
}
public void setCulture(Map<String, Object> culture) {
this.culture = culture;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
@Override
public UserProfile fromDataModel(UserInfo entity) {
this.id = entity.getId();
@ -86,7 +136,17 @@ public class UserProfile implements DataModel<eu.eudat.data.entities.UserInfo, U
this.usertype = entity.getUsertype();
this.name = entity.getName();
this.lastloggedin = entity.getLastloggedin();
this.additionalinfo = entity.getAdditionalinfo();
//this.additionalinfo = entity.getAdditionalinfo();
try {
Map<String, Object> additionalInfo = new ObjectMapper().readValue(entity.getAdditionalinfo(), HashMap.class);
this.language = (Map)additionalInfo.get("language");
this.culture = (Map) additionalInfo.get("culture");
this.timezone = (String) additionalInfo.get("timezone");
this.zenodoEmail = (String) additionalInfo.get("zenodoEmail");
this.avatarUrl = (String) additionalInfo.get("avatarUrl");
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return this;
}

View File

@ -5,6 +5,10 @@ export interface UserListingModel {
name: String;
email: string;
appRoles: AppRole[];
additionalinfo: any;
associatedDmps: any[];
language: any;
culture: any;
timezone: String;
zenodoEmail: String;
avatarUrl: String;
}

View File

@ -6,7 +6,7 @@
<div class="row">
<div class="col-12">
<div class="row profile-card-center-row">
<div class="col-auto"><img mat-card-avatar [src]="userProfile.additionalinfo.avatarUrl" (error)="applyFallbackAvatar($event)">
<div class="col-auto"><img mat-card-avatar [src]="userProfile.avatarUrl" (error)="applyFallbackAvatar($event)">
</div>
</div>
<div class="row profile-card-center-row">

View File

@ -33,7 +33,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
editMode = false;
languages = availableLanguages;
zenodoToken: string;
zenodoEmail: string;
zenodoEmail: String;
formGroup: FormGroup;
constructor(
@ -56,13 +56,13 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
this.currentUserId = this.authService.current().id;
const userId = !params['id'] ? 'me' : params['id'];
this.user = this.userService.getUser(userId).pipe(map(result => {
result['additionalinfo'] = JSON.parse(result['additionalinfo']);
this.zenodoToken = result['additionalinfo']['zenodoToken'];
this.zenodoEmail = result['additionalinfo']['zenodoEmail'];
//result['additionalinfo'] = JSON.parse(result['additionalinfo']);
//this.zenodoToken = result['additionalinfo']['zenodoToken'];
this.zenodoEmail = result['zenodoEmail'];
this.formGroup = new FormBuilder().group({
language: new FormControl(result['additionalinfo']['language'] ? availableLanguages.filter(x => x.value === result['additionalinfo']['language']['value']).pop() : '', [Validators.required]),
timezone: new FormControl(result['additionalinfo']['timezone'], [Validators.required]),
culture: new FormControl(result['additionalinfo']['culture'], [Validators.required])
language: new FormControl(result['language'] ? availableLanguages.filter(x => x.value === result['language']['value']).pop() : '', [Validators.required]),
timezone: new FormControl(result['timezone'], [Validators.required]),
culture: new FormControl(result['culture'], [Validators.required])
});
//this.formGroup.get('language').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { if (x) this.translate.use(x.value) })
this.formGroup.get('timezone').valueChanges
@ -157,7 +157,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
}
public hasZenodo(): boolean {
return !isNullOrUndefined(this.zenodoToken) && this.zenodoToken !== "";
return !isNullOrUndefined(this.zenodoEmail) && this.zenodoEmail !== "";
}
public loginToZenodo() {