Skip to content

Commit

Permalink
Add rout to change password
Browse files Browse the repository at this point in the history
  • Loading branch information
Knorrke committed Jun 15, 2024
1 parent f9d99e2 commit c7c63d4
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/main/java/config/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public void setupRoutes(JavalinConfig config) {
get("/user/profile/{username}", userController::showProfile);
get("/user/update", userController::updateProfile);
post("/user/update", userController::updateProfile);
get("/user/change-password", userController::changePassword);
post("/user/change-password", userController::changePassword);

get("/", postController::getPosts);
get("/pinnwand/{username}", userController::showProfile);
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/modules/user/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.javalin.http.Context;
import io.javalin.http.HandlerType;
import io.javalin.http.HttpStatus;
import io.javalin.http.InternalServerErrorResponse;
import io.javalin.http.NotFoundResponse;
import io.javalin.http.UnauthorizedResponse;
Expand Down Expand Up @@ -48,6 +49,7 @@ public void login(Context ctx) {
return;
} else {
model.put("error", "Login fehlgeschlagen.");
ctx.status(HttpStatus.UNAUTHORIZED);
}
}

Expand Down Expand Up @@ -142,4 +144,35 @@ public void updateProfile(Context ctx) {
model.put("authenticatedUser", authenticatedUser);
ctx.render("user/updateProfile.ftl", model);
}

public void changePassword(Context ctx) {
User authenticatedUser = userService.getAuthenticatedUser(ctx);
if (authenticatedUser == null) {
throw new UnauthorizedResponse("Du bist nicht angemeldet!");
}
Map<String, Object> model = new HashMap<>();
if (ctx.method() == HandlerType.POST) {
MultiMap<String> params = EncodingUtil.decode(ctx);
if (params.getString("new_password").equals(params.getString("new_password2"))) {
// fetch user again to keep password out of session
User user = userService.getUserById(authenticatedUser.getId());
user.setPassword(params.getString("password"));
User validated = userService.checkUser(user);

if (validated != null) {
validated.setPassword(params.getString("new_password"));
userService.updatePassword(validated);
model.put("success", "Profil erfolgreich aktualisiert");
} else {
model.put("error", "Falsches Passwort.");
ctx.status(HttpStatus.UNAUTHORIZED);
}
} else {
model.put("error", "Passwörter stimmen nicht überein.");
}
}

model.put("authenticatedUser", authenticatedUser);
ctx.render("user/changePassword.ftl", model);
}
}
9 changes: 9 additions & 0 deletions src/main/java/modules/user/dao/UserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ public void updateUser(User oldUser, User newUser) {
oldUser.setAbout(newUser.getAbout());
}

@Override
public void updatePassword(User newUser) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(ID, newUser.getId());
params.put(PASSWORD, newUser.getPassword());
String sql = "UPDATE users " + "SET password=:password " + "WHERE user_id = :user_id";
template.update(sql, params);
}

private String generateOrderByFromParams(String sortBy, boolean asc) {
String order = asc ? "ASC" : "DESC";

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/modules/user/dao/UserDaoInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public interface UserDaoInterface {
List<User> getAllUsersSorted(String sortBy, boolean asc, int limit);

void updateUser(User oldUser, User newUser);

void updatePassword(User newUser);
}
5 changes: 5 additions & 0 deletions src/main/java/modules/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public void registerUser(User user) throws InputTooLongException {
userDaoInterface.registerUser(user);
}

public void updatePassword(User validated) {
validated.setPassword(PasswordUtil.hashPassword(validated.getPassword()));
userDaoInterface.updatePassword(validated);
}

public List<User> getAllUsersSorted(String sortBy, boolean asc, int limit) {
return userDaoInterface.getAllUsersSorted(sortBy, asc, limit);
}
Expand Down
18 changes: 16 additions & 2 deletions src/main/resources/public/assets/v4.2.0/css/content.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
}

.warning {
background-color: #ffcc66;
background-color: var(--warning);
border-radius: 20px;
position: relative;
padding-left: 70px !important;
padding: 15px 0 15px 70px !important;
}

.warning::before {
Expand All @@ -22,6 +22,20 @@
font-size: 30pt;
}

.error {
background-color: var(--warning);
border-radius: 20px;
position: relative;
padding: 15px;
}

.success {
background-color: var(--success);
border-radius: 20px;
position: relative;
padding: 15px;
}

