diff --git a/oab/Cargo.lock b/oab/Cargo.lock index 18d97ad..147bca7 100644 --- a/oab/Cargo.lock +++ b/oab/Cargo.lock @@ -2,6 +2,191 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix-codec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "log", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-http" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f9ffb6db08c1c3a1f4aef540f1a63193adc73c4fbd40b75a95fc8c5258f6e51" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1 0.10.1", + "smallvec", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb60846b52c118f2f04a56cc90880a274271c489b2498623d58176f8ca21fa80" +dependencies = [ + "bytestring", + "firestorm", + "http", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "num_cpus", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27e8fe9ba4ae613c21f677c2cfaf0696c3744030c6f485b34634e502d6bb379" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time 0.3.9", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f270541caec49c15673b0af0e9a00143421ad4f118d2df7edcb68b627632f56" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -13,6 +198,30 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -137,6 +346,27 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.9.1" @@ -161,11 +391,23 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "bytestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b6a75fd3048808ef06af5cd79712be8111960adaf89d90250974b38fc3928a" +dependencies = [ + "bytes", +] + [[package]] name = "cc" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -238,6 +480,23 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" +dependencies = [ + "percent-encoding", + "time 0.3.9", + "version_check", +] + [[package]] name = "cpufeatures" version = "0.2.2" @@ -262,6 +521,15 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-queue" version = "0.3.5" @@ -323,6 +591,19 @@ dependencies = [ "pem-rfc7468", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + [[package]] name = "digest" version = "0.8.1" @@ -357,6 +638,15 @@ dependencies = [ "serde", ] +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + [[package]] name = "event-listener" version = "2.5.2" @@ -369,6 +659,28 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "firestorm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c5f6c2c942da57e2aaaa84b8a521489486f14e75e7fa91dab70aba913975f98" + +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -509,6 +821,25 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "h2" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -562,6 +893,29 @@ dependencies = [ "thiserror", ] +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + [[package]] name = "idna" version = "0.2.3" @@ -635,6 +989,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.57" @@ -644,6 +1007,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.4.0" @@ -671,6 +1040,24 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "local-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + [[package]] name = "lock_api" version = "0.4.7" @@ -708,12 +1095,27 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.3" @@ -818,6 +1220,7 @@ dependencies = [ name = "oab" version = "0.1.0" dependencies = [ + "actix-web", "clap", "include_dir", "lazy_static", @@ -826,6 +1229,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "thiserror", "time 0.3.9", "tokio", "tracing", @@ -1192,6 +1596,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + [[package]] name = "ring" version = "0.16.20" @@ -1244,7 +1665,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.12", ] [[package]] @@ -1291,6 +1721,12 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" + [[package]] name = "semver-parser" version = "0.7.0" @@ -1338,6 +1774,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_yaml" version = "0.8.24" @@ -1382,6 +1830,17 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "sha1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.3", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -1548,7 +2007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" dependencies = [ "discard", - "rustc_version", + "rustc_version 0.2.3", "stdweb-derive", "stdweb-internal-macros", "stdweb-internal-runtime", @@ -1580,7 +2039,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha1", + "sha1 0.6.1", "syn", ] @@ -1751,9 +2210,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.18.2" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" dependencies = [ "bytes", "libc", @@ -1802,6 +2261,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "tracing" version = "0.1.34" @@ -1809,6 +2282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2122,3 +2596,32 @@ name = "zeroize" version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.1+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +dependencies = [ + "cc", + "libc", +] diff --git a/oab/Cargo.toml b/oab/Cargo.toml index 2bd5860..647483b 100644 --- a/oab/Cargo.toml +++ b/oab/Cargo.toml @@ -16,8 +16,9 @@ time = { version = "0.3", features = ["formatting", "macros"] } tokio = { version = "1", features = ["full"] } tracing = "*" tracing-subscriber = "*" +thiserror = "1.0" rbson = "2" rbatis = { version = "*", default-features = false, features = ["runtime-tokio-rustls","mysql","debug_mode"] } - +actix-web = "4" diff --git a/oab/sql/table.sql b/oab/sql/table.sql new file mode 100644 index 0000000..9a6ea2f --- /dev/null +++ b/oab/sql/table.sql @@ -0,0 +1,147 @@ +/* + * table.sql + * Copyright (C) 2022 veypi + * + * Distributed under terms of the Apache license. + */ + +CREATE TABLE IF NOT EXISTS `user` +( + `id` varchar(32) NOT NULL DEFAULT '' COMMENT 'User UUID', + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `delete_flag` int(1) NOT NULL, + + `username` varchar(255) NOT NULL UNIQUE, + `nickname` varchar(255), + `email` varchar(255) UNIQUE, + `phone` varchar(255) UNIQUE, + `icon` varchar(255), + + `status` int NOT NULL COMMENT '状态(0:ok,1:disabled)', + `used` int, + `space` int DEFAULT 300, + + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `app` +( + `id` varchar(32) NOT NULL, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `delete_flag` int(1) NOT NULL, + + `name` varchar(255) NOT NULL, + `icon` varchar(255), + `des` varchar(255), + `user_count` int NOT NULL, + `hide` int(1) NOT NULL, + `regist` int(1) NOT NULL, + + `role_id` varchar(32), + `redirect` varchar(255), + `status` int NOT NULL COMMENT '状态(0:ok,1:disabled)', + + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `app_user` +( + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + `app_id` varchar(32) NOT NULL, + `user_id` varchar(32) NOT NULL, + `status` varchar(32) NOT NULL, + + PRIMARY KEY (`user_id`,`app_id`) USING BTREE, + FOREIGN KEY (`app_id`) REFERENCES `app`(`id`), + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='app_to_user'; + + + +CREATE TABLE IF NOT EXISTS `role` +( + `id` varchar(32) NOT NULL, + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `delete_flag` int(1) NOT NULL, + `app_id` varchar(32) NOT NULL, + + `name` varchar(255) NOT NULL, + `des` varchar(255), + `user_count` int NOT NULL, + + PRIMARY KEY (`id`) USING BTREE, + FOREIGN KEY (`app_id`) REFERENCES `app`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `user_role` +( + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + `user_id` varchar(32) NOT NULL, + `role_id` varchar(32) NOT NULL, + `status` varchar(32) NOT NULL, + + PRIMARY KEY (`user_id`,`role_id`) USING BTREE, + FOREIGN KEY (`role_id`) REFERENCES `role`(`id`), + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `resource` +( + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `delete_flag` int(1) NOT NULL, + + `app_id` varchar(32) NOT NULL, + `name` varchar(32) NOT NULL, + `des` varchar(255), + + + PRIMARY KEY (`app_id`,`name`) USING BTREE, + FOREIGN KEY (`app_id`) REFERENCES `app`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE IF NOT EXISTS `access` +( + `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `delete_flag` int(1) NOT NULL, + + `app_id` varchar(32) NOT NULL, + `name` varchar(32) NOT NULL, + + `role_id` varchar(32) NULL DEFAULT NULL, + `user_id` varchar(32) NULL DEFAULT NULL, + `rid` varchar(32) DEFAULT NULL COMMENT '资源子id', + `level` int DEFAULT 0, + + -- PRIMARY KEY (`app_id`,`name`, `role_id`, `user_id`) USING BTREE, + FOREIGN KEY (`role_id`) REFERENCES `role`(`id`), + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), + FOREIGN KEY (`app_id`,`name`) REFERENCES `resource`(`app_id`,`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `app` +ADD FOREIGN KEY (`role_id`) REFERENCES `role`(`id`); + +INSERT INTO `user` (`id`, `username`) +VALUES ('user0', 'name'); + +INSERT INTO `app` (`id`, `name`) +VALUES ('app0', 'a0'); + +INSERT INTO `resource` (`app_id`, `name`) +VALUES ('app0', 'sound'); + +INSERT INTO `role` (`id`, `app_id`) +VALUES ('role0', 'app0'); + +INSERT INTO `access` (`app_id`, `name`, `role_id`, `user_id`) +VALUES ('app0', 'sound', NULL, 'user0'); diff --git a/oab/src/api/mod.rs b/oab/src/api/mod.rs new file mode 100644 index 0000000..def96df --- /dev/null +++ b/oab/src/api/mod.rs @@ -0,0 +1,29 @@ +// +// mod.rs +// Copyright (C) 2022 veypi +// 2022-06-24 16:26 +// Distributed under terms of the Apache license. +// +// +use crate::{Error, Result}; +use actix_web::{get, web, Responder}; + +#[get("/hello/{name}")] +async fn greet(name: web::Path) -> Result { + let n = name.into_inner(); + if n > 0 { + Ok(format!("Hello {n}!")) + } else { + Err(Error::Unknown) + } +} + +#[get("/topic/derive")] +async fn hello() -> impl Responder { + "Hello World!" +} + +pub fn routes(cfg: &mut web::ServiceConfig) { + cfg.service(greet); + cfg.service(hello); +} diff --git a/oab/src/cfg/cfg.rs b/oab/src/cfg.rs similarity index 51% rename from oab/src/cfg/cfg.rs rename to oab/src/cfg.rs index e30a43f..f04d789 100644 --- a/oab/src/cfg/cfg.rs +++ b/oab/src/cfg.rs @@ -8,8 +8,13 @@ // // -use std::borrow::Borrow; +use std::{ + borrow::Borrow, + fs::File, + io::{self, Read}, +}; +use clap::{Args, Parser, Subcommand}; use lazy_static::lazy_static; use rbatis::rbatis::Rbatis; lazy_static! { @@ -17,6 +22,43 @@ lazy_static! { pub static ref DB:Rbatis=Rbatis::new(); } +lazy_static! { + pub static ref CLI: AppCli = AppCli::new(); +} + +lazy_static! { + pub static ref CONFIG: ApplicationConfig = ApplicationConfig::new(); +} + +#[derive(Debug, Parser)] +#[clap(name = "oab")] +#[clap(about = "oab", long_about = None)] +pub struct AppCli { + #[clap(short = 'c', value_name = "cfg",default_value_t = String::from("~/.config/oab/oab.yml"), value_hint = clap::ValueHint::DirPath)] + cfg: String, + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum Clis { + Init, + Web, + Stash(StashData), +} + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true)] +pub struct StashData { + command: Option, +} + +impl AppCli { + fn new() -> Self { + AppCli::parse() + } +} + #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ApplicationConfig { pub debug: bool, @@ -25,30 +67,51 @@ pub struct ApplicationConfig { pub db_user: String, pub db_pass: String, pub db_name: String, - pub log_dir: String, + pub log_dir: Option, /// "100MB" 日志分割尺寸-单位KB,MB,GB - pub log_temp_size: String, - pub log_pack_compress: String, - pub log_level: String, - pub jwt_secret: String, + pub log_temp_size: Option, + pub log_pack_compress: Option, + pub log_level: Option, + pub jwt_secret: Option, } impl ApplicationConfig { pub fn new() -> Self { - ApplicationConfig { + let mut f = match File::open(CLI.cfg.clone()) { + Ok(f) => f, + Err(ref e) if e.kind() == io::ErrorKind::NotFound => return Self::defaut(), + Err(e) => panic!("{}", e), + }; + File::open(CLI.cfg.clone()).unwrap(); + let mut yml_data = String::new(); + f.read_to_string(&mut yml_data).unwrap(); + //读取配置 + let result: ApplicationConfig = + serde_yaml::from_str(&yml_data).expect("load config file fail"); + if result.debug { + println!("load config:{:?}", result); + println!("///////////////////// Start On Debug Mode ////////////////////////////"); + } else { + println!("release_mode is enable!") + } + result + } + pub fn defaut() -> Self { + Self { debug: true, - server_url: "127.0.0.1:4000".to_string(), + server_url: "127.0.0.1:4001".to_string(), db_url: "127.0.0.1:3306".to_string(), db_user: "root".to_string(), - db_name: "test".to_string(), db_pass: "123456".to_string(), - log_dir: "".to_string(), - log_temp_size: "".to_string(), - log_pack_compress: "".to_string(), - log_level: "".to_string(), - jwt_secret: "".to_string(), + db_name: "test".to_string(), + log_dir: None, + log_temp_size: None, + log_pack_compress: None, + log_level: None, + jwt_secret: None, } } + pub fn save(&self) {} pub fn db(&self) -> &DB { DB.borrow() } @@ -61,23 +124,6 @@ impl ApplicationConfig { } } -///默认配置 -impl Default for ApplicationConfig { - fn default() -> Self { - let yml_data = include_str!("./mod.rs"); - //读取配置 - let result: ApplicationConfig = - serde_yaml::from_str(yml_data).expect("load config file fail"); - if result.debug { - println!("load config:{:?}", result); - println!("///////////////////// Start On Debug Mode ////////////////////////////"); - } else { - println!("release_mode is enable!") - } - result - } -} - struct FormatTime; impl tracing_subscriber::fmt::time::FormatTime for FormatTime { fn format_time(&self, w: &mut tracing_subscriber::fmt::format::Writer<'_>) -> std::fmt::Result { @@ -94,5 +140,8 @@ impl tracing_subscriber::fmt::time::FormatTime for FormatTime { } pub fn init_log() { - tracing_subscriber::fmt().with_timer(FormatTime {}).init(); + tracing_subscriber::fmt() + .with_line_number(true) + .with_timer(FormatTime {}) + .init(); } diff --git a/oab/src/cfg/mod.rs b/oab/src/cfg/mod.rs deleted file mode 100644 index 909b715..0000000 --- a/oab/src/cfg/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -// -// mod.rs -// Copyright (C) 2022 veypi -// 2022-05-29 18:39 -// Distributed under terms of the MIT license. -// -// - -mod cfg; -pub use cfg::init_log; -pub use cfg::ApplicationConfig; -pub use cfg::DB; diff --git a/oab/src/cli.rs b/oab/src/cli.rs new file mode 100644 index 0000000..26e66fd --- /dev/null +++ b/oab/src/cli.rs @@ -0,0 +1,56 @@ +// +// cli.rs +// Copyright (C) 2022 veypi +// 2022-07-08 18:39 +// Distributed under terms of the Apache license. +// + +use clap::{Args, Parser, Subcommand}; + +use lazy_static::lazy_static; + +lazy_static! { + pub static ref CLI: cli = cli::new(); +} + +#[derive(Debug, Parser)] +#[clap(name = "oab")] +#[clap(about = "oab", long_about = None)] +struct cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Debug, Subcommand)] +enum Commands { + /// Clones repos + #[clap(arg_required_else_help = true)] + Clone { + /// The remote to clone + #[clap(value_parser)] + remote: String, + }, + /// pushes things + #[clap(arg_required_else_help = true)] + Push { + /// The remote to target + #[clap(value_parser)] + remote: String, + }, + /// adds things + #[clap(arg_required_else_help = true)] + Add { + /// Stuff to add + #[clap(required = true, value_parser)] + path: Vec, + }, + Stash(Stash), + #[clap(external_subcommand)] + External(Vec), +} + +impl cli { + fn new() -> Self { + cli::parse() + } +} diff --git a/oab/src/lib.rs b/oab/src/lib.rs index cde27c6..8a33f34 100644 --- a/oab/src/lib.rs +++ b/oab/src/lib.rs @@ -5,5 +5,9 @@ // Distributed under terms of the MIT license. // -pub mod cfg; +pub mod api; +mod cfg; pub mod models; +mod result; +pub use cfg::{init_log, ApplicationConfig, Clis, CLI, CONFIG, DB}; +pub use result::{Error, Result}; diff --git a/oab/src/main.rs b/oab/src/main.rs index 0f9b45f..9c5811b 100644 --- a/oab/src/main.rs +++ b/oab/src/main.rs @@ -1,15 +1,42 @@ -use oab::{cfg, models}; -use tracing::{info, warn}; +// +// main.rs +// Copyright (C) 2022 veypi +// 2022-07-07 23:51 +// Distributed under terms of the Apache license. +// + +use actix_web::{middleware, web, App, HttpServer}; +use oab::{api, init_log, models, Clis, Result, CLI, CONFIG}; +use tracing::info; #[tokio::main] -async fn main() -> std::io::Result<()> { - let mut cf = cfg::ApplicationConfig::new(); - cfg::init_log(); - cf.log_dir = "".to_string(); - cf.connect().await; - info!("{}", cf.server_url); - warn!("{}", cf.db_url); - models::init().await; - println!("Hello, world!"); - return std::io::Result::Ok(()); +async fn main() -> Result<()> { + init_log(); + if let Some(c) = &CLI.command { + match c { + Clis::Init => { + CONFIG.connect().await; + models::init().await; + return Ok(()); + } + _ => {} + }; + }; + CONFIG.connect().await; + web().await?; + Ok(()) +} +async fn web() -> Result<()> { + std::env::set_var("RUST_LOG", "info"); + std::env::set_var("RUST_BACKTRACE", "1"); + let serv = HttpServer::new(move || { + let logger = middleware::Logger::default(); + let app = App::new(); + app.wrap(logger) + .wrap(middleware::Compress::default()) + .service(web::scope("api").configure(api::routes)) + }); + info!("listen to {}", CONFIG.server_url); + serv.bind(CONFIG.server_url.clone())?.run().await?; + Ok(()) } diff --git a/oab/src/models/app.rs b/oab/src/models/app.rs new file mode 100644 index 0000000..58bddff --- /dev/null +++ b/oab/src/models/app.rs @@ -0,0 +1,80 @@ +// +// app.rs +// Copyright (C) 2022 veypi +// 2022-07-09 00:18 +// Distributed under terms of the Apache license. +// + +use rbatis::{crud_table, DateTimeNative}; + +#[crud_table] +#[derive(Debug, Clone)] +pub struct App { + pub id: String, + pub created: Option, + pub updated: Option, + pub delete_flag: bool, + + pub name: Option, + pub des: Option, + pub icon: Option, + pub user_count: usize, + + pub hide: bool, + pub register: bool, + pub role_id: Option, + pub redirect: Option, + + pub status: usize, +} + +impl App { + pub fn new() -> Self { + Self { + id: rbatis::plugin::object_id::ObjectId::new().to_string(), + created: None, + updated: None, + delete_flag: false, + + name: None, + des: None, + icon: None, + user_count: 0, + hide: false, + register: false, + role_id: None, + redirect: None, + status: 0, + } + } +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)] +pub enum AUStatus { + OK, + Disabled, + Applying, + Deny, +} + +#[crud_table] +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)] +pub struct AppUser { + pub created: Option, + pub updated: Option, + pub app_id: String, + pub user_id: String, + pub status: AUStatus, +} + +impl AppUser { + pub fn new() -> Self { + Self { + created: None, + updated: None, + app_id: "".to_string(), + user_id: "".to_string(), + status: AUStatus::OK, + } + } +} diff --git a/oab/src/models/mod.rs b/oab/src/models/mod.rs index 763c334..1e5079a 100644 --- a/oab/src/models/mod.rs +++ b/oab/src/models/mod.rs @@ -5,16 +5,26 @@ // Distributed under terms of the MIT license. // +mod app; +mod role; mod user; -use rbatis::crud::CRUD; +use std::{fs::File, io::Read}; + use tracing::info; -use user::User; -use crate::cfg; +use crate::DB; +pub use app::{AUStatus, App, AppUser}; +pub use role::{Access, Resource, Role}; +pub use user::User; pub async fn init() { - let mut u = User::default(); - u.name = Some("asd".to_string()); - cfg::DB.save(&u, &[]).await.unwrap(); - info!("{:#?}", u); + info!("init database"); + let mut f = File::open("./sql/table.sql").unwrap(); + let mut sql = String::new(); + f.read_to_string(&mut sql).unwrap(); + DB.exec(&sql, vec![]).await.unwrap(); +} + +pub fn new_id() -> rbatis::object_id::ObjectId { + rbatis::plugin::object_id::ObjectId::new() } diff --git a/oab/src/models/role.rs b/oab/src/models/role.rs new file mode 100644 index 0000000..dbde2cf --- /dev/null +++ b/oab/src/models/role.rs @@ -0,0 +1,48 @@ +// +// role.rs +// Copyright (C) 2022 veypi +// 2022-07-09 02:42 +// Distributed under terms of the Apache license. +// +use rbatis::{crud_table, DateTimeNative}; + +#[crud_table] +#[derive(Debug, Clone, Default)] +pub struct Role { + pub id: String, + pub created: Option, + pub updated: Option, + pub delete_flag: bool, + + pub app_id: String, + pub name: Option, + pub des: Option, + pub user_count: usize, +} + +#[crud_table] +#[derive(Debug, Clone, Default)] +pub struct Resource { + pub created: Option, + pub updated: Option, + pub delete_flag: bool, + + pub app_id: String, + pub name: String, + pub des: Option, +} + +#[crud_table] +#[derive(Debug, Clone, Default)] +pub struct Access { + pub created: Option, + pub updated: Option, + pub delete_flag: bool, + + pub app_id: String, + pub name: String, + pub role_id: Option, + pub user_id: Option, + pub rid: Option, + pub level: usize, +} diff --git a/oab/src/models/user.rs b/oab/src/models/user.rs index 76a852c..5b8a371 100644 --- a/oab/src/models/user.rs +++ b/oab/src/models/user.rs @@ -6,20 +6,42 @@ // // -use rbatis::crud_table; +use rbatis::{crud_table, DateTimeNative}; #[crud_table] #[derive(Debug, Clone)] pub struct User { pub id: String, - pub name: Option, + pub created: Option, + pub updated: Option, + pub delete_flag: bool, + + pub username: Option, + pub nickname: Option, + pub email: Option, + pub phone: Option, + pub icon: Option, + pub status: usize, + pub used: usize, + pub space: usize, } impl Default for User { fn default() -> Self { - User { + Self { id: rbatis::plugin::object_id::ObjectId::new().to_string(), - name: None, + created: None, + updated: None, + delete_flag: false, + + username: None, + nickname: None, + email: None, + phone: None, + icon: None, + status: 0, + used: 0, + space: 300, } } } diff --git a/oab/src/result.rs b/oab/src/result.rs new file mode 100644 index 0000000..d9101a0 --- /dev/null +++ b/oab/src/result.rs @@ -0,0 +1,119 @@ +// +// result.rs +// Copyright (C) 2022 veypi +// 2022-06-24 18:57 +// Distributed under terms of the Apache license. +// + +use actix_web::{ + error, + http::{header::ContentType, StatusCode}, + HttpResponse, +}; +use serde::{Deserialize, Serialize}; +use thiserror::Error as ThisError; + +pub type Result = std::result::Result; +// pub type AsyncResult = std::result::Result>; + +#[derive(Clone, ThisError, Debug, Deserialize, Serialize)] +pub enum Error { + // system + // EnvVarError, + #[error("Parsing listening address failed")] + ParseListeningAddressFailed, + #[error("Data save failed")] + SledSaveFailed, + #[error("Database(1) error")] + SledDbError, + #[error("Database(2) error")] + SqliteDbError, + #[error("Deserialize / Serialize failed")] + SerdeError, + + #[error("Resource not found")] + NotFound, + + #[error("timeout")] + Timeout, + + #[error("bad request")] + BadRequest, + #[error("Method not allowed")] + MethodNotAllowed, + #[error("Internal server error")] + InternalServerError, + + // business + #[error("无效的 Session ID")] + InvalidSessionId, + #[error("invalid verify code")] + InvalidVerifyCode, + #[error("no access")] + NotAuthed, + #[error("login failed")] + LoginFailed, + #[error("Registration failed")] + RegisterFailed, + #[error("Already registered")] + AlreadyRegistered, + #[error("Saving post failed")] + SavePostFailed, + #[error("Can not find post you requested")] + CannotFoundPost, + #[error("Can not find tag you requested")] + CannotFoundTag, + #[error("Upload failed")] + UploadFailed, + #[error("Upload file not found")] + FileNotFound, + #[error("Unknown file type")] + UnknownFileType, + #[error("Unsupported file type {0}")] + UnsupportedFileType(String), + #[error("Creating thumbnail failed")] + CreateThumbnailFailed, + #[error("Reading post id data by tag failed")] + ReadPostIdDataByTagFailed, + #[error("Saving post id data by tag failed")] + SavePostIdDataByTagFailed, + #[error("Tag not found")] + TagNotFound, + + #[error("{0}")] + BusinessException(String), + #[error("invalid header (expected {expected:?}, found {found:?})")] + InvalidHeader { expected: String, found: String }, + + #[error("unknown error")] + Unknown, +} + +impl From for Error { + fn from(e: std::io::Error) -> Self { + Error::UnsupportedFileType(format!("{:?}", e)) + } +} + +impl error::ResponseError for Error { + fn error_response(&self) -> HttpResponse { + HttpResponse::build(self.status_code()) + .insert_header(ContentType::html()) + .body(self.to_string()) + } + + fn status_code(&self) -> StatusCode { + match *self { + Error::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR, + Error::BadRequest => StatusCode::BAD_REQUEST, + Error::Timeout => StatusCode::GATEWAY_TIMEOUT, + _ => StatusCode::BAD_REQUEST, + } + } +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct ErrResponse { + pub code: Error, + pub detail: String, +} diff --git a/oaf/index.html b/oaf/index.html index 35d28b8..10fcb4a 100644 --- a/oaf/index.html +++ b/oaf/index.html @@ -5,18 +5,10 @@ OA -
+
diff --git a/oaf/package.json b/oaf/package.json index 6db8cae..8ddf0b5 100644 --- a/oaf/package.json +++ b/oaf/package.json @@ -13,12 +13,14 @@ "serve": "vite preview" }, "dependencies": { + "@veypi/msg": "^0.1.0", "animate.css": "^4.1.1", "axios": "^0.24.0", "fast-xml-parser": "^3.19.0", "hot-patcher": "^0.5.0", "js-base64": "^3.7.2", "layerr": "^0.1.2", + "mitt": "^3.0.0", "nested-property": "^4.0.0", "path-posix": "^1.0.0", "seamless-scroll-polyfill": "^2.1.5", @@ -29,8 +31,8 @@ "vuex": "^4.0.2" }, "devDependencies": { - "@veypi/one-icon": "2.0.6", "@types/node": "^16.11.12", + "@veypi/one-icon": "2.0.6", "@vitejs/plugin-vue": "^1.9.3", "autoprefixer": "^9.8.8", "base-64": "^1.0.0", diff --git a/oaf/src/App.vue b/oaf/src/App.vue index 5a4cc27..095b149 100644 --- a/oaf/src/App.vue +++ b/oaf/src/App.vue @@ -1,31 +1,31 @@