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

feat(graphQL): add ldap related apis #3625

Open
wants to merge 12 commits into
base: feat/ldap-db
Choose a base branch
from
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ mime_guess = "2.0.4"
assert_matches = "1.5"
insta = "1.34.0"
logkit = "0.3"
ldap3 = "0.11.0"
async-openai = "0.20"
tracing-test = "0.2"
clap = "4.3.0"
Expand Down
1 change: 1 addition & 0 deletions ee/tabby-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use email_setting::EmailSettingDAO;
pub use integrations::IntegrationDAO;
pub use invitations::InvitationDAO;
pub use job_runs::JobRunDAO;
pub use ldap_credential::LdapCredentialDAO;
pub use notifications::NotificationDAO;
pub use oauth_credential::OAuthCredentialDAO;
pub use provided_repositories::ProvidedRepositoryDAO;
Expand Down
1 change: 1 addition & 0 deletions ee/tabby-schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ validator = { version = "0.18.1", features = ["derive"] }
regex.workspace = true
hash-ids.workspace = true
url.workspace = true
ldap3.workspace = true

[dev-dependencies]
tabby-db = { path = "../../ee/tabby-db", features = ["testutils"]}
Expand Down
50 changes: 50 additions & 0 deletions ee/tabby-schema/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ enum AuthMethod {
LOGIN
}

enum AuthProviderKind {
OAUTH_GITHUB
OAUTH_GOOGLE
OAUTH_GITLAB
LDAP
}