.colored {
background: var(--bg-media);
border-radius: 20px;
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/public/assets/v4.2.0/css/layout.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
:root {
/** using color palette https://coolors.co/f0f7fa-8ecae6-219ebc-023047-ffb703-fb8500 */
/** using color palette https://coolors.co/f0f7fa-8ecae6-219ebc-023047-37be3c-ffb703-fb8500 */
--bg-layout: #023047;
--color-layout: #fff;
--hover-header: #fb8500;
--warning: #ffb703;
--success: #37be3c;
--bg-main: #fff;
--bg-content: #f2f2f2;
--color-content: #000;
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/error/error.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<@layout.masterTemplate title="${error.status} &mdash; ${defaultMessage}" colored=false pageTitle=pageTitle>
<p>Bei der Bearbeitung der Anfrage ist leider ein Fehler aufgetreten:</p>
<div class="warning">
<p style="padding: 15px 0;">${error.message}</p>
<p>${error.message}</p>
</div>
</@layout.masterTemplate>
40 changes: 40 additions & 0 deletions src/main/resources/templates/user/changePassword.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<#import "../layout/layout.ftl" as layout />
<#import "../common/fa-icons.ftl" as fa/>

<@layout.masterTemplate pageTitle="Profil aktualisieren">
<#if success??>
<div class="success">
${success}
</div>
</#if>
<#if error??>
<div class="error">
<strong>Error:</strong> ${error}
</div>
</#if>
<form action="/user/change-password" method="post">
<dl>
<dt>Aktuelles Passwort:
<dd>
<span class="text-element">
<input type="password" name="password" size="30">
</span>
</dd>
</dl>
<dl>
<dt>Neues Passwort:
<dd>
<span class="text-element">
<input type="password" name="new_password" size="30">
</span>
</dd>
<dt>Neues Passwort wiederholen:
<dd>
<span class="text-element">
<input type="password" name="new_password2" size="30">
</span>
</dd>
</dl>
<div class="actions"><button class="button colored" type="submit"><@fa.icon fa="save" /> Aktualisieren</button></div>
</form>
</@layout.masterTemplate>
3 changes: 3 additions & 0 deletions src/main/resources/templates/user/profile.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
<div class="media colored">
<a href="/user/update">Profil bearbeiten</a>
</div>
<div class="media colored">
<a href="/user/change-password">Passwort ändern</a>
</div>
</#if>
</div>
</div>
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/base/IntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ protected Response login(HttpClient client, String username) {
client, "/login", String.format("username=%s&password=test", username));
}

protected Response login(HttpClient client, String username, String password) {
return postWithUrlEncodedBody(
client, "/login", String.format("username=%s&password=%s", username, password));
}

protected Response postWithUrlEncodedBody(HttpClient client, String path, String body) {
return postWithUrlEncodedBody(client, path, body, null);
}
Expand Down
56 changes: 56 additions & 0 deletions src/test/java/modules/user/UserControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,62 @@ void updateProfile() {
});
}

@Test
void unauthorizedPasswordChange() {
JavalinTest.test(
app,
(server, client) -> {
Response response =
postWithUrlEncodedBody(
client, "/user/update", "password=test&new_password=test&new_password2=test");
assertThat(response.code())
.as("Unauthorized request")
.isEqualTo(HttpStatus.UNAUTHORIZED.getCode());
});
}

@Test
void wrongPasswordChange() {
JavalinTest.test(
app,
withCookies(),
(server, client) -> {
assertThat(login(client, "test").code()).isEqualTo(200);
Response response =
postWithUrlEncodedBody(
client,
"/user/change-password",
"password=wrong&new_password=test&new_password2=test");
assertThat(response.code())
.as("Wrong password")
.isEqualTo(HttpStatus.UNAUTHORIZED.getCode());
assertThat(response.body().string())
.as("Error message displayed")
.contains("Falsches Passwort");
});
}

@Test
void changePassword() {
JavalinTest.test(
app,
withCookies(),
(server, client) -> {
assertThat(login(client, "test").code()).isEqualTo(200);
Response response =
postWithUrlEncodedBody(
client,
"/user/change-password",
"password=test&new_password=changed&new_password2=changed");
assertThat(response.code()).as("Change password").isEqualTo(200);
assertThat(response.body().string()).as("Successfull").contains("erfolgreich");
assertThat(login(client, "test").code()).as("Old password invalidated").isEqualTo(401);
assertThat(login(client, "test", "changed").code())
.as("New password valid")
.isEqualTo(200);
});
}

@Test
void inputTooLong() {
JavalinTest.test(
Expand Down

0 comments on commit c7c63d4

Please sign in to comment.