Skip to content

Commit

Permalink
Merge pull request #85 from CMIPT/feature-kaiser
Browse files Browse the repository at this point in the history
Add functionality of sending email code.
  • Loading branch information
luckygalaxy666 authored Nov 8, 2024
2 parents f1febd6 + df7cf15 commit a38f188
Show file tree
Hide file tree
Showing 28 changed files with 704 additions and 277 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,10 @@ replay_pid*

# this file should be generated by the helper script
application.properties

# debug configure file
config_debug_docker.json
config_debug.json

# user configure file
config.json
29 changes: 28 additions & 1 deletion README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
| `staticLocations` | `list` | `null` | 静态资源的路径,使用绝对路径,例如 `['/home/gcs/static']`|
| `redisHost` | `string` | `"localhost"` | `Redis` 主机地址。 |
| `redisPort` | `int` | `6379` | `Redis` 端口。 |
| `springMailDefaultEncoding` | `string` | `"UTF-8"` | `Spring` 邮件默认编码。 |
| `springMailProtocol` | `string` | `null` | `Spring` 邮件协议。 |
| `springMailHost` | `string` | `null` | `Spring` 邮件主机地址。 |
| `springMailPort` | `int` | `null` | `Spring` 邮件端口。 |
| `springMailUsername` | `string` | `null` | `Spring` 邮件用户名。 |
| `springMailPassword` | `string` | `null` | `Spring` 邮件密码。 |

## 手动部署
手动部署可以在任意的 `UNIX-like` 系统上面进行,下面依次介绍你需要手动完成的操作。
Expand Down Expand Up @@ -247,6 +253,18 @@ gitolite.admin.repository.path=
spring.redis.host=
# redis 端口
spring.redis.port=
# 邮件默认编码,通常为 UTF-8
spring.mail.default-encoding=
# 邮件协议
spring.mail.protocol=
# 邮件主机地址
spring.mail.host=
# 邮件端口
spring.mail.port=
# 邮件用户名
spring.mail.username=
# 邮件密码
spring.mail.password=
```

**注意**:所有的后端接口均是以 `gcs` 开头,所以在静态资源路径下面不应该有名为 `gcs`
Expand Down Expand Up @@ -315,14 +333,23 @@ front-end.url=
spring.mvc.static-path-pattern=
spring.resources.static-locations=
gitolite.admin.repository.path=/home/$USER/gitolite-admin
spring.redis.host=localhost
spring.redis.port=6379
spring.mail.default-encoding=UTF-8
spring.mail.protocol=
spring.mail.host=
spring.mail.port=
spring.mail.username=
spring.mail.password=
```

其中 `$1` 会被替换成执行脚本时传入的第一个参数。脚本的使用方法为
`bash prepare_dev.sh <db_postgres_password>`,其中的 `<db_postgres_password>`
`postgres` 用户 (这里指数据库中的用户而不是 `OS` 中的用户) 的密码,在执行脚本之前确保当前用户可以使用
`sudo` 进行操作。

在脚本执行成功后,开发者便可以通过 `mvn spring-boot:run` 启动程序,或者通过 `mvn test` 执行单元测试。
在脚本执行成功后,开发者还需要填入用于测试的邮箱相关配置。
完成后,开发者便可以通过 `mvn spring-boot:run` 启动程序,或者通过 `mvn test` 执行单元测试。

**注意**:有时在执行 `mvn spring-boot:run` 或者 `mvn test` 时会提示 `target` 目录的权限不够,这往往
是因为在使用 `bash prepare_dev.sh <db_postgres_password` 之前可能以其他用户的身份执行过 `mvn` 命令,
Expand Down
8 changes: 7 additions & 1 deletion config_default.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,11 @@
"staticPathPattern": null,
"staticLocations": null,
"redisHost": "localhost",
"redisPort": 6379
"redisPort": 6379,
"springMailDefaultEncoding": "UTF-8",
"springMailProtocol": null,
"springMailHost": null,
"springMailPort": null,
"springMailUsername": null,
"springMailPassword": null
}
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
6 changes: 6 additions & 0 deletions prepare_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,10 @@ spring.resources.static-locations=
gitolite.admin.repository.path=/home/$USER/gitolite-admin
spring.redis.host=localhost
spring.redis.port=6379
spring.mail.default-encoding=UTF-8
spring.mail.protocol=
spring.mail.host=
spring.mail.port=
spring.mail.username=
spring.mail.password=
" > src/main/resources/application.properties
58 changes: 41 additions & 17 deletions script/deploy_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,14 @@ def parse_iterable_into_str(iterable, sep=" "):
return sep.join(iterable).strip()