"Represents the kind of context source."
enum ContextSourceKind {
GIT
Expand Down Expand Up @@ -61,6 +68,12 @@ enum Language {
OTHER
}

enum LdapEncryptionKind {
NONE
START_TLS
LDAPS
}

enum LicenseStatus {
OK
EXPIRED
Expand Down Expand Up @@ -231,6 +244,19 @@ input UpdateIntegrationInput {
kind: IntegrationKind!
}

input UpdateLdapCredentialInput {
host: String!
port: Int!
bindDn: String!
bindPassword: String
baseDn: String!
userFilter: String!
encryption: LdapEncryptionKind!
skipTlsVerify: Boolean!
emailAttribute: String!
nameAttribute: String
}

input UpdateMessageInput {
id: ID!
threadId: ID!
Expand Down Expand Up @@ -288,6 +314,10 @@ interface User {
"""
scalar DateTime

type AuthProvider {
kind: AuthProviderKind!
}

type CompletionStats {
start: DateTime!
end: DateTime!
Expand Down Expand Up @@ -464,6 +494,20 @@ type JobStats {
pending: Int!
}

type LdapCredential {
host: String!
port: Int!
bindDn: String!
baseDn: String!
userFilter: String!
encryption: LdapEncryptionKind!
skipTlsVerify: Boolean!
emailAttribute: String!
nameAttribute: String
createdAt: DateTime!
updatedAt: DateTime!
}

type LicenseInfo {
type: LicenseType!
status: LicenseStatus!
Expand Down Expand Up @@ -574,6 +618,7 @@ type Mutation {
updateUserName(id: ID!, name: String!): Boolean!
register(email: String!, password1: String!, password2: String!, invitationCode: String, name: String!): RegisterResponse!
tokenAuth(email: String!, password: String!): TokenAuthResponse!
tokenAuthLdap(userId: String!, password: String!): TokenAuthResponse!
verifyToken(token: String!): Boolean!
refreshToken(refreshToken: String!): RefreshTokenResponse!
createInvitation(email: String!): ID!
Expand All @@ -585,6 +630,9 @@ type Mutation {
deleteInvitation(id: ID!): ID!
updateOauthCredential(input: UpdateOAuthCredentialInput!): Boolean!
deleteOauthCredential(provider: OAuthProvider!): Boolean!
testLdapConnection(input: UpdateLdapCredentialInput!): Boolean!
updateLdapCredential(input: UpdateLdapCredentialInput!): Boolean!
deleteLdapCredential: Boolean!
updateEmailSetting(input: EmailSettingInput!): Boolean!
updateSecuritySetting(input: SecuritySettingInput!): Boolean!
updateNetworkSetting(input: NetworkSettingInput!): Boolean!
Expand Down Expand Up @@ -716,8 +764,10 @@ type Query {
* `func_name lang:go`
"""
repositoryGrep(kind: RepositoryKind!, id: ID!, rev: String, query: String!): RepositoryGrepOutput!
authProviders: [AuthProvider!]!
oauthCredential(provider: OAuthProvider!): OAuthCredential
oauthCallbackUrl(provider: OAuthProvider!): String!
ldapCredential: LdapCredential
serverInfo: ServerInfo!
license: LicenseInfo!
jobs: [String!]!
Expand Down
50 changes: 45 additions & 5 deletions ee/tabby-schema/src/dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ use anyhow::bail;
use hash_ids::HashIds;
use lazy_static::lazy_static;
use tabby_db::{
EmailSettingDAO, IntegrationDAO, InvitationDAO, JobRunDAO, NotificationDAO, OAuthCredentialDAO,
ServerSettingDAO, ThreadDAO, ThreadMessageAttachmentClientCode, ThreadMessageAttachmentCode,
ThreadMessageAttachmentDoc, ThreadMessageAttachmentIssueDoc, ThreadMessageAttachmentPullDoc,
ThreadMessageAttachmentWebDoc, UserEventDAO,
EmailSettingDAO, IntegrationDAO, InvitationDAO, JobRunDAO, LdapCredentialDAO, NotificationDAO,
OAuthCredentialDAO, ServerSettingDAO, ThreadDAO, ThreadMessageAttachmentClientCode,
ThreadMessageAttachmentCode, ThreadMessageAttachmentDoc, ThreadMessageAttachmentIssueDoc,
ThreadMessageAttachmentPullDoc, ThreadMessageAttachmentWebDoc, UserEventDAO,
};

use crate::{
auth::LdapEncryptionKind,
integration::{Integration, IntegrationKind, IntegrationStatus},
interface::UserValue,
notification::{Notification, NotificationRecipient},
repository::RepositoryKind,
schema::{
auth::{self, OAuthCredential, OAuthProvider},
auth::{self, LdapCredential, OAuthCredential, OAuthProvider},
email::{AuthMethod, EmailSetting, Encryption},
job,
repository::{
Expand Down Expand Up @@ -67,6 +68,26 @@ impl TryFrom<OAuthCredentialDAO> for OAuthCredential {
}
}

impl TryFrom<LdapCredentialDAO> for LdapCredential {
type Error = anyhow::Error;

fn try_from(val: LdapCredentialDAO) -> Result<Self, Self::Error> {
Ok(LdapCredential {
host: val.host,
port: val.port as i32,
bind_dn: val.bind_dn,
base_dn: val.base_dn,
user_filter: val.user_filter,
encryption: LdapEncryptionKind::from_enum_str(&val.encryption)?,
skip_tls_verify: val.skip_tls_verify,
email_attribute: val.email_attribute,
name_attribute: val.name_attribute,
created_at: val.created_at,
updated_at: val.updated_at,
})
}
}

impl TryFrom<EmailSettingDAO> for EmailSetting {
type Error = anyhow::Error;

Expand Down Expand Up @@ -447,6 +468,25 @@ impl DbEnum for OAuthProvider {
}
}

impl DbEnum for LdapEncryptionKind {
fn as_enum_str(&self) -> &'static str {
match self {
LdapEncryptionKind::None => "none",
LdapEncryptionKind::StartTLS => "starttls",
LdapEncryptionKind::LDAPS => "ldaps",
}
}

fn from_enum_str(s: &str) -> anyhow::Result<Self> {
match s {
"none" => Ok(LdapEncryptionKind::None),
"starttls" => Ok(LdapEncryptionKind::StartTLS),
"ldaps" => Ok(LdapEncryptionKind::LDAPS),
_ => bail!("Invalid Ldap encryption kind"),
}
}
}

impl DbEnum for AuthMethod {
fn as_enum_str(&self) -> &'static str {
match self {
Expand Down
Loading
Loading