You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth.rs 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. mod tests {
  2. use std::path::PathBuf;
  3. use async_std::task::block_on;
  4. use oslo_lib::{hash_password, State};
  5. use serde_json::json;
  6. use tide::{
  7. http::{Method, Request, Response, StatusCode, Url},
  8. Result, Server,
  9. };
  10. async fn build_app() -> Server<State> {
  11. std::env::set_var("ADMIN_USERNAME", "correct_username".to_string());
  12. std::env::set_var(
  13. "ADMIN_PASSWORD",
  14. hash_password("correct_password", "correct_username"),
  15. );
  16. oslo_lib::build_app().await.unwrap()
  17. }
  18. fn url(path: &str) -> Url {
  19. Url::parse("http://localhost:8080")
  20. .unwrap()
  21. .join(path)
  22. .unwrap()
  23. }
  24. #[test]
  25. fn test_login_page() -> Result<()> {
  26. block_on(async {
  27. let app = build_app().await;
  28. let req = Request::new(Method::Get, url("login"));
  29. let mut res: Response = app.respond(req).await?;
  30. assert_eq!(res.status(), 200);
  31. assert!(res.body_string().await?.contains("Login"));
  32. Ok(())
  33. })
  34. }
  35. #[test]
  36. fn test_logging_in() -> Result<()> {
  37. block_on(async {
  38. let app = build_app().await;
  39. let mut req = Request::new(Method::Post, url("login"));
  40. req.set_content_type(tide::http::mime::MULTIPART_FORM);
  41. let username = String::from("correct_username");
  42. let password = String::from("correct_password");
  43. req.replace_body(format!("username={}&password={}", username, password));
  44. let res: Response = app.respond(req).await?;
  45. assert_eq!(res.status(), StatusCode::Found);
  46. assert_eq!(res.header("location").unwrap(), "/");
  47. Ok(())
  48. })
  49. }
  50. #[test]
  51. fn test_invalid_credentials() -> Result<()> {
  52. block_on(async {
  53. let app = build_app().await;
  54. let mut req = Request::new(Method::Post, url("login"));
  55. req.set_content_type(tide::http::mime::MULTIPART_FORM);
  56. req.replace_body("username=invalid&password=credentials");
  57. let res: Response = app.respond(req).await?;
  58. assert_eq!(res.status(), StatusCode::Found);
  59. assert_eq!(res.header("location").unwrap(), "/login");
  60. Ok(())
  61. })
  62. }
  63. #[test]
  64. fn test_accessing_protected_route_as_guest() -> Result<()> {
  65. block_on(async {
  66. let app = build_app().await;
  67. let req = Request::new(Method::Get, url("/posts/1/edit"));
  68. let res: Response = app.respond(req).await?;
  69. assert_eq!(res.status(), StatusCode::Found);
  70. assert_eq!(res.header("location").unwrap(), "/login");
  71. Ok(())
  72. })
  73. }
  74. #[test]
  75. fn test_attempting_to_create_post_as_guest() -> Result<()> {
  76. block_on(async {
  77. let app = build_app().await;
  78. let mut req = Request::new(Method::Post, url("/posts"));
  79. req.set_content_type(tide::http::mime::MULTIPART_FORM);
  80. req.replace_body("title=test1&slug=test1&body=test1");
  81. let res: Response = app.respond(req).await?;
  82. assert_eq!(res.status(), StatusCode::Found);
  83. assert_eq!(res.header("location").unwrap(), "/login");
  84. Ok(())
  85. })
  86. }
  87. #[test]
  88. fn test_attempting_to_update_post_as_guest() -> Result<()> {
  89. let data = json!({
  90. "title":"test1",
  91. "slug":"test1",
  92. "body":"test1",
  93. "html":"<p>test1</p>\n",
  94. "date":"2000-01-01",
  95. "draft":0
  96. });
  97. block_on(async {
  98. let app = build_app().await;
  99. let posts_dir = std::env::var("POSTS_DIR")?;
  100. let path = PathBuf::from(posts_dir);
  101. let path = path.join("test1.json");
  102. std::fs::write(&path, data.to_string())?;
  103. let mut req = Request::new(Method::Post, url("/posts/test1"));
  104. req.set_content_type(tide::http::mime::MULTIPART_FORM);
  105. req.replace_body("title=test1&slug=test1&body=test2");
  106. let res: Response = app.respond(req).await?;
  107. assert_eq!(res.status(), StatusCode::Found);
  108. assert_eq!(res.header("location").unwrap(), "/login");
  109. assert_eq!(std::fs::read_to_string(&path)?, data.to_string());
  110. std::fs::remove_file(&path)?;
  111. Ok(())
  112. })
  113. }
  114. #[test]
  115. fn test_attempting_to_delete_post_as_guest() -> Result<()> {
  116. let data = json!({
  117. "title":"test2",
  118. "slug":"test2",
  119. "body":"test2",
  120. "html":"<p>test2</p>\n",
  121. "date":"2000-01-01",
  122. "draft":0
  123. });
  124. block_on(async {
  125. let app = build_app().await;
  126. let posts_dir = std::env::var("POSTS_DIR")?;
  127. let path = PathBuf::from(posts_dir);
  128. let path = path.join("test2.json");
  129. std::fs::write(&path, data.to_string())?;
  130. let req = Request::new(Method::Delete, url("/posts/test2"));
  131. let res: Response = app.respond(req).await?;
  132. assert_eq!(res.status(), StatusCode::Found);
  133. assert_eq!(res.header("location").unwrap(), "/login");
  134. assert_eq!(std::fs::read_to_string(&path)?, data.to_string());
  135. std::fs::remove_file(&path)?;
  136. Ok(())
  137. })
  138. }
  139. }