mirror of
https://github.com/ivabus/aliurl
synced 2025-06-08 08:10:28 +03:00
Compare commits
No commits in common. "master" and "0.2.0" have entirely different histories.
6 changed files with 84 additions and 334 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "aliurl"
|
name = "aliurl"
|
||||||
version = "0.3.3"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/ivabus/aliurl"
|
repository = "https://github.com/ivabus/aliurl"
|
||||||
|
@ -12,4 +12,4 @@ rocket = "0.5.0-rc.3"
|
||||||
serde = { version = "1.0.163", features = ["derive"] }
|
serde = { version = "1.0.163", features = ["derive"] }
|
||||||
serde_json = "1.0.96"
|
serde_json = "1.0.96"
|
||||||
url-escape = "0.1.1"
|
url-escape = "0.1.1"
|
||||||
rand = "0.8.5"
|
uuid = { version = "1.3.3", features = ["v4"] }
|
||||||
|
|
84
README.md
84
README.md
|
@ -1,5 +1,3 @@
|
||||||
## Archived, see [ivabus/urouter](https://github.com/ivabus/urouter) or something else as a replacement
|
|
||||||
|
|
||||||
# aliurl
|
# aliurl
|
||||||
|
|
||||||
> ALIaser for URLs
|
> ALIaser for URLs
|
||||||
|
@ -26,14 +24,14 @@ Edit `Rocket.toml` to set port and ip.
|
||||||
cargo run -r
|
cargo run -r
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## Usage
|
||||||
|
|
||||||
### Create new alias
|
### Create new alias
|
||||||
|
|
||||||
#### Request
|
#### Request
|
||||||
|
|
||||||
```http request
|
```http request
|
||||||
POST /api/create_alias HTTP/1.1
|
POST /post HTTP/1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Request body
|
#### Request body
|
||||||
|
@ -41,89 +39,15 @@ POST /api/create_alias HTTP/1.1
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"url": "<URL_TO_BE_ALIASED>",
|
"url": "<URL_TO_BE_ALIASED>",
|
||||||
"alias": "<ALIAS_URI>", // If not provided, random string will be generated
|
"alias": "<ALIAS_URI>", // If not provided, UUID will be generated
|
||||||
"access_key": "<ACCESS_KEY>" // May not be provided, if no ./access_keys file
|
"access_key": "<ACCESS_KEY>" // May not be provided, if no ./access_keys file
|
||||||
"redirect_with_ad": "<BOOL>" //May not be provided, if provided will use ./redirect.html
|
"redirect_with_ad": "<BOOL>" //May not be provided, if provided will use ./redirect.html
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Get all aliases
|
|
||||||
|
|
||||||
#### Request
|
|
||||||
|
|
||||||
```http request
|
|
||||||
POST /api/create_alias HTTP/1.1
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Request body
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"access_key": "<ACCESS_KEY>" // May not be provided, if no ./access_keys file
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Response body
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"alias": "alias_without_ad",
|
|
||||||
"url": "https://example.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"alias": "alias_with_ad",
|
|
||||||
"redirect_with_ad": true,
|
|
||||||
"url": "https://example.com"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Remove alias
|
|
||||||
|
|
||||||
Removes all alias with provided name.
|
|
||||||
|
|
||||||
#### Request
|
|
||||||
|
|
||||||
```http request
|
|
||||||
POST /api/remove_alias HTTP/1.1
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Request body
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"alias": "<ALIAS>",
|
|
||||||
"access_key": "<ACCESS_KEY>" // May not be provided, if no ./access_keys file
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
|
|
||||||
##### Alias(es) removed
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"alias": "alias",
|
|
||||||
"url": "https://example.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"alias": "alias",
|
|
||||||
"redirect_with_ad": true,
|
|
||||||
"url": "https://another.com"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
##### No aliases found
|
|
||||||
|
|
||||||
```json
|
|
||||||
[]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Use alias
|
### Use alias
|
||||||
|
|
||||||
|
|
||||||
#### Request
|
#### Request
|
||||||
|
|
||||||
```http request
|
```http request
|
||||||
|
|
10
Rocket.toml
10
Rocket.toml
|
@ -1,9 +1,11 @@
|
||||||
[default]
|
[release]
|
||||||
address = "127.0.0.1"
|
address = "127.0.0.1"
|
||||||
port = 8080
|
port = 8080
|
||||||
keep_alive = 0
|
workers = 8
|
||||||
ident = "aliurl via Rocket"
|
keep_alive = 5
|
||||||
ip_header = false
|
ident = "Rocket"
|
||||||
|
ip_header = "X-Real-IP" # set to `false` to disable
|
||||||
log_level = "normal"
|
log_level = "normal"
|
||||||
temp_dir = "/tmp"
|
temp_dir = "/tmp"
|
||||||
cli_colors = true
|
cli_colors = true
|
||||||
|
ctrlc = false
|
||||||
|
|
136
src/main.rs
136
src/main.rs
|
@ -1,46 +1,25 @@
|
||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2023 Ivan Bushchik
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod post;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
|
|
||||||
|
use rocket::http::RawStr;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::response::content::RawHtml;
|
use rocket::response::content::RawHtml;
|
||||||
use rocket::response::Redirect;
|
use rocket::response::Redirect;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct CreateAliasRequest {
|
||||||
|
url: String,
|
||||||
|
redirect_with_ad: Option<String>,
|
||||||
|
access_key: Option<String>,
|
||||||
|
alias: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
static mut ACCESS_KEY_REQUIRED: bool = true;
|
static mut ACCESS_KEY_REQUIRED: bool = true;
|
||||||
|
|
||||||
const LEN_OF_GENERATIVE_ALIASES: usize = 6;
|
|
||||||
|
|
||||||
const INDEX_REDIRECT: &'static str = "https://ivabus.dev";
|
const INDEX_REDIRECT: &'static str = "https://ivabus.dev";
|
||||||
const INDEX_WITH_AD: bool = false;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone)]
|
||||||
struct Alias {
|
struct Alias {
|
||||||
|
@ -50,17 +29,7 @@ struct Alias {
|
||||||
redirect_with_ad: Option<bool>,
|
redirect_with_ad: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock() {
|
fn read_alias() -> Vec<Alias> {
|
||||||
while std::path::Path::new("./alias.json.lock").exists() {}
|
|
||||||
std::fs::File::create("./alias.json.lock").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unlock() {
|
|
||||||
std::fs::remove_file("./alias.json.lock").unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_aliases() -> Vec<Alias> {
|
|
||||||
lock();
|
|
||||||
if !std::path::Path::new("./alias.json").exists() {
|
if !std::path::Path::new("./alias.json").exists() {
|
||||||
let mut file = std::fs::File::create("./alias.json").unwrap();
|
let mut file = std::fs::File::create("./alias.json").unwrap();
|
||||||
file.write_all(b"[]").unwrap();
|
file.write_all(b"[]").unwrap();
|
||||||
|
@ -75,9 +44,63 @@ fn read_aliases() -> Vec<Alias> {
|
||||||
let mut buf_reader = BufReader::new(file);
|
let mut buf_reader = BufReader::new(file);
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
buf_reader.read_to_string(&mut contents).unwrap();
|
buf_reader.read_to_string(&mut contents).unwrap();
|
||||||
let aliases_list: Vec<Alias> = serde_json::from_str(&contents).unwrap();
|
let alias_list: Vec<Alias> = serde_json::from_str(&contents).unwrap();
|
||||||
unlock();
|
alias_list
|
||||||
aliases_list
|
}
|
||||||
|
|
||||||
|
#[post("/post", data = "<data>")]
|
||||||
|
fn create_alias(data: &RawStr) -> (Status, String) {
|
||||||
|
let data: CreateAliasRequest = match serde_json::from_str(&data.to_string()) {
|
||||||
|
Ok(req) => req,
|
||||||
|
Err(e) => return (Status::BadRequest, format!("Error: {e}")),
|
||||||
|
};
|
||||||
|
let mut file = std::fs::File::open("./access_keys").unwrap();
|
||||||
|
let mut buffer: String = String::new();
|
||||||
|
file.read_to_string(&mut buffer).unwrap();
|
||||||
|
let access_keys: Vec<&str> = buffer.split("\n").collect();
|
||||||
|
if let Some(key) = data.access_key {
|
||||||
|
if !access_keys.contains(&key.as_str()) {
|
||||||
|
return (Status::Forbidden, "Access key is invalid".to_string());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
if ACCESS_KEY_REQUIRED {
|
||||||
|
return (Status::Forbidden, "Access key needs to be provided".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut alias_list = read_alias();
|
||||||
|
let mut file = std::fs::File::options().write(true).open("./alias.json").unwrap();
|
||||||
|
let alias = match data.alias {
|
||||||
|
None => uuid::Uuid::new_v4().to_string(),
|
||||||
|
Some(alias) => alias,
|
||||||
|
};
|
||||||
|
if alias.contains("?") {
|
||||||
|
return (Status::BadRequest, format!("Error: alias should not contain '?'"));
|
||||||
|
}
|
||||||
|
if let Some(s) = data.redirect_with_ad {
|
||||||
|
if s.to_lowercase() == "true" {
|
||||||
|
alias_list.push(Alias {
|
||||||
|
url: data.url.clone(),
|
||||||
|
alias: alias.clone(),
|
||||||
|
redirect_with_ad: Some(true),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alias_list.push(Alias {
|
||||||
|
url: data.url.clone(),
|
||||||
|
alias: alias.clone(),
|
||||||
|
redirect_with_ad: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
alias_list.dedup_by(|a, b| a.alias == b.alias);
|
||||||
|
|
||||||
|
file.write_all(serde_json::to_string(&alias_list).unwrap().as_bytes()).unwrap();
|
||||||
|
|
||||||
|
file.sync_all().unwrap();
|
||||||
|
return (Status::Ok, format!("Created {} at {}", data.url, alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/404")]
|
#[get("/404")]
|
||||||
|
@ -89,7 +112,7 @@ fn not_found() -> Status {
|
||||||
async fn get_page(page: String) -> Result<Redirect, RawHtml<String>> {
|
async fn get_page(page: String) -> Result<Redirect, RawHtml<String>> {
|
||||||
let mut decoded_page = String::new();
|
let mut decoded_page = String::new();
|
||||||
url_escape::decode_to_string(page, &mut decoded_page);
|
url_escape::decode_to_string(page, &mut decoded_page);
|
||||||
let alias_list = read_aliases();
|
let alias_list = read_alias();
|
||||||
for i in alias_list {
|
for i in alias_list {
|
||||||
if i.alias == decoded_page {
|
if i.alias == decoded_page {
|
||||||
if let Some(red) = i.redirect_with_ad {
|
if let Some(red) = i.redirect_with_ad {
|
||||||
|
@ -107,15 +130,8 @@ async fn get_page(page: String) -> Result<Redirect, RawHtml<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn get_index() -> Result<Redirect, RawHtml<String>> {
|
async fn get_index() -> Redirect {
|
||||||
if INDEX_WITH_AD {
|
Redirect::to(INDEX_REDIRECT)
|
||||||
let mut redirect = String::new();
|
|
||||||
let mut file = std::fs::File::open("./redirect.html").unwrap();
|
|
||||||
file.read_to_string(&mut redirect).unwrap();
|
|
||||||
Err(RawHtml(redirect.replace("#REDIRECT#", INDEX_REDIRECT)))
|
|
||||||
} else {
|
|
||||||
Ok(Redirect::to(INDEX_REDIRECT))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
|
@ -139,17 +155,7 @@ async fn main() -> Result<(), rocket::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let _rocket = rocket::build()
|
let _rocket = rocket::build()
|
||||||
.mount(
|
.mount("/", routes![not_found, create_alias, get_page, get_index])
|
||||||
"/",
|
|
||||||
routes![
|
|
||||||
not_found,
|
|
||||||
post::create_alias,
|
|
||||||
post::get_aliases,
|
|
||||||
post::remove_alias,
|
|
||||||
get_page,
|
|
||||||
get_index
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.launch()
|
.launch()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
180
src/post.rs
180
src/post.rs
|
@ -1,180 +0,0 @@
|
||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2023 Ivan Bushchik
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
|
||||||
use rocket::http::{RawStr, Status};
|
|
||||||
use rocket::response::content::RawJson;
|
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct CreateAliasRequest {
|
|
||||||
url: String,
|
|
||||||
redirect_with_ad: Option<String>,
|
|
||||||
access_key: Option<String>,
|
|
||||||
alias: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct GetAliasesRequest {
|
|
||||||
access_key: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct RemoveAliasRequest {
|
|
||||||
alias: String,
|
|
||||||
access_key: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_access_key(key: Option<String>) -> Result<String, (Status, RawJson<String>)> {
|
|
||||||
let mut file = std::fs::File::open("./access_keys").unwrap();
|
|
||||||
let mut buffer: String = String::new();
|
|
||||||
file.read_to_string(&mut buffer).unwrap();
|
|
||||||
let access_keys: Vec<&str> = buffer.split("\n").collect();
|
|
||||||
return if let Some(key) = key {
|
|
||||||
if !access_keys.contains(&key.as_str()) {
|
|
||||||
Err((Status::Forbidden, RawJson(json!({"Error": "Invalid access key"}).to_string())))
|
|
||||||
} else {
|
|
||||||
Ok(key)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
if ACCESS_KEY_REQUIRED {
|
|
||||||
Err((Status::Forbidden, RawJson(json!({"Error": "No access key"}).to_string())))
|
|
||||||
} else {
|
|
||||||
Ok("".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/api/create_alias", data = "<data>")]
|
|
||||||
pub async fn create_alias(data: &RawStr) -> (Status, RawJson<String>) {
|
|
||||||
let data: CreateAliasRequest = match serde_json::from_str(&data.to_string()) {
|
|
||||||
Ok(req) => req,
|
|
||||||
Err(e) => {
|
|
||||||
return (Status::BadRequest, RawJson(json!({"Error": e.to_string()}).to_string()))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(e) = check_access_key(data.access_key) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
let mut aliases_list = read_aliases();
|
|
||||||
lock();
|
|
||||||
let mut file = std::fs::File::options().write(true).open("./alias.json").unwrap();
|
|
||||||
let alias = match data.alias {
|
|
||||||
None => {
|
|
||||||
let mut gen: String;
|
|
||||||
'gen: loop {
|
|
||||||
gen =
|
|
||||||
Alphanumeric.sample_string(&mut rand::thread_rng(), LEN_OF_GENERATIVE_ALIASES);
|
|
||||||
for i in &aliases_list {
|
|
||||||
if i.alias == gen {
|
|
||||||
continue 'gen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break 'gen;
|
|
||||||
}
|
|
||||||
gen
|
|
||||||
}
|
|
||||||
Some(alias) => alias,
|
|
||||||
};
|
|
||||||
if alias.contains("?") {
|
|
||||||
return (
|
|
||||||
Status::BadRequest,
|
|
||||||
RawJson(json!({"Error": "Alias should not contain \"?\""}).to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let alias = Alias {
|
|
||||||
url: data.url,
|
|
||||||
alias,
|
|
||||||
redirect_with_ad: match data.redirect_with_ad {
|
|
||||||
Some(s) => {
|
|
||||||
if s.to_ascii_lowercase() == "true" {
|
|
||||||
Some(true)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
aliases_list.push(alias.clone());
|
|
||||||
aliases_list.dedup_by(|a, b| a.alias == b.alias);
|
|
||||||
|
|
||||||
file.write_all(serde_json::to_string(&aliases_list).unwrap().as_bytes()).unwrap();
|
|
||||||
file.sync_all().unwrap();
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
return (Status::Ok, RawJson(serde_json::to_string(&alias).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/api/get_aliases", data = "<data>")]
|
|
||||||
pub async fn get_aliases(data: &RawStr) -> (Status, RawJson<String>) {
|
|
||||||
let data: GetAliasesRequest = match serde_json::from_str(&data.to_string()) {
|
|
||||||
Ok(req) => req,
|
|
||||||
Err(e) => {
|
|
||||||
return (Status::BadRequest, RawJson(json!({"Error": format!("{e}")}).to_string()))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(e) = check_access_key(data.access_key) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Status::Ok, RawJson(serde_json::to_string(&read_aliases()).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/api/remove_alias", data = "<data>")]
|
|
||||||
pub async fn remove_alias(data: &RawStr) -> (Status, RawJson<String>) {
|
|
||||||
let data: RemoveAliasRequest = match serde_json::from_str(&data.to_string()) {
|
|
||||||
Ok(req) => req,
|
|
||||||
Err(e) => {
|
|
||||||
return (Status::BadRequest, RawJson(json!({"Error": format!("{e}")}).to_string()))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Err(e) = check_access_key(data.access_key) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
let mut aliases_list = read_aliases();
|
|
||||||
let mut removed_aliases: Vec<Alias> = vec![];
|
|
||||||
lock();
|
|
||||||
let mut file = std::fs::File::options().write(true).open("./alias.json").unwrap();
|
|
||||||
|
|
||||||
for i in (0..aliases_list.len()).rev() {
|
|
||||||
if aliases_list[i].alias == data.alias {
|
|
||||||
removed_aliases.push(aliases_list.remove(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let aliases_list = serde_json::to_string(&aliases_list).unwrap();
|
|
||||||
file.write_all(&aliases_list.as_bytes()).unwrap();
|
|
||||||
file.set_len(aliases_list.as_bytes().len() as u64).unwrap();
|
|
||||||
file.sync_all().unwrap();
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
return (Status::Ok, RawJson(serde_json::to_string(&removed_aliases).unwrap()));
|
|
||||||
}
|
|
2
tea.yaml
2
tea.yaml
|
@ -1,2 +0,0 @@
|
||||||
dependencies:
|
|
||||||
rust-lang.org/cargo: '*'
|
|
Loading…
Reference in a new issue