Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions examples/invitations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::env;
use std::fs::File;
use std::io::Read;

use tokio::runtime::Runtime;

use futures::stream::Stream;
use hubcaps::{Credentials, Github, InstallationTokenGenerator, JWTCredentials, Result};

fn var(name: &str) -> Result<String> {
if let Some(v) = env::var(name).ok() {
Ok(v)
} else {
Err(format!("example missing {}", name).into())
}
}

const USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

fn main() -> Result<()> {
pretty_env_logger::init();
let key_file = var("GH_APP_KEY")?;
let app_id = var("GH_APP_ID")?;
let installation_id = var("GH_INSTALL_ID")?;

let mut rt = Runtime::new()?;

let mut key = Vec::new();
File::open(&key_file)?.read_to_end(&mut key)?;
let cred = JWTCredentials::new(app_id.parse().expect("Bad GH_APP_ID"), key)?;

let mut github = Github::new(USER_AGENT, Credentials::JWT(cred.clone()))?;
github.set_credentials(Credentials::InstallationToken(
InstallationTokenGenerator::new(installation_id.parse().unwrap(), cred),
));

rt.block_on(
github
.org("NixOS")
.membership()
.invitations()
.for_each(|invite| {
println!("{:#?}", invite);
Ok(())
}),
)?;

Ok(())
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ pub mod hooks;
pub mod issues;
pub mod keys;
pub mod labels;
pub mod membership;
pub mod notifications;
pub mod organizations;
pub mod pull_commits;
Expand Down
54 changes: 54 additions & 0 deletions src/membership.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Organization Membership interface
use serde::Deserialize;

use crate::users::User;
use crate::{Github, Stream};

/// Provides access to membership operations available for an individual organization
pub struct OrgMembership {
github: Github,
org: String,
}

impl OrgMembership {
#[doc(hidden)]
pub fn new<O>(github: Github, org: O) -> Self
where
O: Into<String>,
{
Self {
github,
org: org.into(),
}
}

/// Return a stream of all invitations for this repository
///
/// See the [github docs](https://developer.github.com/v3/orgs/members/)
/// for more information
pub fn invitations(&self) -> Stream<Invitation> {
self.github
.get_stream(&format!("/orgs/{}/invitations", self.org))
}
}

#[derive(Debug, Deserialize)]
pub struct Invitation {
pub id: u64,
pub login: Option<String>,
pub email: Option<String>,
pub role: InvitedRole,
pub created_at: String, // TODO: change to `DateTime`?
pub inviter: User,
pub team_count: Option<u64>,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum InvitedRole {
DirectMember,
Admin,
BillingManager,
HiringManager,
Reinstate,
}
6 changes: 6 additions & 0 deletions src/organizations.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Organizations interface
use serde::Deserialize;

use crate::membership::OrgMembership;
use crate::repositories::OrgRepositories;
use crate::teams::OrgTeams;
use crate::{Future, Github};
Expand All @@ -23,6 +24,11 @@ impl Organization {
}
}

/// returns a reference to an interface for Organization invitations
pub fn membership(&self) -> OrgMembership {
OrgMembership::new(self.github.clone(), self.org.clone())
}

/// returns a reference to an interface for team operations
pub fn teams(&self) -> OrgTeams {
OrgTeams::new(self.github.clone(), self.org.clone())
Expand Down