1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
use crate::commit::models::Commit;
use crate::config::AppState;
use crate::errors::{AppError, AppErrorResponse, AppErrorType};
use actix_web::http::header;
use actix_web::{web, HttpRequest, HttpResponse, Responder};
use slog::info;
use std::collections::HashMap;
use std::env;
/// Endpoint used for getting all commits
async fn index(
req: HttpRequest,
state: web::Data<AppState>,
) -> impl Responder {
let query =
web::Query::<HashMap<String, String>>::from_query(req.query_string())
.unwrap();
let hash = match query.get("q") {
Some(x) => x.clone(),
None => String::new(),
};
let repo_user = match query.get("repository_user") {
Some(x) => x.clone(),
None => String::new(),
};
let repo_name = match query.get("repository_name") {
Some(x) => x.clone(),
None => String::new(),
};
let result;
if repo_user != "" && repo_name != "" {
info!(
state.log,
"GET /commit/?repository_user={}&repository_name={}",
&repo_user,
&repo_name
);
let repository_url = format!("{}/{}", repo_user, repo_name);
result =
Commit::find_by_repository(state.pool.clone(), repository_url)
.await;
} else {
info!(state.log, "GET /commit/?q={}", &hash);
result = Commit::find_all(state.pool.clone(), &hash).await;
}
match result {
Ok(commits) => HttpResponse::Ok().json(commits),
_ => HttpResponse::BadRequest().json(AppErrorResponse {
detail: "Error trying to read all commits from database"
.to_string(),
}),
}
}
// Endpoint used for getting one commit
async fn get_commit(
state: web::Data<AppState>,
hash: web::Path<String>,
) -> impl Responder {
info!(state.log, "GET /commit/{}/", &hash);
let result = Commit::find(state.pool.clone(), hash.clone()).await;
result
.map(|commit| HttpResponse::Ok().json(commit))
.map_err(|e| e)
}
/// Endpoint used for delete commitsitory.
/// It uses a SECRET_KEY used like an API key
async fn delete_commit(
req: HttpRequest,
state: web::Data<AppState>,
hash: web::Path<String>,
) -> impl Responder {
match req.headers().get(header::AUTHORIZATION) {
Some(x)
if x.to_str().unwrap()
!= env::var("SECRET_KEY").unwrap_or("".to_string()) =>
{
info!(state.log, "DELETE /commit/{}/ 401", &hash);
return Err(AppError {
error_type: AppErrorType::AuthorizationError,
message: Some(
"You must provide a valid Authorization".to_string(),
),
cause: None,
});
}
Some(_) => {}
None => {
info!(state.log, "DELETE /commit/{}/ 400", &hash);
return Ok(HttpResponse::BadRequest().body(""));
}
};
let result = Commit::delete(state.pool.clone(), &hash).await;
info!(state.log, "DELETE /commit/{}/", &hash);
result
.map(|_| HttpResponse::NoContent().body(""))
.map_err(|e| e)
}
/// Endpoint used for getting a raking of the post authors by commit number
async fn get_top_authors(state: web::Data<AppState>) -> impl Responder {
info!(state.log, "GET /commit/top/");
let result = Commit::most_authors(state.pool.clone()).await;
result
.map(|authors| HttpResponse::Ok().json(authors))
.map_err(|e| e)
}
/// Routes for commits
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service(
web::scope("/commit")
.service(web::resource("/").route(web::get().to(index)))
.service(
web::resource("/top/").route(web::get().to(get_top_authors)),
)
.service(
web::resource("/{hash}/")
.route(web::get().to(get_commit))
.route(web::delete().to(delete_commit)),
),
);
}
|