Add an API endpoint to register apps

This commit is contained in:
Baptiste Gelez 2018-10-21 17:22:27 +01:00
parent 4c8a727e9e
commit f2190adfc2
6 changed files with 97 additions and 1 deletions

13
plume-api/src/apps.rs Normal file
View file

@ -0,0 +1,13 @@
use canapi::Endpoint;
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct AppEndpoint {
pub id: Option<i32>,
pub name: Option<String>,
pub website: Option<String>,
pub redirect_uri: Option<String>,
pub client_id: Option<String>,
pub client_secret: Option<String>,
}
api!("/api/v1/apps" => AppEndpoint);

View file

@ -15,4 +15,5 @@ macro_rules! api {
};
}
pub mod apps;
pub mod posts;

View file

@ -1,7 +1,13 @@
use canapi::{Error, Provider};
use chrono::NaiveDateTime;
use diesel::{self, RunQueryDsl, QueryDsl, ExpressionMethods};
use openssl::rand::rand_bytes;
use plume_api::apps::AppEndpoint;
use Connection;
use schema::apps;
#[derive(Clone, Queryable)]
pub struct App {
pub id: i32,
pub name: String,
@ -12,7 +18,63 @@ pub struct App {
pub creation_date: NaiveDateTime,
}
#[derive(Insertable)]
#[table_name= "apps"]
pub struct NewApp {
pub name: String,
pub client_id: String,
pub client_secret: String,
pub redirect_uri: Option<String>,
pub website: Option<String>,
}
impl Provider<Connection> for App {
type Data = AppEndpoint;
fn get(conn: &Connection, id: i32) -> Result<AppEndpoint, Error> {
unimplemented!()
}
fn list(conn: &Connection, query: AppEndpoint) -> Vec<AppEndpoint> {
unimplemented!()
}
fn create(conn: &Connection, data: AppEndpoint) -> Result<AppEndpoint, Error> {
let mut id = [0; 32];
rand_bytes(&mut id).expect("Error while generating client id");
let client_id = id.into_iter().fold(String::new(), |res, byte| format!("{}{:x}", res, byte));
let mut secret = [0; 32];
rand_bytes(&mut secret).expect("Error while generating client secret");
let client_secret = secret.into_iter().fold(String::new(), |res, byte| format!("{}{:x}", res, byte));
let app = App::insert(conn, NewApp {
name: data.name.expect("App::create: name is required"),
client_id: client_id,
client_secret: client_secret,
redirect_uri: data.redirect_uri,
website: data.website,
});
Ok(AppEndpoint {
id: Some(app.id),
name: Some(app.name),
client_id: Some(app.client_id),
client_secret: Some(app.client_secret),
redirect_uri: app.redirect_uri,
website: app.website,
})
}
fn update(conn: &Connection, id: i32, new_data: AppEndpoint) -> Result<AppEndpoint, Error> {
unimplemented!()
}
fn delete(conn: &Connection, id: i32) {
unimplemented!()
}
}
impl App {
get!(apps, App);
get!(apps);
insert!(apps, NewApp);
}

16
src/api/apps.rs Normal file
View file

@ -0,0 +1,16 @@
use canapi::Provider;
use rocket_contrib::Json;
use serde_json;
use plume_api::apps::AppEndpoint;
use plume_models::{
Connection,
db_conn::DbConn,
apps::App,
};
#[post("/apps", data = "<data>")]
fn create(conn: DbConn, data: Json<AppEndpoint>) -> Json<serde_json::Value> {
let post = <App as Provider<Connection>>::create(&*conn, (*data).clone()).ok();
Json(json!(post))
}

View file

@ -1 +1,2 @@
pub mod apps;
pub mod posts;

View file

@ -156,6 +156,8 @@ fn main() {
routes::errors::csrf_violation
])
.mount("/api/v1", routes![
api::apps::create,
api::posts::get,
api::posts::list,
])
@ -176,6 +178,7 @@ fn main() {
("/@/<name>/inbox".to_owned(), "/@/<name>/inbox".to_owned(), rocket::http::Method::Post),
("/login".to_owned(), "/login".to_owned(), rocket::http::Method::Post),
("/users/new".to_owned(), "/users/new".to_owned(), rocket::http::Method::Post),
("/api/v1/<endpoint>".to_owned(), "/api/v1/<endpoint>".to_owned(), rocket::http::Method::Post)
])
.finalize().expect("main: csrf fairing creation error"))
.launch();