util.rs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. fs::{File, OpenOptions},
  20. os::unix::prelude::OpenOptionsExt,
  21. path::Path,
  22. };
  23. use crypto_box::aead::Aead;
  24. use log::{debug, error};
  25. use darkfi::{Error, Result};
  26. use rand::{distributions::Alphanumeric, rngs::OsRng, Rng};
  27. use crate::{
  28. error::{TaudError, TaudResult},
  29. task_info::{TaskEvent, TaskInfo},
  30. };
  31. pub fn set_event(task_info: &mut TaskInfo, action: &str, author: &str, content: &str) {
  32. debug!(target: "tau", "TaskInfo::set_event()");
  33. if !content.is_empty() {
  34. task_info.events.push(TaskEvent::new(action.into(), author.into(), content.into()));
  35. }
  36. }
  37. pub fn pipe_write<P: AsRef<Path>>(path: P) -> Result<File> {
  38. OpenOptions::new().append(true).custom_flags(libc::O_NONBLOCK).open(path).map_err(Error::from)
  39. }
  40. pub fn gen_id(len: usize) -> String {
  41. OsRng.sample_iter(&Alphanumeric).take(len).map(char::from).collect()
  42. }
  43. pub fn check_write_access(write: Option<String>, password: Option<String>) -> TaudResult<bool> {
  44. let secret = if write.is_some() {
  45. let scrt = write.clone().unwrap();
  46. let bytes: [u8; 32] = bs58::decode(scrt)
  47. .into_vec()
  48. .map_err(|_| {
  49. Error::ParseFailed("Parse secret key failed, couldn't decode into vector of bytes")
  50. })?
  51. .try_into()
  52. .map_err(|_| Error::ParseFailed("Parse secret key failed"))?;
  53. crypto_box::SecretKey::from(bytes)
  54. } else {
  55. crypto_box::SecretKey::generate(&mut OsRng)
  56. };
  57. let public = secret.public_key();
  58. let chacha_box = crypto_box::ChaChaBox::new(&public, &secret);
  59. if password.is_some() {
  60. let bytes = match bs58::decode(password.clone().unwrap()).into_vec() {
  61. Ok(v) => v,
  62. Err(_) => return Err(TaudError::DecryptionError("Error decoding payload".to_string())),
  63. };
  64. if bytes.len() < 25 {
  65. return Err(TaudError::DecryptionError("Invalid bytes length".to_string()))
  66. }
  67. // Try extracting the nonce
  68. let nonce = bytes[0..24].into();
  69. // Take the remaining ciphertext
  70. let pswd = &bytes[24..];
  71. if chacha_box.decrypt(nonce, pswd).is_err() {
  72. error!(target: "taud", "You don't have write access");
  73. return Ok(false);
  74. };
  75. } else {
  76. error!(target: "taud", "You don't have write access");
  77. return Ok(false);
  78. };
  79. Ok(true)
  80. }