Skip to content

Commit

Permalink
build: add ci config and optimize update password. (#326)
Browse files Browse the repository at this point in the history
* update: optimize user password update.

* build: add github workflow config.

* test: fix UserServiceTest#updatePassword.
  • Loading branch information
chivehao authored Jun 17, 2023
1 parent 3e17dec commit aebf020
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 32 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/ikaros_ci_build_dev_container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# This is a basic workflow to help you get started with Actions

name: ikaros_ci_build_dev_container

# Controls when the workflow will run
on:
# Triggers the workflow on push events but only for the "master" branch
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
cache: 'gradle'
java-version: 17
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: |
./gradlew clean build -x test
- name: Set up QEMU
uses: docker/setup-qemu-action@v1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build image and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: |
ikarosrun/ikaros:dev
49 changes: 49 additions & 0 deletions .github/workflows/ikaros_ci_build_tag_container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: ikaros_ci_build_tag_container

on:
push:
branches:
- release-*
tags:
- '*'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
cache: 'gradle'
java-version: 17
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: |
./gradlew clean build -x test
- name: Set up QEMU
uses: docker/setup-qemu-action@v1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build image and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: |
ikarosrun/ikaros:${{ github.ref_name }}
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM eclipse-temurin:17-jre as builder
WORKDIR application
ARG JAR_FILE=server/build/libs/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

###########################################################

FROM eclipse-temurin:17-jre
MAINTAINER li-guohao <git@liguohao.cn>
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

ENV JVM_OPTS="-Xmx256m -Xms256m" \
HALO_WORK_DIR="/root/.ikaros" \
SPRING_CONFIG_LOCATION="optional:classpath:/;optional:file:/root/.ikaros/" \
TZ=Asia/Shanghai

RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone

EXPOSE 9999

ENTRYPOINT ["sh", "-c", "java ${JVM_OPTS} org.springframework.boot.loader.JarLauncher ${0} ${@}"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package run.ikaros.api.exception;

import org.springframework.security.core.AuthenticationException;

public class PasswordNotMatchingException extends AuthenticationException {
public PasswordNotMatchingException(String msg) {
super(msg);
}

public PasswordNotMatchingException(String msg, Throwable cause) {
super(msg, cause);
}
}
4 changes: 2 additions & 2 deletions console/src/modules/system/user/Profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ onMounted(initProfileAndUsername);
<el-input
v-model="passwordReq.oldPassword"
style="max-width: 600px"
clearable
type="password"
show-password
/>
</el-form-item>
<el-form-item label="新密码">
<el-input
v-model="passwordReq.newPassword"
style="max-width: 600px"
clearable
type="password"
show-password
/>
</el-form-item>
<el-form-item>
Expand Down
50 changes: 22 additions & 28 deletions console/src/utils/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ export interface ProblemDetail {
axiosInstance.interceptors.response.use(
(response) => response,
async (error: AxiosError<ProblemDetail>) => {
if (/Network Error/.test(error.message)) {
// @ts-ignore
let msg = error?.response?.data?.message;
if (!msg) {
msg = error.message;
}

if (/Network Error/.test(msg)) {
console.error(
i18n.global.t('core.common.exception.network_error') +
': ' +
error.message,
i18n.global.t('core.common.exception.network_error') + ': ' + msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.network_error') +
': ' +
error.message
i18n.global.t('core.common.exception.network_error') + ': ' + msg
);
return Promise.reject(error);
}
Expand All @@ -50,15 +52,11 @@ axiosInstance.interceptors.response.use(

if (!errorResponse) {
console.error(
i18n.global.t('core.common.exception.network_error') +
': ' +
error.message,
i18n.global.t('core.common.exception.network_error') + ': ' + msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.network_error') +
': ' +
error.message
i18n.global.t('core.common.exception.network_error') + ': ' + msg
);
return Promise.reject(error);
}
Expand All @@ -77,65 +75,61 @@ axiosInstance.interceptors.response.use(
ElMessage.error(
i18n.global.t('core.common.exception.request_parameter_error') +
': ' +
error.message
msg
);
} else if (status === 401) {
console.error(
i18n.global.t('core.common.exception.unauthorized') +
': ' +
error.message,
i18n.global.t('core.common.exception.unauthorized') + ': ' + msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.unauthorized') +
': ' +
error.message
i18n.global.t('core.common.exception.unauthorized') + ': ' + msg
);
} else if (status === 403) {
console.error(
i18n.global.t('core.common.exception.forbidden') + ': ' + error.message,
i18n.global.t('core.common.exception.forbidden') + ': ' + msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.forbidden') + ': ' + error.message
i18n.global.t('core.common.exception.forbidden') + ': ' + msg
);
} else if (status === 404) {
console.error(
i18n.global.t('core.common.exception.not_found') + ': ' + error.message,
i18n.global.t('core.common.exception.not_found') + ': ' + msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.not_found') + ': ' + error.message
i18n.global.t('core.common.exception.not_found') + ': ' + msg
);
} else if (status === 500) {
console.error(
i18n.global.t(
'core.common.exception.server_internal_error_with_title'
) +
': ' +
error.message,
msg,
error
);
ElMessage.error(
i18n.global.t(
'core.common.exception.server_internal_error_with_title'
) +
': ' +
error.message
msg
);
} else {
console.error(
i18n.global.t('core.common.exception.unknown_error_with_title', {
title,
}) +
': ' +
error.message,
msg,
error
);
ElMessage.error(
i18n.global.t('core.common.exception.unknown_error_with_title') +
': ' +
error.message
msg
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;
import run.ikaros.api.exception.NotFoundException;
import run.ikaros.api.exception.PasswordNotMatchingException;
import run.ikaros.server.store.entity.UserEntity;
import run.ikaros.server.store.repository.RoleRepository;
import run.ikaros.server.store.repository.UserRepository;
Expand Down Expand Up @@ -74,7 +75,8 @@ public Mono<Void> updatePassword(@NotBlank String username, @NotBlank String old
.filter(userEntity -> passwordEncoder.matches(oldRawPassword,
addEncodingIdPrefixIfNotExists(userEntity.getPassword())))
.switchIfEmpty(Mono.error(
new RuntimeException("Old password not matching username: " + username)))
new PasswordNotMatchingException(
"Old password not matching username: " + username)))
.filter(userEntity -> !StringUtils.hasText(userEntity.getPassword())
|| !passwordEncoder.matches(rawPassword,
addEncodingIdPrefixIfNotExists(userEntity.getPassword())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import run.ikaros.api.exception.PasswordNotMatchingException;
import run.ikaros.server.security.SecurityProperties;
import run.ikaros.server.store.entity.UserEntity;

Expand Down Expand Up @@ -139,7 +140,8 @@ void updatePassword() {

// update by same password
StepVerifier.create(userService.updatePassword(username, oldPassword, newPassword))
.expectErrorMatches(throwable -> throwable.getClass() == RuntimeException.class
.expectErrorMatches(throwable ->
throwable.getClass() == PasswordNotMatchingException.class
&& throwable.getMessage().startsWith("Old password not matching username: "))
.verify();

Expand Down

0 comments on commit aebf020

Please sign in to comment.