Skip to content

Commit

Permalink
Add account name to user model and use it for auth
Browse files Browse the repository at this point in the history
  • Loading branch information
witold.brzozowski committed Feb 15, 2024
1 parent af82011 commit 2117e6c
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 154 deletions.
56 changes: 28 additions & 28 deletions src/main/java/info/fingo/urlopia/config/ad/Attribute.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package info.fingo.urlopia.config.ad;

public enum Attribute {
PRINCIPAL_NAME("userPrincipalName"),
MAIL("mail"),
FIRST_NAME("givenname"),
LAST_NAME("sn"),
MEMBER("member"),
MEMBER_OF("memberOf"),
MANAGED_OBJECTS("managedObjects"),
MANAGED_BY("managedBy"),
NAME("name"),
DISTINGUISHED_NAME("distinguishedName"),
CREATED_TIME("whenCreated"),
CHANGED_TIME("whenChanged"),
USER_ACCOUNT_CONTROL("userAccountControl");


private String key;

Attribute(String key) {
this.key = key;
}

public String getKey() {
return key;
}
}
package info.fingo.urlopia.config.ad;

public enum Attribute {
PRINCIPAL_NAME("userPrincipalName"),
MAIL("mail"),
FIRST_NAME("givenname"),
LAST_NAME("sn"),
MEMBER("member"),
MEMBER_OF("memberOf"),
MANAGED_OBJECTS("managedObjects"),
MANAGED_BY("managedBy"),
NAME("name"),
DISTINGUISHED_NAME("distinguishedName"),
CREATED_TIME("whenCreated"),
CHANGED_TIME("whenChanged"),
USER_ACCOUNT_CONTROL("userAccountControl"),
ACCOUNT_NAME("sAMAccountName");

private String key;

Attribute(String key) {
this.key = key;
}

public String getKey() {
return key;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,9 @@ public class AccessToken {
private final String value;
private final JwtTokenAuthoritiesProvider jwtTokenAuthoritiesProvider;


public String getPrincipal() {
var decodedToken = decodeToken(value);
return JwtUtils.getPrincipalNameFromDecodedToken(decodedToken);
}

public String getFirstName() {
var decodedToken = decodeToken(value);
return JwtUtils.getFirstNameFromDecodedToken(decodedToken);
}

public String getLastName() {
public String getAccountName() {
var decodedToken = decodeToken(value);
return JwtUtils.getLastNameFromDecodedToken(decodedToken);
return JwtUtils.getAccountNameFromDecodedToken(decodedToken);
}

public Set<SimpleGrantedAuthority> getAuthorities() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ private Authentication getAuthenticationByToken(String header,
HttpServletResponse response) {
try{
var accessToken = jwtTokenValidator.validateAuthorizationHeader(header);
var principal = accessToken.getFirstName() + ";" + accessToken.getLastName();
var accountName = accessToken.getAccountName();
var authorities = accessToken.getAuthorities();
return new UsernamePasswordAuthenticationToken(principal, null, authorities);
return new UsernamePasswordAuthenticationToken(accountName, null, authorities);
}catch (InvalidTokenException | NoSuchUserException exception){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ public class JwtTokenAuthoritiesProvider {
private final UserAuthoritiesProvider userAuthoritiesProvider;

public Set<SimpleGrantedAuthority> getAuthoritiesFromJWT(DecodedJWT decodedToken){
// var principal = JwtUtils.getPrincipalNameFromDecodedToken(decodedToken); TODO: go back to checking @ / sth else than name and surname
// var user = userService.getByPrincipal(principal);

var firstName = JwtUtils.getFirstNameFromDecodedToken(decodedToken);
var lastName = JwtUtils.getLastNameFromDecodedToken(decodedToken);
var user = userService.getByFirstNameAndLastName(firstName, lastName);

var accountName = JwtUtils.getAccountNameFromDecodedToken(decodedToken);
var user = userService.getFirstByAccountName(accountName);
return userAuthoritiesProvider.getAuthoritiesFromUser(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,7 @@
@Component
@RequiredArgsConstructor
public class JwtUtils {

private static final String PRINCIPAL_KEY = "unique_name";
private static final String FIRST_NAME_KEY = "given_name";
private static final String LAST_NAME_KEY = "family_name";


public static String getPrincipalNameFromDecodedToken(DecodedJWT decodedToken){
var payloadAsJson = decodeTokenPayloadToJsonObject(decodedToken);
return payloadAsJson.getAsJsonPrimitive(PRINCIPAL_KEY).getAsString();
}

public static JsonObject decodeTokenPayloadToJsonObject(DecodedJWT decodedJWT) {
try {
Expand All @@ -34,15 +25,9 @@ public static JsonObject decodeTokenPayloadToJsonObject(DecodedJWT decodedJWT) {
}
}

//TEMPORARY FIX

public static String getFirstNameFromDecodedToken(DecodedJWT decodedToken){
var payloadAsJson = decodeTokenPayloadToJsonObject(decodedToken);
return payloadAsJson.getAsJsonPrimitive(FIRST_NAME_KEY).getAsString();
}

public static String getLastNameFromDecodedToken(DecodedJWT decodedToken){
public static String getAccountNameFromDecodedToken(DecodedJWT decodedToken) {
var payloadAsJson = decodeTokenPayloadToJsonObject(decodedToken);
return payloadAsJson.getAsJsonPrimitive(LAST_NAME_KEY).getAsString();
var principal = payloadAsJson.getAsJsonPrimitive(PRINCIPAL_KEY).getAsString();
return principal.substring(0, principal.indexOf("@"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ public boolean preHandle(HttpServletRequest request,
var token = request.getHeader("Authorization");
try{
var accessToken = jwtTokenValidator.validateAuthorizationHeader(token);
// var principal = accessToken.getPrincipal(); TODO: go back to checking @ / sth else than name and surname
// var user = userService.getByPrincipal(principal);

var firstName = accessToken.getFirstName();
var lastName = accessToken.getLastName();
var user = userService.getByFirstNameAndLastName(firstName, lastName);
var user = userService.getFirstByAccountName(accessToken.getAccountName());
request.setAttribute(USER_ID_ATTRIBUTE, user.getId());
} catch (RuntimeException ignored){
} catch (RuntimeException ignored) {
// Ignored
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,10 @@ Team mapToTeam(SearchResult adTeam) {
return this.mapToTeam(adTeam, new Team());
}

Team mapToTeam(SearchResult adTeam,
Team team) {
team.setAdName(
ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.DISTINGUISHED_NAME));
team.setName(
normalizeName(ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.NAME)));
team.setLeader(
findUser(ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.MANAGED_BY)));
Team mapToTeam(SearchResult adTeam, Team team) {
team.setAdName(ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.DISTINGUISHED_NAME));
team.setName(normalizeName(ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.NAME)));
team.setLeader(findUser(ActiveDirectoryUtils.pickAttribute(adTeam, Attribute.MANAGED_BY)));
return team;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,18 @@ public class ActiveDirectoryUserMapper {
@Value("${ad.groups.admin}")
private String adminGroup;

public User mapToUser(SearchResult searchResult,
User user) {
user.setPrincipalName(
ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.PRINCIPAL_NAME));
user.setAdName(
ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.DISTINGUISHED_NAME));
user.setMail(
ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.MAIL));
user.setFirstName(
ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.FIRST_NAME));
user.setLastName(
ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.LAST_NAME));
user.setLeader(
isLeader(searchResult));
user.setB2b(
isB2B(searchResult));
user.setEc(
isEC(searchResult));
user.setActive(
!ActiveDirectoryUtils.isDisabled(searchResult));
user.setAdmin(
isAdmin(searchResult));

public User mapToUser(SearchResult searchResult, User user) {
user.setAccountName(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.ACCOUNT_NAME));
user.setPrincipalName(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.PRINCIPAL_NAME));
user.setAdName(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.DISTINGUISHED_NAME));
user.setMail(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.MAIL));
user.setFirstName(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.FIRST_NAME));
user.setLastName(ActiveDirectoryUtils.pickAttribute(searchResult, Attribute.LAST_NAME));
user.setLeader(isLeader(searchResult));
user.setB2b(isB2B(searchResult));
user.setEc(isEC(searchResult));
user.setActive(!ActiveDirectoryUtils.isDisabled(searchResult));
user.setAdmin(isAdmin(searchResult));
return user;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public static NoSuchUserException invalidEmail() {
return new NoSuchUserException(ERROR_MESSAGE.formatted("email"));
}

public static NoSuchUserException accountName() {
return new NoSuchUserException(ERROR_MESSAGE.formatted("account name"));
}

public static NoSuchUserException inactiveAccount(String mail) {
return new NoSuchUserException(INACTIVE_ACCOUNT_MESSAGE.formatted(mail));
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/info/fingo/urlopia/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public class User {
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "users_id_seq")
private Long id;

@Column(nullable = false, unique = true)
private String accountName;

@Column(nullable = false, unique = true)
private String principalName;

Expand Down Expand Up @@ -109,6 +112,10 @@ public void setMail(String mail) {
this.mail = mail;
}

public void setAccountName(String accountName) {
this.accountName = accountName;
}

public void setPrincipalName(String principalName) {
this.principalName = principalName;
}
Expand Down Expand Up @@ -149,6 +156,10 @@ public void setWorkTime(Float workTime) {
this.workTime = workTime;
}

public String getAccountName() {
return accountName;
}

public String getPrincipalName() {
return principalName;
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/info/fingo/urlopia/user/UserRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface UserRepository extends BaseRepository<User>, JpaRepository<User

Optional<User> findFirstByPrincipalName(String principalName);

Optional<User> findFirstByAccountName(String accountName);

Optional<User> findFirstByAdName(String adName);

Optional<User> findFirstByFirstNameAndLastName(String firstName, String lastName);
Expand Down
26 changes: 6 additions & 20 deletions src/main/java/info/fingo/urlopia/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,12 @@ public User get(String userMail) {
});
}

public User getByPrincipal(String principal) {
public User getFirstByAccountName(String accountName) {
return userRepository
.findFirstByPrincipalName(principal)
.findFirstByAccountName(accountName)
.orElseThrow(() -> {
log.error("There is no user with principal: {}", Anonymizer.anonymizeMail(principal));
return NoSuchUserException.invalidEmail();
});
}
public User getByFirstNameAndLastName(String firstName,
String lastName) {
return userRepository
.findFirstByFirstNameAndLastName(firstName, lastName)
.orElseThrow(() -> {
log.error("There is no user with firstName: {} lastName: {}", firstName, lastName);
return NoSuchUserException.invalidEmail();
log.error("There is no user with account name: {}", accountName);
return NoSuchUserException.accountName();
});
}

Expand Down Expand Up @@ -161,14 +152,9 @@ public Set<User> getLeaders(Long userId) {
}

public Long getCurrentUserId(){
var principal = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

// Temporary fix while domain migration is on
var split = principal.split(";");
var firstName = split[0];
var lastName = split.length > 1 ? split[1] : "";
var accountName = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

var user = userRepository.findFirstByFirstNameAndLastName(firstName, lastName);
var user = userRepository.findFirstByAccountName(accountName);
if (user.isPresent()){
return user.get().getId();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users DROP COLUMN account_name;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN account_name VARCHAR(63) NOT NULL UNIQUE;
6 changes: 3 additions & 3 deletions view.react/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
VITE_OAUTH_CLIENT_ID=
VITE_OAUTH_TENANT_ID=
VITE_AUTH_MODE=AUTH
VITE_OAUTH_CLIENT_ID=
VITE_OAUTH_TENANT_ID=
VITE_AUTH_MODE=AUTH
51 changes: 26 additions & 25 deletions view.react/.gitignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.vscode
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.vscode

0 comments on commit 2117e6c

Please sign in to comment.