def write_content_to_file(content, file_path, mode = 'w'):
def write_content_to_file(content, file_path, mode='w'):
try:
with open(file_path, mode) as f:
f.write(content)
except Exception as e:
command_checker(1, f"Error: {e}")


def create_systemd_service(config):
assert(config != None)
exec_start = parse_iterable_into_str([config.serviceStartJavaCommand] +
Expand Down Expand Up @@ -134,7 +135,8 @@ def create_sys_v_init_service(config):
'''
service_content = header + service_content
log_debug(f"service_content:\n {service_content}")
write_content_to_file(service_content, f'{config.serviceSysVInitDirectory}/{config.serviceName}')
write_content_to_file(
service_content, f'{config.serviceSysVInitDirectory}/{config.serviceName}')
res = os.system(f'chmod +x {config.serviceSysVInitDirectory}/{config.serviceName}')
command_checker(
res, f"Failed to chmod +x {config.serviceSysVInitDirectory}/{config.serviceName}")
Expand Down Expand Up @@ -295,7 +297,7 @@ def init_database(config):
config_datasource(config)


def create_or_update_user(username, password, homeDirectory = None):
def create_or_update_user(username, password, homeDirectory=None):
if username == None or username == "":
return
if os.system(f"cat /etc/passwd | grep -w -E '^{username}'") != 0:
Expand All @@ -307,7 +309,7 @@ def create_or_update_user(username, password, homeDirectory = None):
res = os.system(command)
message = message_tmp.format(command, res)
command_checker(res, message)
elif homeDirectory is not None: # update the home directory
elif homeDirectory is not None: # update the home directory
command = f'usermod -d {homeDirectory} {username}'
res = os.system(command)
message = message_tmp.format(command, res)
Expand Down Expand Up @@ -339,6 +341,12 @@ def write_other_config(config):
"staticLocations": "spring.web.resources.static-locations",
"redisHost": "spring.redis.host",
"redisPort": "spring.redis.port",
"springMailHost": "spring.mail.host",
"springMailPort": "spring.mail.port",
"springMailUsername": "spring.mail.username",
"springMailPassword": "spring.mail.password",
"springMailProtocol": "spring.mail.protocol",
"springMailDefaultEncoding": "spring.mail.default-encoding",
}
if config.frontEndUrl is None:
config.frontEndUrl = ""
Expand Down Expand Up @@ -411,9 +419,10 @@ def init_gitolite(config):
log_debug(f"Create usr directory command: {command}")
command_checker(os.system(command), f"Failed to create usr directory in gitolite-admin/conf")
command = (f"su -c 'mkdir -p {config.serviceUserHomeDirectory}/gitolite-admin/conf/gitolite.d/repository' "
f"{config.serviceUser}")
f"{config.serviceUser}")
log_debug(f"Create repository directory command: {command}")
command_checker(os.system(command), f"Failed to create repository directory in gitolite-admin/conf")
command_checker(os.system(command),
f"Failed to create repository directory in gitolite-admin/conf")
content = f'''
repo gitolite-admin
RW+ = {config.serviceUser}
Expand All @@ -425,15 +434,16 @@ def init_gitolite(config):
repo @all_public_repo
R = @all
'''
write_content_to_file(content, f'{config.serviceUserHomeDirectory}/gitolite-admin/conf/gitolite.conf')
write_content_to_file(
content, f'{config.serviceUserHomeDirectory}/gitolite-admin/conf/gitolite.conf')
# create the usr directory in gitolite-admin/conf
# configure the username and email for gitolite-admin
command = (f"su -c 'git -C {config.serviceUserHomeDirectory}/gitolite-admin "
f"config user.name \"{config.adminName}\"' {config.serviceUser}")
f"config user.name \"{config.adminName}\"' {config.serviceUser}")
log_debug(f"Config username command: {command}")
command_checker(os.system(command), f"Failed to config username")
command = (f"su -c 'git -C {config.serviceUserHomeDirectory}/gitolite-admin "
f"config user.email \"{config.adminEmail}\"' {config.serviceUser}")
f"config user.email \"{config.adminEmail}\"' {config.serviceUser}")
log_debug(f"Config email command: {command}")
command_checker(os.system(command), f"Failed to config email")
command = (f"su -c \"git -C {config.serviceUserHomeDirectory}/gitolite-admin "
Expand All @@ -445,6 +455,7 @@ def init_gitolite(config):
log_debug(f"Push command: {command}")
command_checker(os.system(command), f"Failed to push the change")


def install_redis():
# check if redis has been installed
if os.system('command -v redis-cli') == 0:
Expand Down Expand Up @@ -486,12 +497,14 @@ def deploy_on_ubuntu(config):
if os.path.exists(f'{config.serviceUserHomeDirectory}/.ssh'):
res = os.system(f'rm -rf {config.serviceUserHomeDirectory}/.ssh')
command_checker(res, f"Failed to remove {config.serviceUserHomeDirectory}/.ssh")
res = os.system(f"su -c \"ssh-keygen -f {config.serviceUserHomeDirectory}/.ssh/id_rsa -N ''\" {config.serviceUser}")
res = os.system(
f"su -c \"ssh-keygen -f {config.serviceUserHomeDirectory}/.ssh/id_rsa -N ''\" {config.serviceUser}")
command_checker(res, f"Failed to generate ssh key for {config.serviceUser}")
init_gitolite(config)
# let the service user can use git, rm and tee commands as the git user without password
sudoers_entry = f"{config.serviceUser} ALL=({config.gitUserName}) NOPASSWD: /usr/bin/rm"
res = subprocess.run(f"echo '{sudoers_entry}' | tee /etc/sudoers.d/{config.serviceUser}", shell=True);
res = subprocess.run(
f"echo '{sudoers_entry}' | tee /etc/sudoers.d/{config.serviceUser}", shell=True)
command_checker(res.returncode, f"Failed to create /etc/sudoers.d/{config.serviceUser}")
res = subprocess.run(f"chmod 440 /etc/sudoers.d/{config.serviceUser}", shell=True)
command_checker(res.returncode, f"Failed to chmod 440 /etc/sudoers.d/{config.serviceUser}")
Expand Down Expand Up @@ -532,6 +545,7 @@ def delete_user(username):
message = message_tmp.format(command, res)
command_checker(res, message)


def clean(config):
if config.deployWithDocker:
res = os.system(f"docker stop {config.dockerName}")
Expand Down Expand Up @@ -601,15 +615,17 @@ def get_cli_args():
deploy_helper.py [OPTION]... [--config-path PATH] [--distro DISTRO]
or: deploy_helper.py [OPTION]... --clean
or: deploy_helper.py [OPTION]... [--log-level LEVEL] [--in-docker]"""
)
)
parser.add_argument('--config-path', nargs='?', default='../config.json',
type=str, help="Default to '../config.json'. Path to config JSON file.")
parser.add_argument('--distro', nargs='?', default='ubuntu',
type=str, help="Default to 'ubuntu'. Set linux distribution.")
parser.add_argument('--default-config-path', nargs='?', default='../config_default.json',
type=str, help="Default to '../config_default.json'. Path to default config JSON file.")
parser.add_argument('--clean', action='store_true', help="Default to false. Clean up the project.")
parser.add_argument('--in-docker', action='store_true', help="Default to false. Whether or not deploy in docker.")
parser.add_argument('--clean', action='store_true',
help="Default to false. Clean up the project.")
parser.add_argument('--in-docker', action='store_true',
help="Default to false. Whether or not deploy in docker.")
parser.add_argument('--log-level', nargs='?', default='INFO',
type=str, help=("""\
Default to 'INFO'.
Expand All @@ -625,8 +641,7 @@ def get_cli_args():
from working. The application is still running but encountered a failure.
- CRITICAL: A severe error occurred, causing the application to
stop or severely impact functionality. Immediate attention is required.
"""
))
"""))
return parser.parse_args()


Expand All @@ -650,6 +665,15 @@ def deploy_with_docker(config):
return


def check_args(config):
# TODO: add more checks
required_fields = ['springMailHost', 'springMailPort',
'springMailUsername', 'springMailPassword']
for field in required_fields:
if not hasattr(config, field):
raise ValueError(f"Missing required field: {field}")


def main():
args = get_cli_args()
if args.log_level.upper() not in logging._nameToLevel:
Expand All @@ -661,7 +685,7 @@ def main():
setattr(config, 'configPath', args.config_path)
setattr(config, 'defaultConfigPath', args.default_config_path)
setattr(config, 'distro', args.distro)
# TODO: add args check
check_args(config)
if args.clean:
clean(config)
elif not args.in_docker and config.deployWithDocker:
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/edu/cmipt/gcs/constant/ApiPathConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class ApiPathConstant {
AUTHENTICATION_API_PREFIX + "/signout";
public static final String AUTHENTICATION_REFRESH_API_PATH =
AUTHENTICATION_API_PREFIX + "/refresh";
public static final String AUTHENTICATION_SEND_EMAIL_VERIFICATION_CODE_API_PATH =
AUTHENTICATION_API_PREFIX + "/send-email-verification-code";

public static final String DEVELOPMENT_API_PREFIX = ALL_API_PREFIX + "/developer";
public static final String DEVELOPMENT_GET_API_MAP_API_PATH = DEVELOPMENT_API_PREFIX + "/api";
Expand All @@ -30,6 +32,10 @@ public class ApiPathConstant {
public static final String USER_DELETE_USER_API_PATH = USER_API_PREFIX + "/delete";
public static final String USER_PAGE_USER_REPOSITORY_API_PATH =
USER_API_PREFIX + "/page/repository";
public static final String USER_UPDATE_USER_PASSWORD_WITH_OLD_PASSWORD_API_PATH =
USER_API_PREFIX + "/update-password-with-old-password";
public static final String USER_UPDATE_USER_PASSWORD_WITH_EMAIL_VERIFICATION_CODE_API_PATH =
USER_API_PREFIX + "/update-password-with-email-verification-code";

public static final String REPOSITORY_API_PREFIX = ALL_API_PREFIX + "/repository";
public static final String REPOSITORY_CREATE_REPOSITORY_API_PATH =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public class ApplicationConstant {
public static final String TEST_PROFILE = "test";
public static final long ACCESS_TOKEN_EXPIRATION = 10 * 60 * 1000L; // 10 minutes
public static final long REFRESH_TOKEN_EXPIRATION = 30 * 24 * 60 * 60 * 1000L; // 30 days
public static final long EMAIL_VERIFICATION_CODE_EXPIRATION = 5 * 60 * 1000L; // 5 minutes
}
3 changes: 3 additions & 0 deletions src/main/java/edu/cmipt/gcs/constant/ValidationConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ public class ValidationConstant {

public static final int MIN_SSH_KEY_PUBLICKEY_LENGTH = 1;
public static final int MAX_SSH_KEY_PUBLICKEY_LENGTH = 4096;

public static final int EMAIL_VERIFICATION_CODE_LENGTH = 6;
public static final String EMAIL_VERIFICATION_CODE_PATTERN = "^[0-9]*$";
}
Loading

0 comments on commit a38f188

Please sign in to comment.