Skip to content

Commit

Permalink
Merge branch 'main' into bug/CSTM-CPC-1014-Fix-pet-date-and-update-pe…
Browse files Browse the repository at this point in the history
…t-form
  • Loading branch information
1-emil authored Oct 23, 2023
2 parents 59e0956 + a64681a commit 2d50478
Show file tree
Hide file tree
Showing 13 changed files with 239 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ public Flux<UserDetails> getUsers(String jwtToken) {
.retrieve()
.bodyToFlux(UserDetails.class);
}

public Mono<Void> deleteUser(String jwtToken, String userId) {
return webClientBuilder.build()
.delete()
.uri(authServiceUrl + "/users/{userId}", userId)
.cookie("Bearer", jwtToken)
.retrieve()
.bodyToMono(void.class);
}

//FUCK REACTIVE
/*
This shit is beyond cursed, but I do not care. This works, I only spent 6 HOURS OF MY LIFE.
Expand Down Expand Up @@ -200,15 +210,6 @@ public Mono<VetResponseDTO> createVetUser(Mono<RegisterVet> model){
// .bodyToMono(UserDetails.class);
// }
//
// public Mono<UserDetails> deleteUser(String auth, final long userId) {
// return webClientBuilder.build()
// .delete()
// .uri(authServiceUrl + "/users/{userId}", userId)
// .header("Authorization", auth)
// .retrieve()
// .bodyToMono(UserDetails.class);
// }

public Mono<ResponseEntity<UserDetails>> verifyUser(final String token) {

return webClientBuilder.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,13 @@ public Mono<UserDetails> getUserById(@PathVariable String userId, @CookieValue("
return authServiceClient.getUserById(auth, userId);
}

@SecuredEndpoint(allowedRoles = {Roles.ADMIN})
@DeleteMapping(value = "users/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<ResponseEntity<Void>> deleteUserById(@PathVariable String userId, @CookieValue("Bearer") String auth) {
return authServiceClient.deleteUser(auth, userId)
.then(Mono.just(ResponseEntity.noContent().<Void>build()))
.defaultIfEmpty(ResponseEntity.notFound().build());
}

@SecuredEndpoint(allowedRoles = {Roles.ANONYMOUS})
@PostMapping(value = "/users/login",produces = "application/json;charset=utf-8;", consumes = "application/json")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
angular.module('adminPanel')
.controller('AdminPanelController', ['$http', '$scope', "authProvider", function ($http, $scope, authProvider) {
.controller('AdminPanelController', ['$http', '$scope', "authProvider", "$window", function ($http, $scope, authProvider, $window) {

var self = this;
self.users = []
Expand All @@ -20,24 +20,41 @@ angular.module('adminPanel')
console.log("EventSource error: "+error)
}
}

$scope.startsWith = function (actual, expected) {
let lowerStr = (actual + "").toLowerCase();
let lowerExpected = (expected + "").toLowerCase();
return lowerStr.indexOf(lowerExpected) === 0;

$scope.search = function () {
if ($scope.query === '') {
$http.get('api/gateway/users', {
headers: {'Authorization': "Bearer " + authProvider.getUser().token}
})
.then(function (resp) {
self.users = resp.data;
});
} else {
$http.get('api/gateway/users', {
params: { username: $scope.query },
headers: {'Authorization': "Bearer " + authProvider.getUser().token}
})
.then(function (resp) {
self.users = resp.data;
});
}
};


$scope.removeUser = function (userid) {
$http.delete('api/gateway/users/' + userid, {
headers: {'Authorization': "Bearer " + authProvider.getUser().token}})
.then(function () {
$http.get('api/gateway/users', {
headers: {'Authorization': "Bearer " + authProvider.getUser().token}})
.then(function (resp) {
self.users = resp.data;
$http.get('api/gateway/users', {
headers: {'Authorization': "Bearer " + authProvider.getUser().token}})
.then(function (resp) {
self.users = resp.data;
alert("User has been deleted successfully.");
$window.location.reload();
});
});
});
};


}
]);
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ <h2 class="admin-panel">Users</h2>
</tr>
</thead>

<tr id="userId" ng-repeat="user in $ctrl.users | filter:$ctrl.query:startsWith track by user.userId">
<tr id="userId" ng-repeat="user in $ctrl.users | filter:{username:$ctrl.query}:startsWith track by user.userId">
<td>
<a style="text-decoration: none;" ui-sref="userDetails({ userId: user.userId })">
<span>{{ user.username }}</span>
</a>
</td>
<td>{{user.email}}</td>
<td>
<input class="add-vet-button btn btn-success" type="button" value="Delete" ng-click="removeUser(user.id)"/>
<input class="add-vet-button btn btn-success" type="button" value="Delete" ng-click="removeUser(user.userId)"/>
</td>
</tr>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

angular.module('userDetails')
.controller('UserDetailsController', ['$http', '$stateParams', function ($http, $stateParams, $scope) {
.controller('UserDetailsController', ['$http', '$stateParams', '$location', function ($http, $stateParams, $location) {

let self = this;
self.userId = $stateParams.userId;
Expand All @@ -14,5 +14,8 @@ angular.module('userDetails')
.catch(function (error) {
$scope.errorMessages = n.data.message.split`\n`;
});
}]);

self.goToAdminPanel = function() {
$location.path("/adminPanel");
}
}]);
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,35 @@
<meta charset="UTF-8">
<title>Title</title>
</head>
<body >
<div ng-controller="UserDetailsController as userDetails">
<h3>User Details for ID: {{ userDetails.userId }}</h3>
<p><strong>Username:</strong> {{ userDetails.user ? userDetails.user.username : 'N/A' }}</p>
<p><strong>Email:</strong> {{ userDetails.user ? userDetails.user.email : 'N/A' }}</p>
<p><strong>Roles:</strong> {{ userDetails.user ? userDetails.user.roles : 'N/A' }}</p>
<body>
<div ng-controller="UserDetailsController as userDetails" class="user-details">
<h3>User Details for ID: {{ userDetails.userId }}</h3>
<p><strong>Username:</strong> {{ userDetails.user ? userDetails.user.username : 'N/A' }}</p>
<p><strong>Email:</strong> {{ userDetails.user ? userDetails.user.email : 'N/A' }}</p>
<p><strong>Roles:</strong>
<span ng-repeat="role in userDetails.user.roles">
{{role.name}}
<span ng-if="!$last">, </span>
</span>
</p>
<button class="btn btn-primary" ng-click="userDetails.goToAdminPanel()" >Back</button>
</div>

<!-- Map these fields so that display depending on the user's role -->
</body>
</html>

<!-- &lt;!&ndash; Display different details based on the user's role &ndash;&gt;-->
<!-- <div ng-if="userDetails.user && userDetails.user.roles === 'ADMIN'">-->
<!-- <p><strong>Role:</strong> Admin</p>-->
<!-- &lt;!&ndash; Add admin-specific details here &ndash;&gt;-->
<!-- </div>-->

<!-- <div ng-if="userDetails.user === userDetails.role.owner ">-->
<!-- <p><strong>Role:</strong> Owner</p>-->
<!-- &lt;!&ndash; Add customer-specific details here &ndash;&gt;-->
<!-- <p><strong>First Name:</strong> {{ userDetails.user.owner.firstName || 'N/A' }}</p>-->
<!-- <p><strong>Last Name:</strong> {{ userDetails.user.owner.lastName || 'N/A' }}</p>-->
<!-- &lt;!&ndash; Add more customer-specific details here &ndash;&gt;-->
<!-- </div>-->
<style>
.user-details {
font-family: Arial, sans-serif;
color: #333;
}

.user-details h3 {
color: #007BFF;
}

<!-- <div ng-if="userDetails.user === userDetails.role.vet ">-->
<!-- <p><strong>Role:</strong> Vet</p>-->
<!-- &lt;!&ndash; Add customer-specific details here &ndash;&gt;-->
<!-- <p><strong>First Name:</strong> {{ userDetails.user.vet.firstName || 'N/A' }}</p>-->
<!-- <p><strong>Last Name:</strong> {{ userDetails.user.vet.lastName || 'N/A' }}</p>-->
<!-- &lt;!&ndash; Add more customer-specific details here &ndash;&gt;-->
<!-- </div>-->

</div>

</body>
</html>
.user-details p {
margin-bottom: 10px;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -534,4 +534,50 @@ void ShouldVerifyUserToken_ShouldReturnInvalid(){
.expectNextCount(0)
.verifyError();
}

@Test
@DisplayName("Should create a vet user")
void shouldCreateVetUser() throws IOException {
// Arrange
RegisterVet registerVet = RegisterVet.builder()
.username("username")
.password("password")
.email("email")
.build();
Mono<RegisterVet> registerVetMono = Mono.just(registerVet);

// Set up the MockWebServer to return a specific response
final MockResponse mockResponse = new MockResponse();
mockResponse
.setHeader("Content-Type", "application/json")
.setResponseCode(200);
server.enqueue(mockResponse);

// Act
Mono<VetResponseDTO> result = authServiceClient.createVetUser(registerVetMono);

// Assert
StepVerifier.create(result)
.expectNextCount(0)
.verifyComplete();
}

@Test
void deleteUser_ShouldReturnOk() throws Exception {
final MockResponse mockResponse = new MockResponse();
mockResponse
.setResponseCode(200);

server.enqueue(mockResponse);

String jwtToken = "jwtToken";
String userId = "userId";

final Mono<Void> validatedTokenResponse = authServiceClient.deleteUser(jwtToken, userId);

// check status response in step verifier
StepVerifier.create(Mono.just(validatedTokenResponse))
.expectNextCount(1)
.verifyComplete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3708,6 +3708,26 @@ public void getUserById_ValidUserId_ShouldReturnUser() {
assertEquals(userDetails.getEmail(), u.getEmail());
});
}

@Test
void deleteUserById_ValidUserId_ShouldDeleteUser() {
UserDetails userDetails = UserDetails.builder()
.userId("validUserId")
.username("validUsername")
.email("validEmail")
.build();

when(authServiceClient.deleteUser(anyString(), anyString()))
.thenReturn(Mono.empty());

client.delete()
.uri("/api/gateway/users/validUserId")
.cookie("Bearer", "validToken")
.exchange()
.expectStatus().isNoContent();
}


private EducationResponseDTO buildEducation(){
return EducationResponseDTO.builder()
.educationId("1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,21 @@ public interface UserService {

User createUser(UserIDLessRoleLessDTO user);



List<UserDetails> findAllWithoutPage();

//void deleteUser(long id);

Mail generateVerificationMail(User user);

UserPasswordLessDTO verifyEmailFromToken(String token);

HashMap<String, Object> login(UserIDLessUsernameLessDTO user) throws IncorrectPasswordException;


User getUserByEmail(String email) throws NotFoundException;

User getUserByUserId(String userIid);
List<UserDetails> getUsersByUsernameContaining(String username);
User getUserByUserId(String userId);

void deleteUser(String userId);

List<UserDetails> getUsersByUsernameContaining(String username);

void processForgotPassword(UserResetPwdRequestModel userResetPwdWithTokenRequestModel);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ public User createUser(@Valid UserIDLessRoleLessDTO userIDLessDTO) {
format("User with username %s already exists", userIDLessDTO.getUsername()));
}


// add exception when trying to create a user with existing username

User user = userMapper.idLessRoleLessDTOToModel(userIDLessDTO);

if (userIDLessDTO.getDefaultRole() == null|| userIDLessDTO.getDefaultRole().isEmpty()){
Expand Down Expand Up @@ -446,6 +443,17 @@ public User getUserByUserId(String userId) {
.orElseThrow(() -> new NotFoundException("No user with userId: " + userId));
}

@Override
public void deleteUser(String userId) {
User user = userRepo.findUserByUserIdentifier_UserId(userId);
if (user != null) {
userRepo.delete(user);
} else {
throw new NotFoundException("No user with userId: " + userId);
}
}


@Override
public List<UserDetails> getUsersByUsernameContaining(String username) {
return userMapper.modelToDetailsList(userRepo.findByUsernameContaining(username));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

Check warning on line 38 in auth-service/src/main/java/com/petclinic/authservice/presentationlayer/User/UserController.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Unused import

Unused import `import reactor.core.publisher.Mono;`

import java.util.Base64;
import java.util.HashMap;
Expand Down Expand Up @@ -177,6 +178,15 @@ public ResponseEntity<Void> processResetPassword(@RequestBody @Valid UserResetPw
return ResponseEntity.ok().build();
}

@DeleteMapping("/{userId}")
public ResponseEntity<Void> deleteUser(@PathVariable String userId) {

userService.deleteUser(userId);

return ResponseEntity.noContent().build();
}


private boolean isValidBase64(String s) {
try {
Base64.getDecoder().decode(s);
Expand Down
Loading

0 comments on commit 2d50478

Please sign in to comment.