Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add derives for Clone, Debug, Eq, Hash, and PartialEq for public types #119

Merged
merged 11 commits into from Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions CHANGELOG.md
@@ -1,13 +1,19 @@
# Changelog

## 0.19
## Unreleased

- [[#119](https://github.com/IronCoreLabs/ironoxide/pull/119)]
- Add `Clone`, `Debug`, `Eq`, `Hash`, and `PartialEq` to almost all public structs.

## 0.19

- [[#114]](https://github.com/IronCoreLabs/ironoxide/pull/114)
- Adds timeouts to all public API methods. Most timeouts use a top-level config set in IronOxideConfig. Some special cases allow for passing an optional timeout directly (rotate_all, user_create, user_verify, generate_new_device). Timeouts apply to both IronOxide and BlockingIronOxide
- Configs can now be set on BlockingIronOxide. Before, defaults were always used.
- Trying out an "open" struct for all config objects to allow for easier construction and access
- Adds dependency on tokio/rt-threaded feature flag

## 0.18
## 0.18

- [[#112](https://github.com/IronCoreLabs/ironoxide/pull/112)]
- Make the default API async
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -24,7 +24,7 @@ rand = "~0.6"
rand_chacha = "~0.1"
regex = "~1.3"
ring = { version= "~0.16", features = ["std"] }
recrypt = "~0.9.2"
recrypt = {git = "https://github.com/IronCoreLabs/recrypt-rs", branch = "hash_eq_all_types"}
url= "~2.1.0"
reqwest = {version="~0.10.0", features = ["json"]}
hex = "~0.3"
Expand Down
1 change: 0 additions & 1 deletion build.rs
@@ -1,4 +1,3 @@
extern crate protobuf_codegen_pure;
use std::{
env,
fs::File,
Expand Down
27 changes: 25 additions & 2 deletions src/document/mod.rs
Expand Up @@ -15,21 +15,44 @@ use crate::{
Result,
};
use itertools::{Either, EitherOrBoth, Itertools};
use std::hash::{Hash, Hasher};

/// Advanced document operations
pub mod advanced;

/// Optional parameters that can be provided when encrypting a new document.
#[derive(Debug, PartialEq, Clone)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DocumentEncryptOpts {
id: Option<DocumentId>,
name: Option<DocumentName>,
// at least one user/group must be included either explicitly or via a policy
grants: EitherOrBoth<ExplicitGrant, PolicyGrant>,
}
#[derive(Debug, PartialEq, Clone)]

impl Hash for DocumentEncryptOpts {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.name.hash(state);
match &self.grants {
EitherOrBoth::Left(explicit) => {
0.hash(state);
explicit.hash(state);
}
EitherOrBoth::Right(policy) => {
1.hash(state);
policy.hash(state);
}
EitherOrBoth::Both(explicit, policy) => {
2.hash(state);
explicit.hash(state);
policy.hash(state);
}
}
}
}

/// Explicit users/groups that should have access to decrypt a document.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ExplicitGrant {
grant_to_author: bool,
grants: Vec<UserOrGroup>,
Expand Down
2 changes: 1 addition & 1 deletion src/group.rs
Expand Up @@ -11,8 +11,8 @@ use crate::{
};
use vec1::Vec1;

#[derive(Clone)]
/// Options for group creation.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupCreateOpts {
// unique id of a group within a segment. If none, the server will assign an id.
id: Option<GroupId>,
Expand Down
34 changes: 17 additions & 17 deletions src/internal/document_api/mod.rs
Expand Up @@ -46,7 +46,7 @@ const HEADER_META_LENGTH_LENGTH: usize = 2;
const CURRENT_DOCUMENT_ID_VERSION: u8 = 2;

/// Document ID. Unique within the segment. Must match the regex `^[a-zA-Z0-9_.$#|@/:;=+'-]+$`
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
giarc3 marked this conversation as resolved.
Show resolved Hide resolved
pub struct DocumentId(pub(crate) String);
impl DocumentId {
pub fn id(&self) -> &str {
Expand Down Expand Up @@ -74,7 +74,7 @@ impl TryFrom<String> for DocumentId {
}

/// (unencrypted) name of a document. Construct via `try_from(&str)`
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct DocumentName(pub(crate) String);
impl DocumentName {
pub fn name(&self) -> &String {
Expand Down Expand Up @@ -161,7 +161,7 @@ fn parse_document_parts(
}

/// Represents the reason a document can be viewed by the requesting user.
#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum AssociationType {
/// User created the document
Expand All @@ -173,7 +173,7 @@ pub enum AssociationType {
}

/// Represents a User struct which is returned from doc get to show the IDs of users the document is visible to
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct VisibleUser {
id: UserId,
}
Expand All @@ -184,7 +184,7 @@ impl VisibleUser {
}

/// Represents a Group struct which is returned from doc get to show the IDs and names of groups the document is visible to
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct VisibleGroup {
id: GroupId,
name: Option<GroupName>,
Expand All @@ -201,7 +201,7 @@ impl VisibleGroup {
/// Single document's (abbreviated) metadata. Returned as part of a `DocumentListResult`.
///
/// If you want full metadata for a document, see `DocumentMetadataResult`
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentListMeta(DocumentListApiResponseItem);
impl DocumentListMeta {
pub fn id(&self) -> &DocumentId {
Expand All @@ -222,7 +222,7 @@ impl DocumentListMeta {
}

/// Metadata for each of the documents that the current user has access to decrypt.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentListResult {
result: Vec<DocumentListMeta>,
}
Expand All @@ -233,7 +233,7 @@ impl DocumentListResult {
}

/// Full metadata for a document.
#[derive(Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentMetadataResult(DocumentMetaApiResponse);
impl DocumentMetadataResult {
pub fn id(&self) -> &DocumentId {
Expand Down Expand Up @@ -273,7 +273,7 @@ impl DocumentMetadataResult {
/// - `encrypted_data` - Bytes of encrypted document content
/// - `encrypted_deks` - List of encrypted document encryption keys (EDEK) of users/groups that have been granted access to `encrypted_data`
/// - `access_errs` - Users and groups that could not be granted access
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentEncryptUnmanagedResult {
id: DocumentId,
encrypted_data: Vec<u8>,
Expand Down Expand Up @@ -329,7 +329,7 @@ impl DocumentEncryptUnmanagedResult {
/// - `encrypted_data` - Bytes of encrypted document content
/// - `grants` - Users and groups that have access to decrypt the `encrypted_data`
/// - `access_errs` - Users and groups that could not be granted access
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentEncryptResult {
id: DocumentId,
name: Option<DocumentName>,
Expand Down Expand Up @@ -363,7 +363,7 @@ impl DocumentEncryptResult {
}
}
/// Result of decrypting a document. Includes minimal metadata as well as the decrypted bytes.
#[derive(Debug, PartialEq, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentDecryptResult {
id: DocumentId,
name: Option<DocumentName>,
Expand All @@ -390,7 +390,7 @@ impl DocumentDecryptResult {
}

/// A failure to edit the access list of a document.
#[derive(Debug, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocAccessEditErr {
/// User or group whose access was to be granted/revoked
pub user_or_group: UserOrGroup,
Expand All @@ -409,7 +409,7 @@ impl DocAccessEditErr {

/// Result of granting or revoking access to a document. Both grant and revoke support partial
/// success.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentAccessResult {
succeeded: Vec<UserOrGroup>,
failed: Vec<DocAccessEditErr>,
Expand All @@ -433,11 +433,11 @@ impl DocumentAccessResult {
&self.failed
}
}
#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
struct DecryptedData(Vec<u8>);

/// Result of successful unmanaged decryption
#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct DocumentDecryptUnmanagedResult {
id: DocumentId,
access_via: UserOrGroup,
Expand All @@ -462,7 +462,7 @@ impl DocumentDecryptUnmanagedResult {
}

/// Either a user or a group. Allows for containing both.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum UserOrGroup {
User { id: UserId },
Expand Down Expand Up @@ -785,7 +785,7 @@ fn recrypt_document<CR: rand::CryptoRng + rand::RngCore>(
/// Once decrypted, the DEK serves as a symmetric encryption key.
///
/// It can also be useful to think of an EDEK as representing a "document access grant" to a user/group.
#[derive(Debug, Clone, PartialEq)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct EncryptedDek {
grant_to: WithKey<UserOrGroup>,
encrypted_dek_data: recrypt::api::EncryptedValue,
Expand Down
8 changes: 4 additions & 4 deletions src/internal/document_api/requests.rs
Expand Up @@ -14,13 +14,13 @@ use crate::internal::{
use chrono::{DateTime, Utc};
use std::convert::{TryFrom, TryInto};

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct Association {
#[serde(rename = "type")]
pub typ: AssociationType,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[derive(Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
pub struct DocumentVisibility {
pub users: Vec<VisibleUser>,
pub groups: Vec<VisibleGroup>,
Expand Down Expand Up @@ -121,7 +121,7 @@ impl From<&AccessGrant> for UserOrGroup {
}
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[derive(Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct DocumentMetaApiResponse {
pub id: DocumentId,
Expand All @@ -141,7 +141,7 @@ pub mod document_list {
pub result: Vec<DocumentListApiResponseItem>,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
pub struct DocumentListApiResponseItem {
pub id: DocumentId,
pub name: Option<DocumentName>,
Expand Down
18 changes: 9 additions & 9 deletions src/internal/group_api/mod.rs
Expand Up @@ -51,7 +51,7 @@ impl GroupCreateOptsStd {
}

/// Group ID. Unique within a segment. Must match the regex `^[a-zA-Z0-9_.$#|@/:;=+'-]+$`
#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct GroupId(pub(crate) String);
impl GroupId {
pub fn id(&self) -> &str {
Expand Down Expand Up @@ -82,7 +82,7 @@ impl TryFrom<&str> for GroupId {
}

/// Group's user-assigned name. (non-unique)
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct GroupName(pub(crate) String);
impl GroupName {
pub fn name(&self) -> &String {
Expand All @@ -104,7 +104,7 @@ impl TryFrom<&str> for GroupName {
}

/// List of (abbreviated) groups for which the requesting user is either an admin or member.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupListResult {
result: Vec<GroupMetaResult>,
}
Expand All @@ -118,7 +118,7 @@ impl GroupListResult {
}
}
/// Abbreviated group information.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupMetaResult {
id: GroupId,
name: Option<GroupName>,
Expand Down Expand Up @@ -165,7 +165,7 @@ impl GroupMetaResult {
}
}

#[derive(Debug, Clone, PartialEq)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupCreateResult {
id: GroupId,
name: Option<GroupName>,
Expand Down Expand Up @@ -227,7 +227,7 @@ impl GroupCreateResult {
}
}
/// Group information.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupGetResult {
id: GroupId,
name: Option<GroupName>,
Expand Down Expand Up @@ -293,7 +293,7 @@ impl GroupGetResult {
}

/// Failure to make the requested change to a group's membership or administrators.
#[derive(Debug, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupAccessEditErr {
user: UserId,
error: String,
Expand All @@ -312,7 +312,7 @@ impl GroupAccessEditErr {
}

/// Result from requesting changes to a group's membership or administrators. Partial success is supported.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupAccessEditResult {
succeeded: Vec<UserId>,
failed: Vec<GroupAccessEditErr>,
Expand Down Expand Up @@ -530,7 +530,7 @@ pub async fn group_create<CR: rand::CryptoRng + rand::RngCore>(
resp.try_into()
}

#[derive(Debug, Clone)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GroupUpdatePrivateKeyResult {
id: GroupId,
needs_rotation: bool,
Expand Down