| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552 |
- package gorm
- import (
- "github.com/porter-dev/porter/internal/encryption"
- "github.com/porter-dev/porter/internal/models"
- "github.com/porter-dev/porter/internal/repository"
- "github.com/porter-dev/porter/internal/repository/credentials"
- "gorm.io/gorm"
- ints "github.com/porter-dev/porter/internal/models/integrations"
- )
- // KubeIntegrationRepository uses gorm.DB for querying the database
- type KubeIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- }
- // NewKubeIntegrationRepository returns a KubeIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewKubeIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- ) repository.KubeIntegrationRepository {
- return &KubeIntegrationRepository{db, key}
- }
- // CreateKubeIntegration creates a new kube auth mechanism
- func (repo *KubeIntegrationRepository) CreateKubeIntegration(
- am *ints.KubeIntegration,
- ) (*ints.KubeIntegration, error) {
- err := repo.EncryptKubeIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("KubeIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- return am, nil
- }
- // ReadKubeIntegration finds a kube auth mechanism by id
- func (repo *KubeIntegrationRepository) ReadKubeIntegration(
- projectID, id uint,
- ) (*ints.KubeIntegration, error) {
- ki := &ints.KubeIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&ki).Error; err != nil {
- return nil, err
- }
- err := repo.DecryptKubeIntegrationData(ki, repo.key)
- if err != nil {
- return nil, err
- }
- return ki, nil
- }
- // ListKubeIntegrationsByProjectID finds all kube auth mechanisms
- // for a given project id
- func (repo *KubeIntegrationRepository) ListKubeIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.KubeIntegration, error) {
- kis := []*ints.KubeIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&kis).Error; err != nil {
- return nil, err
- }
- return kis, nil
- }
- // EncryptKubeIntegrationData will encrypt the kube integration data before
- // writing to the DB
- func (repo *KubeIntegrationRepository) EncryptKubeIntegrationData(
- ki *ints.KubeIntegration,
- key *[32]byte,
- ) error {
- if len(ki.ClientCertificateData) > 0 {
- cipherData, err := encryption.Encrypt(ki.ClientCertificateData, key)
- if err != nil {
- return err
- }
- ki.ClientCertificateData = cipherData
- }
- if len(ki.ClientKeyData) > 0 {
- cipherData, err := encryption.Encrypt(ki.ClientKeyData, key)
- if err != nil {
- return err
- }
- ki.ClientKeyData = cipherData
- }
- if len(ki.Token) > 0 {
- cipherData, err := encryption.Encrypt(ki.Token, key)
- if err != nil {
- return err
- }
- ki.Token = cipherData
- }
- if len(ki.Username) > 0 {
- cipherData, err := encryption.Encrypt(ki.Username, key)
- if err != nil {
- return err
- }
- ki.Username = cipherData
- }
- if len(ki.Password) > 0 {
- cipherData, err := encryption.Encrypt(ki.Password, key)
- if err != nil {
- return err
- }
- ki.Password = cipherData
- }
- if len(ki.Kubeconfig) > 0 {
- cipherData, err := encryption.Encrypt(ki.Kubeconfig, key)
- if err != nil {
- return err
- }
- ki.Kubeconfig = cipherData
- }
- return nil
- }
- // DecryptKubeIntegrationData will decrypt the kube integration data before
- // returning it from the DB
- func (repo *KubeIntegrationRepository) DecryptKubeIntegrationData(
- ki *ints.KubeIntegration,
- key *[32]byte,
- ) error {
- if len(ki.ClientCertificateData) > 0 {
- plaintext, err := encryption.Decrypt(ki.ClientCertificateData, key)
- if err != nil {
- return err
- }
- ki.ClientCertificateData = plaintext
- }
- if len(ki.ClientKeyData) > 0 {
- plaintext, err := encryption.Decrypt(ki.ClientKeyData, key)
- if err != nil {
- return err
- }
- ki.ClientKeyData = plaintext
- }
- if len(ki.Token) > 0 {
- plaintext, err := encryption.Decrypt(ki.Token, key)
- if err != nil {
- return err
- }
- ki.Token = plaintext
- }
- if len(ki.Username) > 0 {
- plaintext, err := encryption.Decrypt(ki.Username, key)
- if err != nil {
- return err
- }
- ki.Username = plaintext
- }
- if len(ki.Password) > 0 {
- plaintext, err := encryption.Decrypt(ki.Password, key)
- if err != nil {
- return err
- }
- ki.Password = plaintext
- }
- if len(ki.Kubeconfig) > 0 {
- plaintext, err := encryption.Decrypt(ki.Kubeconfig, key)
- if err != nil {
- return err
- }
- ki.Kubeconfig = plaintext
- }
- return nil
- }
- // BasicIntegrationRepository uses gorm.DB for querying the database
- type BasicIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- }
- // NewBasicIntegrationRepository returns a BasicIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewBasicIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- ) repository.BasicIntegrationRepository {
- return &BasicIntegrationRepository{db, key}
- }
- // CreateBasicIntegration creates a new basic auth mechanism
- func (repo *BasicIntegrationRepository) CreateBasicIntegration(
- am *ints.BasicIntegration,
- ) (*ints.BasicIntegration, error) {
- err := repo.EncryptBasicIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("BasicIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- return am, nil
- }
- // ReadBasicIntegration finds a basic auth mechanism by id
- func (repo *BasicIntegrationRepository) ReadBasicIntegration(
- projectID, id uint,
- ) (*ints.BasicIntegration, error) {
- basic := &ints.BasicIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&basic).Error; err != nil {
- return nil, err
- }
- err := repo.DecryptBasicIntegrationData(basic, repo.key)
- if err != nil {
- return nil, err
- }
- return basic, nil
- }
- // ListBasicIntegrationsByProjectID finds all basic auth mechanisms
- // for a given project id
- func (repo *BasicIntegrationRepository) ListBasicIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.BasicIntegration, error) {
- basics := []*ints.BasicIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&basics).Error; err != nil {
- return nil, err
- }
- return basics, nil
- }
- // EncryptBasicIntegrationData will encrypt the basic integration data before
- // writing to the DB
- func (repo *BasicIntegrationRepository) EncryptBasicIntegrationData(
- basic *ints.BasicIntegration,
- key *[32]byte,
- ) error {
- if len(basic.Username) > 0 {
- cipherData, err := encryption.Encrypt(basic.Username, key)
- if err != nil {
- return err
- }
- basic.Username = cipherData
- }
- if len(basic.Password) > 0 {
- cipherData, err := encryption.Encrypt(basic.Password, key)
- if err != nil {
- return err
- }
- basic.Password = cipherData
- }
- return nil
- }
- // DecryptBasicIntegrationData will decrypt the basic integration data before
- // returning it from the DB
- func (repo *BasicIntegrationRepository) DecryptBasicIntegrationData(
- basic *ints.BasicIntegration,
- key *[32]byte,
- ) error {
- if len(basic.Username) > 0 {
- plaintext, err := encryption.Decrypt(basic.Username, key)
- if err != nil {
- return err
- }
- basic.Username = plaintext
- }
- if len(basic.Password) > 0 {
- plaintext, err := encryption.Decrypt(basic.Password, key)
- if err != nil {
- return err
- }
- basic.Password = plaintext
- }
- return nil
- }
- // OIDCIntegrationRepository uses gorm.DB for querying the database
- type OIDCIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- }
- // NewOIDCIntegrationRepository returns a OIDCIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewOIDCIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- ) repository.OIDCIntegrationRepository {
- return &OIDCIntegrationRepository{db, key}
- }
- // CreateOIDCIntegration creates a new oidc auth mechanism
- func (repo *OIDCIntegrationRepository) CreateOIDCIntegration(
- am *ints.OIDCIntegration,
- ) (*ints.OIDCIntegration, error) {
- err := repo.EncryptOIDCIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("OIDCIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- return am, nil
- }
- // ReadOIDCIntegration finds a oidc auth mechanism by id
- func (repo *OIDCIntegrationRepository) ReadOIDCIntegration(
- projectID, id uint,
- ) (*ints.OIDCIntegration, error) {
- oidc := &ints.OIDCIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&oidc).Error; err != nil {
- return nil, err
- }
- err := repo.DecryptOIDCIntegrationData(oidc, repo.key)
- if err != nil {
- return nil, err
- }
- return oidc, nil
- }
- // ListOIDCIntegrationsByProjectID finds all oidc auth mechanisms
- // for a given project id
- func (repo *OIDCIntegrationRepository) ListOIDCIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.OIDCIntegration, error) {
- oidcs := []*ints.OIDCIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&oidcs).Error; err != nil {
- return nil, err
- }
- return oidcs, nil
- }
- // EncryptOIDCIntegrationData will encrypt the oidc integration data before
- // writing to the DB
- func (repo *OIDCIntegrationRepository) EncryptOIDCIntegrationData(
- oidc *ints.OIDCIntegration,
- key *[32]byte,
- ) error {
- if len(oidc.IssuerURL) > 0 {
- cipherData, err := encryption.Encrypt(oidc.IssuerURL, key)
- if err != nil {
- return err
- }
- oidc.IssuerURL = cipherData
- }
- if len(oidc.ClientID) > 0 {
- cipherData, err := encryption.Encrypt(oidc.ClientID, key)
- if err != nil {
- return err
- }
- oidc.ClientID = cipherData
- }
- if len(oidc.ClientSecret) > 0 {
- cipherData, err := encryption.Encrypt(oidc.ClientSecret, key)
- if err != nil {
- return err
- }
- oidc.ClientSecret = cipherData
- }
- if len(oidc.CertificateAuthorityData) > 0 {
- cipherData, err := encryption.Encrypt(oidc.CertificateAuthorityData, key)
- if err != nil {
- return err
- }
- oidc.CertificateAuthorityData = cipherData
- }
- if len(oidc.IDToken) > 0 {
- cipherData, err := encryption.Encrypt(oidc.IDToken, key)
- if err != nil {
- return err
- }
- oidc.IDToken = cipherData
- }
- if len(oidc.RefreshToken) > 0 {
- cipherData, err := encryption.Encrypt(oidc.RefreshToken, key)
- if err != nil {
- return err
- }
- oidc.RefreshToken = cipherData
- }
- return nil
- }
- // DecryptOIDCIntegrationData will decrypt the kube integration data before
- // returning it from the DB
- func (repo *OIDCIntegrationRepository) DecryptOIDCIntegrationData(
- oidc *ints.OIDCIntegration,
- key *[32]byte,
- ) error {
- if len(oidc.IssuerURL) > 0 {
- plaintext, err := encryption.Decrypt(oidc.IssuerURL, key)
- if err != nil {
- return err
- }
- oidc.IssuerURL = plaintext
- }
- if len(oidc.ClientID) > 0 {
- plaintext, err := encryption.Decrypt(oidc.ClientID, key)
- if err != nil {
- return err
- }
- oidc.ClientID = plaintext
- }
- if len(oidc.ClientSecret) > 0 {
- plaintext, err := encryption.Decrypt(oidc.ClientSecret, key)
- if err != nil {
- return err
- }
- oidc.ClientSecret = plaintext
- }
- if len(oidc.CertificateAuthorityData) > 0 {
- plaintext, err := encryption.Decrypt(oidc.CertificateAuthorityData, key)
- if err != nil {
- return err
- }
- oidc.CertificateAuthorityData = plaintext
- }
- if len(oidc.IDToken) > 0 {
- plaintext, err := encryption.Decrypt(oidc.IDToken, key)
- if err != nil {
- return err
- }
- oidc.IDToken = plaintext
- }
- if len(oidc.RefreshToken) > 0 {
- plaintext, err := encryption.Decrypt(oidc.RefreshToken, key)
- if err != nil {
- return err
- }
- oidc.RefreshToken = plaintext
- }
- return nil
- }
- // OAuthIntegrationRepository uses gorm.DB for querying the database
- type OAuthIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- storageBackend credentials.CredentialStorage
- }
- // NewOAuthIntegrationRepository returns a OAuthIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewOAuthIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- storageBackend credentials.CredentialStorage,
- ) repository.OAuthIntegrationRepository {
- return &OAuthIntegrationRepository{db, key, storageBackend}
- }
- // CreateOAuthIntegration creates a new oauth auth mechanism
- func (repo *OAuthIntegrationRepository) CreateOAuthIntegration(
- am *ints.OAuthIntegration,
- ) (*ints.OAuthIntegration, error) {
- err := repo.EncryptOAuthIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.OAuthCredential{}
- if repo.storageBackend != nil {
- credentialData.AccessToken = am.AccessToken
- credentialData.RefreshToken = am.RefreshToken
- credentialData.ClientID = am.ClientID
- am.AccessToken = []byte{}
- am.RefreshToken = []byte{}
- am.ClientID = []byte{}
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("OAuthIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteOAuthCredential(am, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return am, nil
- }
- // ReadOAuthIntegration finds a oauth auth mechanism by id
- func (repo *OAuthIntegrationRepository) ReadOAuthIntegration(
- projectID, id uint,
- ) (*ints.OAuthIntegration, error) {
- oauth := &ints.OAuthIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&oauth).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- credentialData, err := repo.storageBackend.GetOAuthCredential(oauth)
- if err != nil {
- return nil, err
- }
- oauth.AccessToken = credentialData.AccessToken
- oauth.RefreshToken = credentialData.RefreshToken
- oauth.ClientID = credentialData.ClientID
- }
- err := repo.DecryptOAuthIntegrationData(oauth, repo.key)
- if err != nil {
- return nil, err
- }
- return oauth, nil
- }
- // ListOAuthIntegrationsByProjectID finds all oauth auth mechanisms
- // for a given project id
- func (repo *OAuthIntegrationRepository) ListOAuthIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.OAuthIntegration, error) {
- oauths := []*ints.OAuthIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&oauths).Error; err != nil {
- return nil, err
- }
- return oauths, nil
- }
- // UpdateOAuthIntegration modifies an existing oauth integration in the database
- func (repo *OAuthIntegrationRepository) UpdateOAuthIntegration(
- am *ints.OAuthIntegration,
- ) (*ints.OAuthIntegration, error) {
- err := repo.EncryptOAuthIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.OAuthCredential{}
- if repo.storageBackend != nil {
- credentialData.AccessToken = am.AccessToken
- credentialData.RefreshToken = am.RefreshToken
- credentialData.ClientID = am.ClientID
- am.AccessToken = []byte{}
- am.RefreshToken = []byte{}
- am.ClientID = []byte{}
- }
- if err := repo.db.Save(am).Error; err != nil {
- return nil, err
- }
- err = repo.DecryptOAuthIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteOAuthCredential(am, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return am, nil
- }
- // EncryptOAuthIntegrationData will encrypt the oauth integration data before
- // writing to the DB
- func (repo *OAuthIntegrationRepository) EncryptOAuthIntegrationData(
- oauth *ints.OAuthIntegration,
- key *[32]byte,
- ) error {
- if len(oauth.ClientID) > 0 {
- cipherData, err := encryption.Encrypt(oauth.ClientID, key)
- if err != nil {
- return err
- }
- oauth.ClientID = cipherData
- }
- if len(oauth.AccessToken) > 0 {
- cipherData, err := encryption.Encrypt(oauth.AccessToken, key)
- if err != nil {
- return err
- }
- oauth.AccessToken = cipherData
- }
- if len(oauth.RefreshToken) > 0 {
- cipherData, err := encryption.Encrypt(oauth.RefreshToken, key)
- if err != nil {
- return err
- }
- oauth.RefreshToken = cipherData
- }
- return nil
- }
- // DecryptOAuthIntegrationData will decrypt the oauth integration data before
- // returning it from the DB
- func (repo *OAuthIntegrationRepository) DecryptOAuthIntegrationData(
- oauth *ints.OAuthIntegration,
- key *[32]byte,
- ) error {
- if len(oauth.ClientID) > 0 {
- plaintext, err := encryption.Decrypt(oauth.ClientID, key)
- if err != nil {
- return err
- }
- oauth.ClientID = plaintext
- }
- if len(oauth.AccessToken) > 0 {
- plaintext, err := encryption.Decrypt(oauth.AccessToken, key)
- if err != nil {
- return err
- }
- oauth.AccessToken = plaintext
- }
- if len(oauth.RefreshToken) > 0 {
- plaintext, err := encryption.Decrypt(oauth.RefreshToken, key)
- if err != nil {
- return err
- }
- oauth.RefreshToken = plaintext
- }
- return nil
- }
- // GCPIntegrationRepository uses gorm.DB for querying the database
- type GCPIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- storageBackend credentials.CredentialStorage
- }
- // NewGCPIntegrationRepository returns a GCPIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewGCPIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- storageBackend credentials.CredentialStorage,
- ) repository.GCPIntegrationRepository {
- return &GCPIntegrationRepository{db, key, storageBackend}
- }
- // CreateGCPIntegration creates a new gcp auth mechanism
- func (repo *GCPIntegrationRepository) CreateGCPIntegration(
- am *ints.GCPIntegration,
- ) (*ints.GCPIntegration, error) {
- err := repo.EncryptGCPIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.GCPCredential{}
- if repo.storageBackend != nil {
- credentialData.GCPKeyData = am.GCPKeyData
- am.GCPKeyData = []byte{}
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("GCPIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteGCPCredential(am, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return am, nil
- }
- // ReadGCPIntegration finds a gcp auth mechanism by id
- func (repo *GCPIntegrationRepository) ReadGCPIntegration(
- projectID, id uint,
- ) (*ints.GCPIntegration, error) {
- gcp := &ints.GCPIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&gcp).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- credentialData, err := repo.storageBackend.GetGCPCredential(gcp)
- if err != nil {
- return nil, err
- }
- gcp.GCPKeyData = credentialData.GCPKeyData
- }
- err := repo.DecryptGCPIntegrationData(gcp, repo.key)
- if err != nil {
- return nil, err
- }
- return gcp, nil
- }
- // ListGCPIntegrationsByProjectID finds all gcp auth mechanisms
- // for a given project id
- func (repo *GCPIntegrationRepository) ListGCPIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.GCPIntegration, error) {
- gcps := []*ints.GCPIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&gcps).Error; err != nil {
- return nil, err
- }
- return gcps, nil
- }
- // EncryptGCPIntegrationData will encrypt the gcp integration data before
- // writing to the DB
- func (repo *GCPIntegrationRepository) EncryptGCPIntegrationData(
- gcp *ints.GCPIntegration,
- key *[32]byte,
- ) error {
- if len(gcp.GCPKeyData) > 0 {
- cipherData, err := encryption.Encrypt(gcp.GCPKeyData, key)
- if err != nil {
- return err
- }
- gcp.GCPKeyData = cipherData
- }
- return nil
- }
- // DecryptGCPIntegrationData will decrypt the gcp integration data before
- // returning it from the DB
- func (repo *GCPIntegrationRepository) DecryptGCPIntegrationData(
- gcp *ints.GCPIntegration,
- key *[32]byte,
- ) error {
- if len(gcp.GCPKeyData) > 0 {
- plaintext, err := encryption.Decrypt(gcp.GCPKeyData, key)
- if err != nil {
- return err
- }
- gcp.GCPKeyData = plaintext
- }
- return nil
- }
- // AWSIntegrationRepository uses gorm.DB for querying the database
- type AWSIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- storageBackend credentials.CredentialStorage
- }
- // NewAWSIntegrationRepository returns a AWSIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewAWSIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- storageBackend credentials.CredentialStorage,
- ) repository.AWSIntegrationRepository {
- return &AWSIntegrationRepository{db, key, storageBackend}
- }
- // CreateAWSIntegration creates a new aws auth mechanism
- func (repo *AWSIntegrationRepository) CreateAWSIntegration(
- am *ints.AWSIntegration,
- ) (*ints.AWSIntegration, error) {
- err := repo.EncryptAWSIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.AWSCredential{}
- if repo.storageBackend != nil {
- credentialData.AWSAccessKeyID = am.AWSAccessKeyID
- credentialData.AWSClusterID = am.AWSClusterID
- credentialData.AWSSecretAccessKey = am.AWSSecretAccessKey
- credentialData.AWSSessionToken = am.AWSSessionToken
- am.AWSAccessKeyID = []byte{}
- am.AWSClusterID = []byte{}
- am.AWSSecretAccessKey = []byte{}
- am.AWSSessionToken = []byte{}
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", am.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("AWSIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(am); err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteAWSCredential(am, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return am, nil
- }
- // UpdateCluster modifies an existing Cluster in the database
- func (repo *AWSIntegrationRepository) OverwriteAWSIntegration(
- am *ints.AWSIntegration,
- ) (*ints.AWSIntegration, error) {
- err := repo.EncryptAWSIntegrationData(am, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.AWSCredential{}
- if repo.storageBackend != nil {
- credentialData.AWSAccessKeyID = am.AWSAccessKeyID
- credentialData.AWSClusterID = am.AWSClusterID
- credentialData.AWSSecretAccessKey = am.AWSSecretAccessKey
- credentialData.AWSSessionToken = am.AWSSessionToken
- am.AWSAccessKeyID = []byte{}
- am.AWSClusterID = []byte{}
- am.AWSSecretAccessKey = []byte{}
- am.AWSSessionToken = []byte{}
- }
- if err := repo.db.Save(am).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteAWSCredential(am, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return am, nil
- }
- // ReadAWSIntegration finds a aws auth mechanism by id
- func (repo *AWSIntegrationRepository) ReadAWSIntegration(
- projectID, id uint,
- ) (*ints.AWSIntegration, error) {
- aws := &ints.AWSIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&aws).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- credentialData, err := repo.storageBackend.GetAWSCredential(aws)
- if err != nil {
- return nil, err
- }
- aws.AWSAccessKeyID = credentialData.AWSAccessKeyID
- aws.AWSClusterID = credentialData.AWSClusterID
- aws.AWSSecretAccessKey = credentialData.AWSSecretAccessKey
- aws.AWSSessionToken = credentialData.AWSSessionToken
- }
- err := repo.DecryptAWSIntegrationData(aws, repo.key)
- if err != nil {
- return nil, err
- }
- return aws, nil
- }
- // ListAWSIntegrationsByProjectID finds all aws auth mechanisms
- // for a given project id
- func (repo *AWSIntegrationRepository) ListAWSIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.AWSIntegration, error) {
- awss := []*ints.AWSIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&awss).Error; err != nil {
- return nil, err
- }
- return awss, nil
- }
- // EncryptAWSIntegrationData will encrypt the aws integration data before
- // writing to the DB
- func (repo *AWSIntegrationRepository) EncryptAWSIntegrationData(
- aws *ints.AWSIntegration,
- key *[32]byte,
- ) error {
- if len(aws.AWSClusterID) > 0 {
- cipherData, err := encryption.Encrypt(aws.AWSClusterID, key)
- if err != nil {
- return err
- }
- aws.AWSClusterID = cipherData
- }
- if len(aws.AWSAccessKeyID) > 0 {
- cipherData, err := encryption.Encrypt(aws.AWSAccessKeyID, key)
- if err != nil {
- return err
- }
- aws.AWSAccessKeyID = cipherData
- }
- if len(aws.AWSSecretAccessKey) > 0 {
- cipherData, err := encryption.Encrypt(aws.AWSSecretAccessKey, key)
- if err != nil {
- return err
- }
- aws.AWSSecretAccessKey = cipherData
- }
- if len(aws.AWSSessionToken) > 0 {
- cipherData, err := encryption.Encrypt(aws.AWSSessionToken, key)
- if err != nil {
- return err
- }
- aws.AWSSessionToken = cipherData
- }
- return nil
- }
- // DecryptAWSIntegrationData will decrypt the aws integration data before
- // returning it from the DB
- func (repo *AWSIntegrationRepository) DecryptAWSIntegrationData(
- aws *ints.AWSIntegration,
- key *[32]byte,
- ) error {
- if len(aws.AWSClusterID) > 0 {
- plaintext, err := encryption.Decrypt(aws.AWSClusterID, key)
- if err != nil {
- return err
- }
- aws.AWSClusterID = plaintext
- }
- if len(aws.AWSAccessKeyID) > 0 {
- plaintext, err := encryption.Decrypt(aws.AWSAccessKeyID, key)
- if err != nil {
- return err
- }
- aws.AWSAccessKeyID = plaintext
- }
- if len(aws.AWSSecretAccessKey) > 0 {
- plaintext, err := encryption.Decrypt(aws.AWSSecretAccessKey, key)
- if err != nil {
- return err
- }
- aws.AWSSecretAccessKey = plaintext
- }
- if len(aws.AWSSessionToken) > 0 {
- plaintext, err := encryption.Decrypt(aws.AWSSessionToken, key)
- if err != nil {
- return err
- }
- aws.AWSSessionToken = plaintext
- }
- return nil
- }
- // GithubAppInstallationRepository implements repository.GithubAppInstallationRepository
- type GithubAppInstallationRepository struct {
- db *gorm.DB
- }
- // NewGithubAppInstallationRepository creates a new GithubAppInstallationRepository
- func NewGithubAppInstallationRepository(db *gorm.DB) repository.GithubAppInstallationRepository {
- return &GithubAppInstallationRepository{db}
- }
- // CreateGithubAppInstallation creates a new GithubAppInstallation instance
- func (repo *GithubAppInstallationRepository) CreateGithubAppInstallation(am *ints.GithubAppInstallation) (*ints.GithubAppInstallation, error) {
- if err := repo.db.Create(am).Error; err != nil {
- return nil, err
- }
- return am, nil
- }
- // ReadGithubAppInstallationByInstallationID finds a GithubAppInstallation by id
- func (repo *GithubAppInstallationRepository) ReadGithubAppInstallationByInstallationID(gaID uint) (*ints.GithubAppInstallation, error) {
- ret := &ints.GithubAppInstallation{}
- if err := repo.db.Where("installation_id = ?", gaID).First(&ret).Error; err != nil {
- return nil, err
- }
- return ret, nil
- }
- // ReadGithubAppInstallationByAccountID finds a GithubAppInstallation by an account ID
- func (repo *GithubAppInstallationRepository) ReadGithubAppInstallationByAccountID(accountID int64) (*ints.GithubAppInstallation, error) {
- ret := &ints.GithubAppInstallation{}
- if err := repo.db.Where("account_id = ?", accountID).First(&ret).Error; err != nil {
- return nil, err
- }
- return ret, nil
- }
- // ReadGithubAppInstallationByAccountIDs finds all instances of GithubInstallations given a list of account IDs
- // note that if there is not Installation for a given ID, no error will be generated
- func (repo *GithubAppInstallationRepository) ReadGithubAppInstallationByAccountIDs(accountIDs []int64) ([]*ints.GithubAppInstallation, error) {
- ret := make([]*ints.GithubAppInstallation, 0)
- if err := repo.db.Where("account_id IN ?", accountIDs).Find(&ret).Error; err != nil {
- return nil, err
- }
- return ret, nil
- }
- // DeleteGithubAppInstallationByAccountID deletes a GithubAppInstallation given an account ID
- // note that this deletion is done with db.Unscoped(), so the record is actually deleted
- func (repo *GithubAppInstallationRepository) DeleteGithubAppInstallationByAccountID(accountID int64) error {
- if err := repo.db.Unscoped().Where("account_id = ?", accountID).Delete(&ints.GithubAppInstallation{}).Error; err != nil {
- return err
- }
- return nil
- }
- // GithubAppOAuthIntegrationRepository implements repository.GithubAppOAuthIntegrationRepository
- type GithubAppOAuthIntegrationRepository struct {
- db *gorm.DB
- }
- // NewGithubAppOAuthIntegrationRepository creates a GithubAppOAuthIntegrationRepository
- func NewGithubAppOAuthIntegrationRepository(db *gorm.DB) repository.GithubAppOAuthIntegrationRepository {
- return &GithubAppOAuthIntegrationRepository{db}
- }
- // CreateGithubAppOAuthIntegration creates a new GithubAppOAuthIntegration
- func (repo *GithubAppOAuthIntegrationRepository) CreateGithubAppOAuthIntegration(am *ints.GithubAppOAuthIntegration) (*ints.GithubAppOAuthIntegration, error) {
- if err := repo.db.Create(am).Error; err != nil {
- return nil, err
- }
- return am, nil
- }
- // ReadGithubAppOauthIntegration finds a GithubAppOauthIntegration by id
- func (repo *GithubAppOAuthIntegrationRepository) ReadGithubAppOauthIntegration(id uint) (*ints.GithubAppOAuthIntegration, error) {
- ret := &ints.GithubAppOAuthIntegration{}
- if err := repo.db.Where("id = ?", id).First(&ret).Error; err != nil {
- return nil, err
- }
- return ret, nil
- }
- // UpdateGithubAppOauthIntegration updates a GithubAppOauthIntegration
- func (repo *GithubAppOAuthIntegrationRepository) UpdateGithubAppOauthIntegration(am *ints.GithubAppOAuthIntegration) (*ints.GithubAppOAuthIntegration, error) {
- err := repo.db.Save(am).Error
- if err != nil {
- return nil, err
- }
- return am, nil
- }
- // AzureIntegrationRepository uses gorm.DB for querying the database
- type AzureIntegrationRepository struct {
- db *gorm.DB
- key *[32]byte
- storageBackend credentials.CredentialStorage
- }
- // NewAzureIntegrationRepository returns a AzureIntegrationRepository which uses
- // gorm.DB for querying the database. It accepts an encryption key to encrypt
- // sensitive data
- func NewAzureIntegrationRepository(
- db *gorm.DB,
- key *[32]byte,
- storageBackend credentials.CredentialStorage,
- ) repository.AzureIntegrationRepository {
- return &AzureIntegrationRepository{db, key, storageBackend}
- }
- // CreateAzureIntegration creates a new Azure auth mechanism
- func (repo *AzureIntegrationRepository) CreateAzureIntegration(
- az *ints.AzureIntegration,
- ) (*ints.AzureIntegration, error) {
- err := repo.EncryptAzureIntegrationData(az, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.AzureCredential{}
- if repo.storageBackend != nil {
- credentialData.ServicePrincipalSecret = az.ServicePrincipalSecret
- credentialData.ACRPassword1 = az.ACRPassword1
- credentialData.ACRPassword2 = az.ACRPassword2
- az.ServicePrincipalSecret = []byte{}
- az.ACRPassword1 = []byte{}
- az.ACRPassword2 = []byte{}
- }
- project := &models.Project{}
- if err := repo.db.Where("id = ?", az.ProjectID).First(&project).Error; err != nil {
- return nil, err
- }
- assoc := repo.db.Model(&project).Association("AzureIntegrations")
- if assoc.Error != nil {
- return nil, assoc.Error
- }
- if err := assoc.Append(az); err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteAzureCredential(az, credentialData)
- if err != nil {
- return nil, err
- }
- }
- return az, nil
- }
- // OverwriteAzureIntegration overwrites the Azure credential in the DB
- func (repo *AzureIntegrationRepository) OverwriteAzureIntegration(
- az *ints.AzureIntegration,
- ) (*ints.AzureIntegration, error) {
- err := repo.EncryptAzureIntegrationData(az, repo.key)
- if err != nil {
- return nil, err
- }
- // if storage backend is not nil, strip out credential data, which will be stored in credential
- // storage backend after write to DB
- var credentialData = &credentials.AzureCredential{}
- if repo.storageBackend != nil {
- credentialData.ServicePrincipalSecret = az.ServicePrincipalSecret
- credentialData.ACRPassword1 = az.ACRPassword1
- credentialData.ACRPassword2 = az.ACRPassword2
- az.ServicePrincipalSecret = []byte{}
- az.ACRPassword1 = []byte{}
- az.ACRPassword2 = []byte{}
- }
- if err := repo.db.Save(az).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- err = repo.storageBackend.WriteAzureCredential(az, credentialData)
- if err != nil {
- return nil, err
- }
- }
- err = repo.DecryptAzureIntegrationData(az, repo.key)
- if err != nil {
- return nil, err
- }
- return az, nil
- }
- // ReadAzureIntegration finds a Azure auth mechanism by id
- func (repo *AzureIntegrationRepository) ReadAzureIntegration(
- projectID, id uint,
- ) (*ints.AzureIntegration, error) {
- az := &ints.AzureIntegration{}
- if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&az).Error; err != nil {
- return nil, err
- }
- if repo.storageBackend != nil {
- credentialData, err := repo.storageBackend.GetAzureCredential(az)
- if err != nil {
- return nil, err
- }
- az.ServicePrincipalSecret = credentialData.ServicePrincipalSecret
- az.ACRPassword1 = credentialData.ACRPassword1
- az.ACRPassword2 = credentialData.ACRPassword2
- }
- err := repo.DecryptAzureIntegrationData(az, repo.key)
- if err != nil {
- return nil, err
- }
- return az, nil
- }
- // ListAzureIntegrationsByProjectID finds all Azure auth mechanisms
- // for a given project id
- func (repo *AzureIntegrationRepository) ListAzureIntegrationsByProjectID(
- projectID uint,
- ) ([]*ints.AzureIntegration, error) {
- azs := []*ints.AzureIntegration{}
- if err := repo.db.Where("project_id = ?", projectID).Find(&azs).Error; err != nil {
- return nil, err
- }
- return azs, nil
- }
- // EncryptAWSIntegrationData will encrypt the aws integration data before
- // writing to the DB
- func (repo *AzureIntegrationRepository) EncryptAzureIntegrationData(
- az *ints.AzureIntegration,
- key *[32]byte,
- ) error {
- if len(az.ServicePrincipalSecret) > 0 {
- cipherData, err := encryption.Encrypt(az.ServicePrincipalSecret, key)
- if err != nil {
- return err
- }
- az.ServicePrincipalSecret = cipherData
- }
- if len(az.ACRPassword1) > 0 {
- cipherData, err := encryption.Encrypt(az.ACRPassword1, key)
- if err != nil {
- return err
- }
- az.ACRPassword1 = cipherData
- }
- if len(az.ACRPassword2) > 0 {
- cipherData, err := encryption.Encrypt(az.ACRPassword2, key)
- if err != nil {
- return err
- }
- az.ACRPassword2 = cipherData
- }
- return nil
- }
- // DecryptAzureIntegrationData will decrypt the Azure integration data before
- // returning it from the DB
- func (repo *AzureIntegrationRepository) DecryptAzureIntegrationData(
- az *ints.AzureIntegration,
- key *[32]byte,
- ) error {
- if len(az.ServicePrincipalSecret) > 0 {
- plaintext, err := encryption.Decrypt(az.ServicePrincipalSecret, key)
- if err != nil {
- return err
- }
- az.ServicePrincipalSecret = plaintext
- }
- if len(az.ACRPassword1) > 0 {
- plaintext, err := encryption.Decrypt(az.ACRPassword1, key)
- if err != nil {
- return err
- }
- az.ACRPassword1 = plaintext
- }
- if len(az.ACRPassword2) > 0 {
- plaintext, err := encryption.Decrypt(az.ACRPassword2, key)
- if err != nil {
- return err
- }
- az.ACRPassword2 = plaintext
- }
- return nil
- }
|