Compare commits
86 Commits
main
...
feature/BE
Author | SHA1 | Date | |
---|---|---|---|
d349de766a | |||
4bebd26cd5 | |||
830800a313 | |||
ee3f1bfe41 | |||
34fc328308 | |||
7027f96cde | |||
5d279b8b92 | |||
84c96236f7 | |||
eeee00e344 | |||
78e0765a13 | |||
6b675842ec | |||
a878ed8e3c | |||
2cc220d9d8 | |||
c2d1f8a5c0 | |||
b67f702c5e | |||
b8ad85791e | |||
ef03747b8b | |||
61b104b92c | |||
8fc983f510 | |||
f4e73382e3 | |||
62f76d5c1d | |||
135bc3b5e2 | |||
ed21c3f9e3 | |||
ecd54600de | |||
a241d3539d | |||
a06e86ef96 | |||
be8bec2c4e | |||
e67ee6426f | |||
ee123f4e38 | |||
915bac0b47 | |||
d9e3464141 | |||
1a64061f27 | |||
8c2451162b | |||
f9a6104964 | |||
71f5c2e463 | |||
c9b1d739e8 | |||
7ec9b7650d | |||
a67e3cd2dc | |||
e5ff3e7068 | |||
4a0f0d870b | |||
f9829abee2 | |||
2f7761d6eb | |||
782438c81b | |||
8c84a4402e | |||
64b5b2fa49 | |||
4dcb289339 | |||
9efb5f0ffb | |||
c370180773 | |||
6f71461a12 | |||
31b0b76716 | |||
9e41e03be2 | |||
4d9627294f | |||
91992fcf03 | |||
03f5b5cf3b | |||
b4779fe234 | |||
dc756141a9 | |||
cc579301b8 | |||
e1a4dbde54 | |||
9dfab5f145 | |||
3f50b341ab | |||
dc1ed5aac4 | |||
1e8e574aff | |||
59250db289 | |||
73a6f0862a | |||
6536a90a80 | |||
ddeb75f16e | |||
fedcdeb1f8 | |||
f496c64d58 | |||
6717019863 | |||
f2503b5cf1 | |||
92c08f75e1 | |||
d5c72f4420 | |||
c20a78605d | |||
8f950a7821 | |||
632589fcbc | |||
325e153101 | |||
0c51ea8b76 | |||
bb6c77004f | |||
20d8e87d9f | |||
4f6b779f74 | |||
17fbdf95ef | |||
2faa05c3b9 | |||
075f87ed01 | |||
b0fd020d6f | |||
a3afe66b5d | |||
e2136514b5 |
9
.devcontainer/Dockerfile
Normal file
9
.devcontainer/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/debian/.devcontainer/base.Dockerfile
|
||||||
|
|
||||||
|
# [Choice] Debian version (use bullseye on local arm64/Apple Silicon): bullseye, buster
|
||||||
|
ARG VARIANT="buster"
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
|
||||||
|
|
||||||
|
# ** [Optional] Uncomment this section to install additional packages. **
|
||||||
|
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
66
.devcontainer/devcontainer.json
Normal file
66
.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/ubuntu
|
||||||
|
{
|
||||||
|
"name": "beteran-common-rust",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"args": {
|
||||||
|
// Use the VARIANT arg to pick a Debian OS version: buster, bullseye
|
||||||
|
// Use bullseye when on local on arm64/Apple Silicon.
|
||||||
|
"VARIANT": "bullseye"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runArgs": [
|
||||||
|
"--cap-add=SYS_PTRACE",
|
||||||
|
"--security-opt",
|
||||||
|
"seccomp=unconfined"
|
||||||
|
],
|
||||||
|
// Use this environment variable if you need to bind mount your local source code into a new container.
|
||||||
|
"remoteEnv": {
|
||||||
|
"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
|
||||||
|
},
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
"customizations": {
|
||||||
|
// Configure properties specific to VS Code.
|
||||||
|
"vscode": {
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
"lldb.verboseLogging": true,
|
||||||
|
"lldb.executable": "/usr/bin/lldb",
|
||||||
|
// VS Code don't watch files under ./target
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/.git/objects/**": true,
|
||||||
|
"**/.git/subtree-cache/**": true,
|
||||||
|
"**/target/**": true
|
||||||
|
},
|
||||||
|
"rust-analyzer.checkOnSave.command": "clippy",
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"donjayamanne.githistory",
|
||||||
|
"eamodio.gitlens",
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"ms-azuretools.vscode-docker",
|
||||||
|
"mutantdino.resourcemonitor",
|
||||||
|
"rust-lang.rust-analyzer",
|
||||||
|
"serayuzgur.crates",
|
||||||
|
"tamasfe.even-better-toml",
|
||||||
|
"vadimcn.vscode-lldb"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
// "postCreateCommand": "uname -a",
|
||||||
|
"postCreateCommand": "bash ./.devcontainer/scripts/postCreateCommand.sh",
|
||||||
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
|
"remoteUser": "vscode",
|
||||||
|
"features": {
|
||||||
|
"git": "latest",
|
||||||
|
"rust": "latest"
|
||||||
|
}
|
||||||
|
}
|
5
.devcontainer/rust-toolchain.toml
Normal file
5
.devcontainer/rust-toolchain.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "stable"
|
||||||
|
profile = "minimal"
|
||||||
|
components = ["clippy", "rustfmt"]
|
||||||
|
targets = []
|
4
.devcontainer/scripts/postCreateCommand.sh
Normal file
4
.devcontainer/scripts/postCreateCommand.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
75
.rustfmt.toml
Normal file
75
.rustfmt.toml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=
|
||||||
|
array_width = 60
|
||||||
|
attr_fn_like_width = 70
|
||||||
|
binop_separator = "Front" # "Front", "Back"
|
||||||
|
blank_lines_lower_bound = 0
|
||||||
|
blank_lines_upper_bound = 1
|
||||||
|
brace_style = "SameLineWhere" #"AlwaysNextLine", "PreferSameLine", "SameLineWhere"
|
||||||
|
chain_width = 60
|
||||||
|
color = "Auto" #"Auto", "Always", "Never"
|
||||||
|
combine_control_expr = true # true, false
|
||||||
|
comment_width = 80
|
||||||
|
condense_wildcard_suffixes = false # true, false
|
||||||
|
control_brace_style = "AlwaysSameLine" # "AlwaysNextLine", "AlwaysSameLine", "ClosingNextLine"
|
||||||
|
disable_all_formatting = false # true, false
|
||||||
|
edition = "2015" # "2015", "2018", "2021"
|
||||||
|
empty_item_single_line = true # true, false
|
||||||
|
enum_discrim_align_threshold = 0
|
||||||
|
error_on_line_overflow = false # true, false
|
||||||
|
error_on_unformatted = false # true, false
|
||||||
|
fn_args_layout = "Tall" # "Compressed", "Tall", "Vertical"
|
||||||
|
fn_call_width = 60
|
||||||
|
fn_single_line = false # true, false
|
||||||
|
force_explicit_abi = true # true, false
|
||||||
|
force_multiline_blocks = false # true, false
|
||||||
|
format_code_in_doc_comments = false # true, false
|
||||||
|
format_generated_files = false # true, false
|
||||||
|
format_macro_matchers = false # true, false
|
||||||
|
format_macro_bodies = true # true, false
|
||||||
|
format_strings = false # true, false
|
||||||
|
group_imports = "Preserve" # "Preserve", "StdExternalCrate"
|
||||||
|
hard_tabs = false # true, false
|
||||||
|
hex_literal_case = "Preserve" # "Upper", "Lower"
|
||||||
|
hide_parse_errors = false # true, false
|
||||||
|
ignore = []
|
||||||
|
imports_indent = "Block" # "Block", "Visual"
|
||||||
|
imports_layout = "Mixed" # "Horizontal", "HorizontalVertical", "Mixed", "Vertical"
|
||||||
|
indent_style = "Block" # "Block", "Visual"
|
||||||
|
inline_attribute_width = 0
|
||||||
|
license_template_path = ""
|
||||||
|
match_arm_blocks = true # true, false
|
||||||
|
match_arm_leading_pipes = "Never" # "Always", "Never", "Preserve"
|
||||||
|
match_block_trailing_comma = false # true, false
|
||||||
|
max_width = 100
|
||||||
|
merge_derives = true # true, false
|
||||||
|
imports_granularity = "Preserve" # "Preserve", "Crate", "Module", "Item", "One"
|
||||||
|
merge_imports = false # true, false
|
||||||
|
newline_style = "Auto" # "Auto", "Native", "Unix", "Windows"
|
||||||
|
normalize_comments = false # true, false
|
||||||
|
normalize_doc_attributes = false # true, false
|
||||||
|
overflow_delimited_expr = false # true, false
|
||||||
|
remove_nested_parens = true # true, false
|
||||||
|
reorder_impl_items = false # true, false
|
||||||
|
reorder_imports = true # true, false
|
||||||
|
reorder_modules = true # true, false
|
||||||
|
report_fixme = "Never" # "Always", "Unnumbered", "Never"
|
||||||
|
report_todo = "Never" # "Always", "Unnumbered", "Never"
|
||||||
|
skip_children = false # true, false
|
||||||
|
single_line_if_else_max_width = 50
|
||||||
|
space_after_colon = true # true, false
|
||||||
|
space_before_colon = false # true, false
|
||||||
|
spaces_around_ranges = false # true, false
|
||||||
|
struct_field_align_threshold = 0
|
||||||
|
struct_lit_single_line = true # true, false
|
||||||
|
struct_lit_width = 18
|
||||||
|
struct_variant_width = 35
|
||||||
|
tab_spaces = 2
|
||||||
|
trailing_comma = "Vertical" # "Always", "Never", "Vertical"
|
||||||
|
trailing_semicolon = true # true, false
|
||||||
|
type_punctuation_density = "Wide" # "Compressed", "Wide"
|
||||||
|
unstable_features = false # true, false
|
||||||
|
use_field_init_shorthand = false # true, false
|
||||||
|
use_small_heuristics = "Default" # "Default", "Off", "Max"
|
||||||
|
use_try_shorthand = false # true, false
|
||||||
|
where_single_line = false # true, false
|
||||||
|
wrap_comments = false # true, false
|
23
Cargo.toml
Normal file
23
Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
name = "beteran-common-rust"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[lib]
|
||||||
|
name = "beteran_common_rust"
|
||||||
|
path = "./src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = { version = "0" }
|
||||||
|
jsonwebtoken = { version = "8" }
|
||||||
|
lazy_static = { version = "1" }
|
||||||
|
prost = { version = "0" }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = { version = "1" }
|
||||||
|
|
||||||
|
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.99-snapshot" }
|
||||||
|
|
||||||
|
|
||||||
|
[build-dependencies]
|
27
resources/private.pem
Normal file
27
resources/private.pem
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAw/GvSFLy8K5uT79REy5lJtIS+Y9uAP1SJEyLvAqWfdPh9YO5
|
||||||
|
QCnYPp1uCqL3xWozkhrQWUbaYkO+65vjmYcGBMlzO+7KvZcHh4wr8ybA03M6Yy6J
|
||||||
|
SbnXRQvVm2Bvp2Z1B0dkT11CtZxiaNywYFvMhh5+zEbsrbFkzN5zI+hNpyg4uaaQ
|
||||||
|
Y5Oy2jGW3zuOIy/i0qzs3pCHWDAk0d5hpGvflUIj7BOQtl7CcFoB8tMp6F2fi8t9
|
||||||
|
m/Qa0yvQz8CNf7pdDqprUlm509wKzB4HgX8aG5SMwMlfuQjvT3jQNLRnHJFDghdZ
|
||||||
|
uCaop8IKf4PVGjuLo0SEebYzVEYfzLQrHemoRwIDAQABAoIBAA7y+XSDH5XNOQ1M
|
||||||
|
g1r7RyxXCquPjcz1hrbOQDrwc9rVt3+LtS54As+EI0kcddrR521WLl8hULf+gypm
|
||||||
|
kk68RnFHDUudREqCo0hsIU5DvqJjQCkg+8hsLUhPRtS73sjewD7162lCrDw+2iM1
|
||||||
|
8x7m4gu5d+MN5jC6P/6BWjd7GbGO9Yvnz1avKLwwNgLoivZn1S88FAXE8wEgAG4j
|
||||||
|
evlHX6BaAaOkMyocaB67nNWyZQi/+prxRtdYdCqTV2wyrDVVFgh/1P70nijVUU5X
|
||||||
|
UKQFZWOOmaRLiy5iL36XgMtnToTPMboF+MZuRbmQfxgifYFxqObuX+8cleylPilh
|
||||||
|
MgayeUECgYEA/5CPPzlhaHEehXPnG/UvXPHWuuWFMwNWkKl2yNnBFA/0uB46bKXp
|
||||||
|
kgVrA6Yhu0IbyXZGc6YL4QDNGgiRvEBQ4JTrd1McSMr/iCesdjxQcoq12Z97yX0r
|
||||||
|
iriyL7siwMaoMKwD5N2WqovTlFBB+p/tDwDnLKeTxUXbaQ55k/HZ17sCgYEAxEcg
|
||||||
|
kl5K5Xo6r8ZVyKi9Kiz1KHUacevWocUUzPoPgqBAnx/g/AKNpqGg/JgZVK8C/uT8
|
||||||
|
9du6lJkNGezCQKic7GuE6wxDu7Zajr43dNZH+kGc5cWyYBFmt7KuFQ/jD804nGZF
|
||||||
|
SM0YLTixzqA5yEEBXKe5+INCh8xPIH2LhFYFKuUCgYAgzZFVcCwMl9hvEL1tXT9D
|
||||||
|
EteZDbTXI2qNDvNsPGcICDRFHbwqDfG5CHD/+ucBfi7K4R+R4JJNwyiQWuE55Jd8
|
||||||
|
/CBtJIHQ5h1+gHkmg/9fdGZ7FHlzF1nraGGWttJzJAyakrm9OqQIKAJ0Wwjc/oIT
|
||||||
|
Fu6VUL0q6RiMl4sLblOj2QKBgFzFQZ/s8XmFTDfIhsNQ/hfxJ+73aoht8ASGIk6/
|
||||||
|
4pTbKbAMYUq76jfYLT82pMJh9giEMwwBzy5tKMQYI7hr+b/FEg4Gvfz7M9JEFfIj
|
||||||
|
VeHzITV5O9YsY2BwE9fgqnHNjfReYmEGj2bQZTpEgQslrn8cx8muQMPuzXeN32Ot
|
||||||
|
RMQBAoGAeV9lVry9F5gB8rlOBlbPOz8wldx5hjs5TvwLnZVdyfwsjmAKEKKNTdma
|
||||||
|
AxH8Zkz0U/EMOzbmlc0hRSzwtM4ApH3E4TiQctyCAGxS9OY/AeW6TU0o+H2cyktR
|
||||||
|
LJkeETFJfaqynSBfSY2qX2YzsG5tlc8oITf8QKwKQ9WbrTHLQjs=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
9
resources/public.pem
Normal file
9
resources/public.pem
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw/GvSFLy8K5uT79REy5l
|
||||||
|
JtIS+Y9uAP1SJEyLvAqWfdPh9YO5QCnYPp1uCqL3xWozkhrQWUbaYkO+65vjmYcG
|
||||||
|
BMlzO+7KvZcHh4wr8ybA03M6Yy6JSbnXRQvVm2Bvp2Z1B0dkT11CtZxiaNywYFvM
|
||||||
|
hh5+zEbsrbFkzN5zI+hNpyg4uaaQY5Oy2jGW3zuOIy/i0qzs3pCHWDAk0d5hpGvf
|
||||||
|
lUIj7BOQtl7CcFoB8tMp6F2fi8t9m/Qa0yvQz8CNf7pdDqprUlm509wKzB4HgX8a
|
||||||
|
G5SMwMlfuQjvT3jQNLRnHJFDghdZuCaop8IKf4PVGjuLo0SEebYzVEYfzLQrHemo
|
||||||
|
RwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
1
src/error/mod.rs
Normal file
1
src/error/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod rpc;
|
371
src/error/rpc.rs
Normal file
371
src/error/rpc.rs
Normal file
|
@ -0,0 +1,371 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
use prost::Message;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Parse {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Parse {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "parse error: {}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct InvalidRequest {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InvalidRequest {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "invalid request error: {}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum InvalidParamsType {
|
||||||
|
None,
|
||||||
|
DateTime,
|
||||||
|
Decimal,
|
||||||
|
EqualsTo,
|
||||||
|
Float,
|
||||||
|
Integer,
|
||||||
|
Range,
|
||||||
|
RegEx,
|
||||||
|
Required,
|
||||||
|
StringLength,
|
||||||
|
Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InvalidParamsType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
InvalidParamsType::None => {
|
||||||
|
write!(f, "None")
|
||||||
|
}
|
||||||
|
InvalidParamsType::DateTime => {
|
||||||
|
write!(f, "DateTime error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Decimal => {
|
||||||
|
write!(f, "Decimal error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::EqualsTo => {
|
||||||
|
write!(f, "EqualsTo error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Float => {
|
||||||
|
write!(f, "Float error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Integer => {
|
||||||
|
write!(f, "Integer error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Range => {
|
||||||
|
write!(f, "Range error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::RegEx => {
|
||||||
|
write!(f, "RegEx error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Required => {
|
||||||
|
write!(f, "Required error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::StringLength => {
|
||||||
|
write!(f, "String Length error")
|
||||||
|
}
|
||||||
|
InvalidParamsType::Url => {
|
||||||
|
write!(f, "Url error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InvalidParamsType> for bpr::protobuf::rpc::InvalidParamsType {
|
||||||
|
fn from(t: InvalidParamsType) -> Self {
|
||||||
|
match t {
|
||||||
|
InvalidParamsType::None => bpr::protobuf::rpc::InvalidParamsType::None,
|
||||||
|
InvalidParamsType::DateTime => bpr::protobuf::rpc::InvalidParamsType::DateTime,
|
||||||
|
InvalidParamsType::Decimal => bpr::protobuf::rpc::InvalidParamsType::Decimal,
|
||||||
|
InvalidParamsType::EqualsTo => bpr::protobuf::rpc::InvalidParamsType::EqualsTo,
|
||||||
|
InvalidParamsType::Float => bpr::protobuf::rpc::InvalidParamsType::Float,
|
||||||
|
InvalidParamsType::Integer => bpr::protobuf::rpc::InvalidParamsType::Integer,
|
||||||
|
InvalidParamsType::Range => bpr::protobuf::rpc::InvalidParamsType::Range,
|
||||||
|
InvalidParamsType::RegEx => bpr::protobuf::rpc::InvalidParamsType::RegEx,
|
||||||
|
InvalidParamsType::Required => bpr::protobuf::rpc::InvalidParamsType::Required,
|
||||||
|
InvalidParamsType::StringLength => bpr::protobuf::rpc::InvalidParamsType::StringLength,
|
||||||
|
InvalidParamsType::Url => bpr::protobuf::rpc::InvalidParamsType::Url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bpr::protobuf::rpc::InvalidParamsType> for InvalidParamsType {
|
||||||
|
fn from(t: bpr::protobuf::rpc::InvalidParamsType) -> Self {
|
||||||
|
match t {
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::None => InvalidParamsType::None,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::DateTime => InvalidParamsType::DateTime,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Decimal => InvalidParamsType::Decimal,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::EqualsTo => InvalidParamsType::EqualsTo,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Float => InvalidParamsType::Float,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Integer => InvalidParamsType::Integer,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Range => InvalidParamsType::Range,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::RegEx => InvalidParamsType::RegEx,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Required => InvalidParamsType::Required,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::StringLength => InvalidParamsType::StringLength,
|
||||||
|
bpr::protobuf::rpc::InvalidParamsType::Url => InvalidParamsType::Url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InvalidParamsType> for i32 {
|
||||||
|
fn from(s: InvalidParamsType) -> Self {
|
||||||
|
match s {
|
||||||
|
InvalidParamsType::DateTime => InvalidParamsType::DateTime as i32,
|
||||||
|
InvalidParamsType::Decimal => InvalidParamsType::Decimal as i32,
|
||||||
|
InvalidParamsType::EqualsTo => InvalidParamsType::EqualsTo as i32,
|
||||||
|
InvalidParamsType::Float => InvalidParamsType::Float as i32,
|
||||||
|
InvalidParamsType::Integer => InvalidParamsType::Integer as i32,
|
||||||
|
InvalidParamsType::Range => InvalidParamsType::Range as i32,
|
||||||
|
InvalidParamsType::RegEx => InvalidParamsType::RegEx as i32,
|
||||||
|
InvalidParamsType::Required => InvalidParamsType::Required as i32,
|
||||||
|
InvalidParamsType::StringLength => InvalidParamsType::StringLength as i32,
|
||||||
|
InvalidParamsType::Url => InvalidParamsType::Url as i32,
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct InvalidParamsDetail {
|
||||||
|
pub location: String,
|
||||||
|
pub param: String,
|
||||||
|
pub value: String,
|
||||||
|
pub error_type: InvalidParamsType,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InvalidParamsDetail {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Invalid Params Detail error, location: {}, param: {}, value: {}, error_type: {}, message: {}", self.location, self.param, self.value, self.error_type, self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&InvalidParamsDetail> for bpr::protobuf::rpc::InvalidParamsDetail {
|
||||||
|
fn from(d: &InvalidParamsDetail) -> Self {
|
||||||
|
bpr::protobuf::rpc::InvalidParamsDetail {
|
||||||
|
location: d.location.clone(),
|
||||||
|
param: d.param.clone(),
|
||||||
|
value: d.value.clone(),
|
||||||
|
error_type: d.error_type as i32,
|
||||||
|
message: d.message.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct InvalidParams {
|
||||||
|
pub message: String,
|
||||||
|
pub detail: InvalidParamsDetail,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InvalidParams {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Invalid Params error, message: {}, detail: {:?}",
|
||||||
|
self.message, self.detail
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Internal {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Internal {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Internal error, message: {}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Server {
|
||||||
|
pub code: i32,
|
||||||
|
pub message: String,
|
||||||
|
pub data: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Server {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Server error, message: {}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum Error {
|
||||||
|
///
|
||||||
|
Parse(Parse),
|
||||||
|
///
|
||||||
|
InvalidRequest(InvalidRequest),
|
||||||
|
///
|
||||||
|
InvalidParams(InvalidParams),
|
||||||
|
///
|
||||||
|
Internal(Internal),
|
||||||
|
///
|
||||||
|
Server(Server),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::Parse(e) => {
|
||||||
|
write!(f, "Parse error: {}", e)
|
||||||
|
}
|
||||||
|
Error::InvalidRequest(e) => {
|
||||||
|
write!(f, "InvalidRequest error: {}", e)
|
||||||
|
}
|
||||||
|
Error::InvalidParams(e) => {
|
||||||
|
write!(f, "InvalidParams error: {}", e)
|
||||||
|
}
|
||||||
|
Error::Internal(e) => {
|
||||||
|
write!(f, "Internal error: {}", e)
|
||||||
|
}
|
||||||
|
Error::Server(e) => {
|
||||||
|
write!(f, "Server error: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for bpr::protobuf::rpc::Error {
|
||||||
|
fn from(err: Error) -> Self {
|
||||||
|
match err {
|
||||||
|
Error::Parse(e) => bpr::protobuf::rpc::Error {
|
||||||
|
code: bpr::protobuf::rpc::Error::PARSE,
|
||||||
|
message: e.message,
|
||||||
|
data: None,
|
||||||
|
},
|
||||||
|
Error::InvalidRequest(e) => bpr::protobuf::rpc::Error {
|
||||||
|
code: bpr::protobuf::rpc::Error::INVALID_REQUEST,
|
||||||
|
message: e.message,
|
||||||
|
data: None,
|
||||||
|
},
|
||||||
|
Error::InvalidParams(e) => bpr::protobuf::rpc::Error {
|
||||||
|
code: bpr::protobuf::rpc::Error::INVALID_PARAMS,
|
||||||
|
message: e.message.clone(),
|
||||||
|
data: Some(bpr::protobuf::rpc::InvalidParamsDetail::from(&e.detail).encode_to_vec()),
|
||||||
|
},
|
||||||
|
Error::Internal(e) => bpr::protobuf::rpc::Error {
|
||||||
|
code: bpr::protobuf::rpc::Error::INTERNAL,
|
||||||
|
message: e.message,
|
||||||
|
data: None,
|
||||||
|
},
|
||||||
|
Error::Server(e) => bpr::protobuf::rpc::Error {
|
||||||
|
code: e.code,
|
||||||
|
message: e.message,
|
||||||
|
data: e.data,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. header parsing (-32700)
|
||||||
|
// "message": "header could not be resolved.",
|
||||||
|
// "detail": [
|
||||||
|
// {
|
||||||
|
// "location": "header",
|
||||||
|
// "msg": "must be String"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// 2. data from header (-32700)
|
||||||
|
// "message": "'client'(header) must be String, input 'name': 123",
|
||||||
|
// "detail": [
|
||||||
|
// {
|
||||||
|
// "location": "header",
|
||||||
|
// "param": "client",
|
||||||
|
// "value": 123,
|
||||||
|
// "error": "TypeError",
|
||||||
|
// "msg": "must be String"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// 3. request parsing (-32600)
|
||||||
|
// "message": "request could not be resolved.",
|
||||||
|
// "detail": [
|
||||||
|
// {
|
||||||
|
// "location": "request",
|
||||||
|
// "msg": "must be String"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// 4. data from request (-32602)
|
||||||
|
// "message": "'client'(request) must be String, input 'name': 123",
|
||||||
|
// "detail": [
|
||||||
|
// {
|
||||||
|
// "location": "request",
|
||||||
|
// "param": "client",
|
||||||
|
// "value": 123,
|
||||||
|
// "error": "TypeError",
|
||||||
|
// "msg": "must be String"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// 5. crud (-32603)
|
||||||
|
// "message": "Internal error",
|
||||||
|
|
||||||
|
// 6. return
|
||||||
|
|
||||||
|
// -32700
|
||||||
|
// Parse error Invalid JSON was received by the server.
|
||||||
|
// An error occurred on the server while parsing the JSON text.
|
||||||
|
// -32600
|
||||||
|
// Invalid Request The JSON sent is not a valid Request object.
|
||||||
|
// -32601
|
||||||
|
// Method not found The method does not exist / is not available.
|
||||||
|
// -32602
|
||||||
|
// Invalid params Invalid method parameter(s).
|
||||||
|
// -32603
|
||||||
|
// Internal error Internal JSON-RPC error.
|
||||||
|
// -32000 to -32099
|
||||||
|
// Server error Reserved for implementation-defined server-errors.
|
||||||
|
|
||||||
|
// 400 Bad Request
|
||||||
|
// 클라이언트의 요청이 유효하지 않아 더 이상 작업을 진행하지 않는 경우 (필수 여부, 유효 여부, 범위, 패턴 ...)
|
||||||
|
// "message": "'name'(body) must be String, input 'name': 123",
|
||||||
|
// "detail": [
|
||||||
|
// {
|
||||||
|
// "location": "body",
|
||||||
|
// "param": "name",
|
||||||
|
// "value": 123,
|
||||||
|
// "error": "TypeError",
|
||||||
|
// "msg": "must be String"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// 401 Unauthorized
|
||||||
|
// 클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우
|
||||||
|
|
||||||
|
// 403 Forbidden
|
||||||
|
// 클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우
|
||||||
|
|
||||||
|
// 404 Not Found
|
||||||
|
// 클라이언트가 요청한 자원이 존재하지 않다.
|
||||||
|
|
||||||
|
// 409 Conflict
|
||||||
|
// 클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우
|
||||||
|
|
||||||
|
// 429 Too Many Requests
|
||||||
|
// 클라이언트가 일정 시간 동안 너무 많은 요청을 보낸 경우
|
||||||
|
|
||||||
|
// 500 Internal Server Error
|
||||||
|
|
||||||
|
// 501 Not Implemented
|
||||||
|
// 503 Service Unavailable
|
76
src/jwt/mod.rs
Normal file
76
src/jwt/mod.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ENCODING_KEY: jsonwebtoken::EncodingKey =
|
||||||
|
jsonwebtoken::EncodingKey::from_rsa_pem(include_bytes!("../../resources/private.pem"))
|
||||||
|
.expect("ENCODING_KEY");
|
||||||
|
static ref DECODING_KEY: jsonwebtoken::DecodingKey =
|
||||||
|
jsonwebtoken::DecodingKey::from_rsa_pem(include_bytes!("../../resources/public.pem"))
|
||||||
|
.expect("DECODING_KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
Encoding(String),
|
||||||
|
Decoding(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::Encoding(e) => write!(f, "Encoding Error: {}", e),
|
||||||
|
Error::Decoding(e) => write!(f, "Decoding Error: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[derive(Debug, Serialize, Deserialize)]
|
||||||
|
// struct Claims {
|
||||||
|
// aud: String, // Optional. Audience
|
||||||
|
// exp: usize, // Required (validate_exp defaults to true in validation). Expiration time (as UTC timestamp)
|
||||||
|
// iat: usize, // Optional. Issued at (as UTC timestamp)
|
||||||
|
// iss: String, // Optional. Issuer
|
||||||
|
// nbf: usize, // Optional. Not Before (as UTC timestamp)
|
||||||
|
// sub: String, // Optional. Subject (whom token refers to)
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Claims {
|
||||||
|
pub iss: String,
|
||||||
|
pub iat: i64,
|
||||||
|
pub exp: i64,
|
||||||
|
pub session_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(issuer: &str, session_id: &str) -> Result<String, Error> {
|
||||||
|
use jsonwebtoken::{encode, Algorithm, Header};
|
||||||
|
|
||||||
|
let header = Header::new(Algorithm::RS256);
|
||||||
|
|
||||||
|
let issued_at = (chrono::Utc::now()).timestamp();
|
||||||
|
let expiration_at = (chrono::Utc::now() + chrono::Duration::days(1)).timestamp();
|
||||||
|
|
||||||
|
let claims = Claims {
|
||||||
|
iss: issuer.to_string(),
|
||||||
|
iat: issued_at,
|
||||||
|
exp: expiration_at,
|
||||||
|
session_id: session_id.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let token =
|
||||||
|
encode(&header, &claims, &ENCODING_KEY).map_err(|e| Error::Encoding(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode(token: &str) -> Result<Claims, Error> {
|
||||||
|
use jsonwebtoken::{decode, Algorithm, Validation};
|
||||||
|
|
||||||
|
let token_data = decode::<Claims>(token, &DECODING_KEY, &Validation::new(Algorithm::RS256))
|
||||||
|
.map_err(|e| Error::Decoding(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(token_data.claims)
|
||||||
|
}
|
6
src/lib.rs
Normal file
6
src/lib.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
|
pub mod jwt;
|
||||||
|
pub mod pagination;
|
62
src/pagination/mod.rs
Normal file
62
src/pagination/mod.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Sort {
|
||||||
|
///
|
||||||
|
ASC(String),
|
||||||
|
///
|
||||||
|
DESC(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Sort> for bpr::protobuf::pagination::Sort {
|
||||||
|
fn from(d: &Sort) -> Self {
|
||||||
|
match d {
|
||||||
|
Sort::ASC(by) => bpr::protobuf::pagination::Sort {
|
||||||
|
by: by.to_string(),
|
||||||
|
order: bpr::protobuf::pagination::SortOrder::Asc as i32,
|
||||||
|
},
|
||||||
|
Sort::DESC(by) => bpr::protobuf::pagination::Sort {
|
||||||
|
by: by.to_string(),
|
||||||
|
order: bpr::protobuf::pagination::SortOrder::Desc as i32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&bpr::protobuf::pagination::Sort> for Sort {
|
||||||
|
fn from(d: &bpr::protobuf::pagination::Sort) -> Self {
|
||||||
|
match d.order {
|
||||||
|
x if x == bpr::protobuf::pagination::SortOrder::Desc as i32 => Sort::DESC(d.by.to_string()),
|
||||||
|
_ => Sort::ASC(d.by.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Pagination {
|
||||||
|
///
|
||||||
|
pub page: Option<u32>,
|
||||||
|
///
|
||||||
|
pub page_size: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Pagination> for bpr::protobuf::pagination::Pagination {
|
||||||
|
fn from(d: &Pagination) -> Self {
|
||||||
|
bpr::protobuf::pagination::Pagination {
|
||||||
|
page: d.page,
|
||||||
|
page_size: d.page_size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&bpr::protobuf::pagination::Pagination> for Pagination {
|
||||||
|
fn from(d: &bpr::protobuf::pagination::Pagination) -> Self {
|
||||||
|
Pagination {
|
||||||
|
page: d.page,
|
||||||
|
page_size: d.page_size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user