Explorar o código

update models to make postgres compatible

Alexander Belanger %!s(int64=5) %!d(string=hai) anos
pai
achega
093eb46509

+ 15 - 0
go.sum

@@ -87,6 +87,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
+github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
 github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
 github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
@@ -716,8 +717,10 @@ github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1/go.mod h1:cO
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/instrumenta/kubeval v0.0.0-20190918223246-8d013ec9fc56/go.mod h1:bpiMYvNpVxWjdJsS0hDRu9TrobT5GfWCZwJseGUstxE=
+github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
 github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
 github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
 github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
 github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
 github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
@@ -725,18 +728,24 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
 github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
 github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
 github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.7.0 h1:pwjzcYyfmz/HQOQlENvG1OcDqauTGaqlVahq934F0/U=
 github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA=
+github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
 github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
 github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
 github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
 github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
 github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
 github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
 github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
 github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.0.5 h1:NUbEWPmCQZbMmYlTjVoNPhc0CfnYyz2bfUAh6A5ZVJM=
 github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
 github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
 github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
 github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
 github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
@@ -744,6 +753,7 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU
 github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
 github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
 github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
+github.com/jackc/pgtype v1.5.0 h1:jzBqRk2HFG2CV4AIwgCI2PwTgm6UUoCAK2ofHHRirtc=
 github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
 github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
@@ -751,6 +761,7 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ
 github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
 github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
 github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
+github.com/jackc/pgx/v4 v4.9.0 h1:6STjDqppM2ROy5p1wNDcsC7zJTjSHeuCsguZmXyzx7c=
 github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms=
 github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
@@ -907,6 +918,7 @@ github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL
 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
+github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA=
 github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
 github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
 github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
@@ -1672,6 +1684,7 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
 gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
@@ -1814,7 +1827,9 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/postgres v1.0.2 h1:mB5JjD4QglbCTdMT1aZDxQzHr87XDK1qh0MKIU3P96g=
 gorm.io/driver/postgres v1.0.2/go.mod h1:FvRSYfBI9jEp6ZSjlpS9qNcSjxwYxFc03UOTrHdvvYA=
+gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc=
 gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c=
 gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
 gorm.io/gorm v1.20.2 h1:bZzSEnq7NDGsrd+n3evOOedDrY5oLM5QPlCjZJUK2ro=

+ 17 - 17
internal/forms/action.go

@@ -99,44 +99,44 @@ func (sar *ServiceAccountActionResolver) PopulateServiceAccount(
 		sar.SA.ClientKeyData = authInfo.ClientKeyData
 	}
 
-	if authInfo.Token != "" {
-		sar.SA.Token = authInfo.Token
+	if len(authInfo.Token) > 0 {
+		sar.SA.Token = []byte(authInfo.Token)
 	}
 
-	if authInfo.Username != "" {
-		sar.SA.Username = authInfo.Username
+	if len(authInfo.Username) > 0 {
+		sar.SA.Username = []byte(authInfo.Username)
 	}
 
-	if authInfo.Password != "" {
-		sar.SA.Password = authInfo.Password
+	if len(authInfo.Password) > 0 {
+		sar.SA.Password = []byte(authInfo.Password)
 	}
 
 	if authInfo.AuthProvider != nil && authInfo.AuthProvider.Name == "oidc" {
 		if url, ok := authInfo.AuthProvider.Config["idp-issuer-url"]; ok {
-			sar.SA.OIDCIssuerURL = url
+			sar.SA.OIDCIssuerURL = []byte(url)
 		}
 
 		if clientID, ok := authInfo.AuthProvider.Config["client-id"]; ok {
-			sar.SA.OIDCClientID = clientID
+			sar.SA.OIDCClientID = []byte(clientID)
 		}
 
 		if clientSecret, ok := authInfo.AuthProvider.Config["client-secret"]; ok {
-			sar.SA.OIDCClientSecret = clientSecret
+			sar.SA.OIDCClientSecret = []byte(clientSecret)
 		}
 
 		if caData, ok := authInfo.AuthProvider.Config["idp-certificate-authority-data"]; ok {
 			// based on the implementation, the oidc plugin expects the data to be base64 encoded,
 			// which means we will not decode it here
 			// reference: https://github.com/kubernetes/kubernetes/blob/9dfb4c876bfca7a5ae84259fae2bc337ed90c2d7/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc.go#L135
-			sar.SA.OIDCCertificateAuthorityData = caData
+			sar.SA.OIDCCertificateAuthorityData = []byte(caData)
 		}
 
 		if idToken, ok := authInfo.AuthProvider.Config["id-token"]; ok {
-			sar.SA.OIDCIDToken = idToken
+			sar.SA.OIDCIDToken = []byte(idToken)
 		}
 
 		if refreshToken, ok := authInfo.AuthProvider.Config["refresh-token"]; ok {
-			sar.SA.OIDCRefreshToken = refreshToken
+			sar.SA.OIDCRefreshToken = []byte(refreshToken)
 		}
 	}
 
@@ -254,7 +254,7 @@ func (oida *OIDCIssuerDataAction) PopulateServiceAccount(
 	// based on the implementation, the oidc plugin expects the data to be base64 encoded,
 	// which means we will not decode it here
 	// reference: https://github.com/kubernetes/kubernetes/blob/9dfb4c876bfca7a5ae84259fae2bc337ed90c2d7/staging/src/k8s.io/client-go/plugin/pkg/client/auth/oidc/oidc.go#L135
-	oida.ServiceAccountActionResolver.SA.OIDCCertificateAuthorityData = oida.OIDCIssuerCAData
+	oida.ServiceAccountActionResolver.SA.OIDCCertificateAuthorityData = []byte(oida.OIDCIssuerCAData)
 
 	return nil
 }
@@ -275,7 +275,7 @@ func (tda *TokenDataAction) PopulateServiceAccount(
 		return err
 	}
 
-	tda.ServiceAccountActionResolver.SA.Token = tda.TokenData
+	tda.ServiceAccountActionResolver.SA.Token = []byte(tda.TokenData)
 
 	return nil
 }
@@ -319,9 +319,9 @@ func (akda *AWSDataAction) PopulateServiceAccount(
 		return err
 	}
 
-	akda.ServiceAccountActionResolver.SA.AWSAccessKeyID = akda.AWSAccessKeyID
-	akda.ServiceAccountActionResolver.SA.AWSSecretAccessKey = akda.AWSSecretAccessKey
-	akda.ServiceAccountActionResolver.SA.AWSClusterID = akda.AWSClusterID
+	akda.ServiceAccountActionResolver.SA.AWSAccessKeyID = []byte(akda.AWSAccessKeyID)
+	akda.ServiceAccountActionResolver.SA.AWSSecretAccessKey = []byte(akda.AWSSecretAccessKey)
+	akda.ServiceAccountActionResolver.SA.AWSClusterID = []byte(akda.AWSClusterID)
 
 	return nil
 }

+ 4 - 4
internal/forms/action_test.go

@@ -327,7 +327,7 @@ func TestPopulateServiceAccountTokenDataAction(t *testing.T) {
 		t.Errorf("service account auth mechanism is not %s\n", models.Bearer)
 	}
 
-	if sa.Token != tokenData {
+	if string(sa.Token) != tokenData {
 		t.Errorf("service account token data is wrong: expected %s, got %s\n",
 			tokenData, sa.Token)
 	}
@@ -438,17 +438,17 @@ func TestPopulateServiceAccountAWSKeyDataAction(t *testing.T) {
 		t.Errorf("service account auth mechanism is not %s\n", models.AWS)
 	}
 
-	if sa.AWSAccessKeyID != "ALSDKJFADSF" {
+	if string(sa.AWSAccessKeyID) != "ALSDKJFADSF" {
 		t.Errorf("service account aws access key id is wrong: expected %s, got %s\n",
 			"ALSDKJFADSF", sa.AWSAccessKeyID)
 	}
 
-	if sa.AWSSecretAccessKey != "ASDLFKJALSDKFJ" {
+	if string(sa.AWSSecretAccessKey) != "ASDLFKJALSDKFJ" {
 		t.Errorf("service account aws access secret key is wrong: expected %s, got %s\n",
 			"ASDLFKJALSDKFJ", sa.AWSSecretAccessKey)
 	}
 
-	if sa.AWSClusterID != "cluster-test" {
+	if string(sa.AWSClusterID) != "cluster-test" {
 		t.Errorf("service account aws cluster id is wrong: expected %s, got %s\n",
 			"cluster-test", sa.AWSClusterID)
 	}

+ 16 - 16
internal/kubernetes/kubeconfig.go

@@ -332,20 +332,20 @@ func createRawConfigFromServiceAccount(
 		authInfoMap[authInfoName].ClientCertificateData = sa.ClientCertificateData
 		authInfoMap[authInfoName].ClientKeyData = sa.ClientKeyData
 	case models.Basic:
-		authInfoMap[authInfoName].Username = sa.Username
-		authInfoMap[authInfoName].Password = sa.Password
+		authInfoMap[authInfoName].Username = string(sa.Username)
+		authInfoMap[authInfoName].Password = string(sa.Password)
 	case models.Bearer:
-		authInfoMap[authInfoName].Token = sa.Token
+		authInfoMap[authInfoName].Token = string(sa.Token)
 	case models.OIDC:
 		authInfoMap[authInfoName].AuthProvider = &api.AuthProviderConfig{
 			Name: "oidc",
 			Config: map[string]string{
-				"idp-issuer-url":                 sa.OIDCIssuerURL,
-				"client-id":                      sa.OIDCClientID,
-				"client-secret":                  sa.OIDCClientSecret,
-				"idp-certificate-authority-data": sa.OIDCCertificateAuthorityData,
-				"id-token":                       sa.OIDCIDToken,
-				"refresh-token":                  sa.OIDCRefreshToken,
+				"idp-issuer-url":                 string(sa.OIDCIssuerURL),
+				"client-id":                      string(sa.OIDCClientID),
+				"client-secret":                  string(sa.OIDCClientSecret),
+				"idp-certificate-authority-data": string(sa.OIDCCertificateAuthorityData),
+				"id-token":                       string(sa.OIDCIDToken),
+				"refresh-token":                  string(sa.OIDCRefreshToken),
 			},
 		}
 	case models.GCP:
@@ -392,8 +392,8 @@ func getGCPToken(
 	updateTokenCache UpdateTokenCacheFunc,
 ) (string, error) {
 	// check the token cache for a non-expired token
-	if tok := sa.TokenCache.Token; !sa.TokenCache.IsExpired() && tok != "" {
-		return tok, nil
+	if tok := sa.TokenCache.Token; !sa.TokenCache.IsExpired() && len(tok) > 0 {
+		return string(tok), nil
 	}
 
 	creds, err := google.CredentialsFromJSON(
@@ -423,8 +423,8 @@ func getAWSToken(
 	updateTokenCache UpdateTokenCacheFunc,
 ) (string, error) {
 	// check the token cache for a non-expired token
-	if tok := sa.TokenCache.Token; !sa.TokenCache.IsExpired() && tok != "" {
-		return tok, nil
+	if tok := sa.TokenCache.Token; !sa.TokenCache.IsExpired() && len(tok) > 0 {
+		return string(tok), nil
 	}
 
 	generator, err := token.NewGenerator(false, false)
@@ -437,8 +437,8 @@ func getAWSToken(
 		SharedConfigState: session.SharedConfigEnable,
 		Config: aws.Config{
 			Credentials: credentials.NewStaticCredentials(
-				sa.AWSAccessKeyID,
-				sa.AWSSecretAccessKey,
+				string(sa.AWSAccessKeyID),
+				string(sa.AWSSecretAccessKey),
 				"",
 			),
 		},
@@ -450,7 +450,7 @@ func getAWSToken(
 
 	tok, err := generator.GetWithOptions(&token.GetTokenOptions{
 		Session:   sess,
-		ClusterID: sa.AWSClusterID,
+		ClusterID: string(sa.AWSClusterID),
 	})
 
 	if err != nil {

+ 2 - 2
internal/models/repoclient.go

@@ -25,8 +25,8 @@ type RepoClient struct {
 	// All fields below this line are encrypted before storage
 	// ------------------------------------------------------------------
 
-	AccessToken  string `json:"access_token"`
-	RefreshToken string `json:"refresh_token"`
+	AccessToken  []byte `json:"access_token"`
+	RefreshToken []byte `json:"refresh_token"`
 }
 
 // RepoClientExternal is a RepoClient scrubbed of sensitive information to be

+ 14 - 13
internal/models/serviceaccount.go

@@ -105,7 +105,8 @@ type ServiceAccount struct {
 	ImpersonateGroups string `json:"act-as-groups,omitempty"`
 
 	// ------------------------------------------------------------------
-	// All fields below this line are encrypted before storage
+	// All fields below this line are encrypted before storage, so type is
+	// byte.
 	// ------------------------------------------------------------------
 
 	// Certificate data is used by x509 auth mechanisms over TLS
@@ -113,11 +114,11 @@ type ServiceAccount struct {
 	ClientKeyData         []byte `json:"client-key-data,omitempty"`
 
 	// Token is used for bearer-token auth mechanisms
-	Token string `json:"token,omitempty"`
+	Token []byte `json:"token,omitempty"`
 
 	// Username/Password for basic authentication to a cluster
-	Username string `json:"username,omitempty"`
-	Password string `json:"password,omitempty"`
+	Username []byte `json:"username,omitempty"`
+	Password []byte `json:"password,omitempty"`
 
 	// TokenCache is a cache for bearer tokens with an expiry time
 	// Used by GCP and AWS mechanisms
@@ -127,17 +128,17 @@ type ServiceAccount struct {
 	GCPKeyData []byte `json:"gcp_key_data"`
 
 	// AWS data
-	AWSAccessKeyID     string `json:"aws_access_key_id"`
-	AWSSecretAccessKey string `json:"aws_secret_access_key"`
-	AWSClusterID       string `json:"aws_cluster_id"`
+	AWSAccessKeyID     []byte `json:"aws_access_key_id"`
+	AWSSecretAccessKey []byte `json:"aws_secret_access_key"`
+	AWSClusterID       []byte `json:"aws_cluster_id"`
 
 	// OIDC-related fields
-	OIDCIssuerURL                string `json:"idp-issuer-url"`
-	OIDCClientID                 string `json:"client-id"`
-	OIDCClientSecret             string `json:"client-secret"`
-	OIDCCertificateAuthorityData string `json:"idp-certificate-authority-data"`
-	OIDCIDToken                  string `json:"id-token"`
-	OIDCRefreshToken             string `json:"refresh-token"`
+	OIDCIssuerURL                []byte `json:"idp-issuer-url"`
+	OIDCClientID                 []byte `json:"client-id"`
+	OIDCClientSecret             []byte `json:"client-secret"`
+	OIDCCertificateAuthorityData []byte `json:"idp-certificate-authority-data"`
+	OIDCIDToken                  []byte `json:"id-token"`
+	OIDCRefreshToken             []byte `json:"refresh-token"`
 }
 
 // ServiceAccountExternal is an external ServiceAccount to be shared over REST

+ 1 - 1
internal/models/tokencache.go

@@ -19,7 +19,7 @@ type TokenCache struct {
 	// All fields below this line are encrypted before storage
 	// ------------------------------------------------------------------
 
-	Token string `json:"access_token"`
+	Token []byte `json:"access_token"`
 }
 
 // IsExpired returns true if a token is expired, false otherwise

+ 2 - 2
internal/repository/gorm/helpers_test.go

@@ -181,8 +181,8 @@ func initRepoClient(tester *tester, t *testing.T) {
 		UserID:       tester.initUsers[0].ID,
 		RepoUserID:   1,
 		Kind:         models.RepoClientGithub,
-		AccessToken:  "accesstoken1234",
-		RefreshToken: "refreshtoken1234",
+		AccessToken:  []byte("accesstoken1234"),
+		RefreshToken: []byte("refreshtoken1234"),
 	}
 
 	rc, err := tester.repo.RepoClient.CreateRepoClient(rc)

+ 12 - 12
internal/repository/gorm/repoclient.go

@@ -81,24 +81,24 @@ func (repo *RepoClientRepository) EncryptRepoClientData(
 	rc *models.RepoClient,
 	key *[32]byte,
 ) error {
-	if rc.AccessToken != "" {
-		cipherData, err := repository.Encrypt([]byte(rc.AccessToken), key)
+	if len(rc.AccessToken) > 0 {
+		cipherData, err := repository.Encrypt(rc.AccessToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		rc.AccessToken = string(cipherData)
+		rc.AccessToken = cipherData
 	}
 
-	if rc.RefreshToken != "" {
-		cipherData, err := repository.Encrypt([]byte(rc.RefreshToken), key)
+	if len(rc.RefreshToken) > 0 {
+		cipherData, err := repository.Encrypt(rc.RefreshToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		rc.RefreshToken = string(cipherData)
+		rc.RefreshToken = cipherData
 	}
 
 	return nil
@@ -110,24 +110,24 @@ func (repo *RepoClientRepository) DecryptRepoClientData(
 	rc *models.RepoClient,
 	key *[32]byte,
 ) error {
-	if rc.AccessToken != "" {
-		plaintext, err := repository.Decrypt([]byte(rc.AccessToken), key)
+	if len(rc.AccessToken) > 0 {
+		plaintext, err := repository.Decrypt(rc.AccessToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		rc.AccessToken = string(plaintext)
+		rc.AccessToken = plaintext
 	}
 
-	if rc.RefreshToken != "" {
-		plaintext, err := repository.Decrypt([]byte(rc.RefreshToken), key)
+	if len(rc.RefreshToken) > 0 {
+		plaintext, err := repository.Decrypt(rc.RefreshToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		rc.RefreshToken = string(plaintext)
+		rc.RefreshToken = plaintext
 	}
 
 	return nil

+ 6 - 6
internal/repository/gorm/repoclient_test.go

@@ -23,8 +23,8 @@ func TestCreateRepoClient(t *testing.T) {
 		UserID:       tester.initUsers[0].ID,
 		RepoUserID:   1,
 		Kind:         models.RepoClientGithub,
-		AccessToken:  "accesstoken1234",
-		RefreshToken: "refreshtoken1234",
+		AccessToken:  []byte("accesstoken1234"),
+		RefreshToken: []byte("refreshtoken1234"),
 	}
 
 	repoClient, err := tester.repo.RepoClient.CreateRepoClient(repoClient)
@@ -50,8 +50,8 @@ func TestCreateRepoClient(t *testing.T) {
 		UserID:       tester.initUsers[0].ID,
 		RepoUserID:   1,
 		Kind:         models.RepoClientGithub,
-		AccessToken:  "accesstoken1234",
-		RefreshToken: "refreshtoken1234",
+		AccessToken:  []byte("accesstoken1234"),
+		RefreshToken: []byte("refreshtoken1234"),
 	}
 
 	copyRepoClient := repoClient
@@ -96,8 +96,8 @@ func TestListRepoClientsByProjectID(t *testing.T) {
 		UserID:       tester.initUsers[0].ID,
 		RepoUserID:   1,
 		Kind:         models.RepoClientGithub,
-		AccessToken:  "accesstoken1234",
-		RefreshToken: "refreshtoken1234",
+		AccessToken:  []byte("accesstoken1234"),
+		RefreshToken: []byte("refreshtoken1234"),
 	}
 
 	copyRepoClient := rcs[0]

+ 81 - 81
internal/repository/gorm/serviceaccount.go

@@ -180,14 +180,14 @@ func (repo *ServiceAccountRepository) ListServiceAccountsByProjectID(
 func (repo *ServiceAccountRepository) UpdateServiceAccountTokenCache(
 	tokenCache *models.TokenCache,
 ) (*models.ServiceAccount, error) {
-	if tok := tokenCache.Token; tok != "" {
-		cipherData, err := repository.Encrypt([]byte(tok), repo.key)
+	if tok := tokenCache.Token; len(tok) > 0 {
+		cipherData, err := repository.Encrypt(tok, repo.key)
 
 		if err != nil {
 			return nil, err
 		}
 
-		tokenCache.Token = string(cipherData)
+		tokenCache.Token = cipherData
 	}
 
 	sa := &models.ServiceAccount{}
@@ -232,34 +232,34 @@ func (repo *ServiceAccountRepository) EncryptServiceAccountData(
 		sa.ClientKeyData = cipherData
 	}
 
-	if sa.Token != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.Token), key)
+	if len(sa.Token) > 0 {
+		cipherData, err := repository.Encrypt(sa.Token, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Token = string(cipherData)
+		sa.Token = cipherData
 	}
 
-	if sa.Username != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.Username), key)
+	if len(sa.Username) > 0 {
+		cipherData, err := repository.Encrypt(sa.Username, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Username = string(cipherData)
+		sa.Username = cipherData
 	}
 
-	if sa.Password != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.Password), key)
+	if len(sa.Password) > 0 {
+		cipherData, err := repository.Encrypt(sa.Password, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Password = string(cipherData)
+		sa.Password = cipherData
 	}
 
 	if len(sa.GCPKeyData) > 0 {
@@ -272,104 +272,104 @@ func (repo *ServiceAccountRepository) EncryptServiceAccountData(
 		sa.GCPKeyData = cipherData
 	}
 
-	if tok := sa.TokenCache.Token; tok != "" {
-		cipherData, err := repository.Encrypt([]byte(tok), key)
+	if tok := sa.TokenCache.Token; len(tok) > 0 {
+		cipherData, err := repository.Encrypt(tok, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.TokenCache.Token = string(cipherData)
+		sa.TokenCache.Token = cipherData
 	}
 
-	if sa.AWSAccessKeyID != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.AWSAccessKeyID), key)
+	if len(sa.AWSAccessKeyID) > 0 {
+		cipherData, err := repository.Encrypt(sa.AWSAccessKeyID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSAccessKeyID = string(cipherData)
+		sa.AWSAccessKeyID = cipherData
 	}
 
-	if sa.AWSSecretAccessKey != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.AWSSecretAccessKey), key)
+	if len(sa.AWSSecretAccessKey) > 0 {
+		cipherData, err := repository.Encrypt(sa.AWSSecretAccessKey, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSSecretAccessKey = string(cipherData)
+		sa.AWSSecretAccessKey = cipherData
 	}
 
-	if sa.AWSClusterID != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.AWSClusterID), key)
+	if len(sa.AWSClusterID) > 0 {
+		cipherData, err := repository.Encrypt(sa.AWSClusterID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSClusterID = string(cipherData)
+		sa.AWSClusterID = cipherData
 	}
 
-	if sa.OIDCIssuerURL != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCIssuerURL), key)
+	if len(sa.OIDCIssuerURL) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCIssuerURL, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCIssuerURL = string(cipherData)
+		sa.OIDCIssuerURL = cipherData
 	}
 
-	if sa.OIDCClientID != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCClientID), key)
+	if len(sa.OIDCClientID) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCClientID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCClientID = string(cipherData)
+		sa.OIDCClientID = cipherData
 	}
 
-	if sa.OIDCClientSecret != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCClientSecret), key)
+	if len(sa.OIDCClientSecret) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCClientSecret, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCClientSecret = string(cipherData)
+		sa.OIDCClientSecret = cipherData
 	}
 
-	if sa.OIDCCertificateAuthorityData != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCCertificateAuthorityData), key)
+	if len(sa.OIDCCertificateAuthorityData) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCCertificateAuthorityData, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCCertificateAuthorityData = string(cipherData)
+		sa.OIDCCertificateAuthorityData = cipherData
 	}
 
-	if sa.OIDCIDToken != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCIDToken), key)
+	if len(sa.OIDCIDToken) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCIDToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCIDToken = string(cipherData)
+		sa.OIDCIDToken = cipherData
 	}
 
-	if sa.OIDCRefreshToken != "" {
-		cipherData, err := repository.Encrypt([]byte(sa.OIDCRefreshToken), key)
+	if len(sa.OIDCRefreshToken) > 0 {
+		cipherData, err := repository.Encrypt(sa.OIDCRefreshToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCRefreshToken = string(cipherData)
+		sa.OIDCRefreshToken = cipherData
 	}
 
 	for i, cluster := range sa.Clusters {
@@ -433,34 +433,34 @@ func (repo *ServiceAccountRepository) DecryptServiceAccountData(
 		sa.ClientKeyData = plaintext
 	}
 
-	if sa.Token != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.Token), key)
+	if len(sa.Token) > 0 {
+		plaintext, err := repository.Decrypt(sa.Token, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Token = string(plaintext)
+		sa.Token = plaintext
 	}
 
-	if sa.Username != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.Username), key)
+	if len(sa.Username) > 0 {
+		plaintext, err := repository.Decrypt(sa.Username, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Username = string(plaintext)
+		sa.Username = plaintext
 	}
 
-	if sa.Password != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.Password), key)
+	if len(sa.Password) > 0 {
+		plaintext, err := repository.Decrypt(sa.Password, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.Password = string(plaintext)
+		sa.Password = plaintext
 	}
 
 	if len(sa.GCPKeyData) > 0 {
@@ -473,104 +473,104 @@ func (repo *ServiceAccountRepository) DecryptServiceAccountData(
 		sa.GCPKeyData = plaintext
 	}
 
-	if tok := sa.TokenCache.Token; tok != "" {
-		plaintext, err := repository.Decrypt([]byte(tok), key)
+	if tok := sa.TokenCache.Token; len(tok) > 0 {
+		plaintext, err := repository.Decrypt(tok, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.TokenCache.Token = string(plaintext)
+		sa.TokenCache.Token = plaintext
 	}
 
-	if sa.AWSAccessKeyID != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.AWSAccessKeyID), key)
+	if len(sa.AWSAccessKeyID) > 0 {
+		plaintext, err := repository.Decrypt(sa.AWSAccessKeyID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSAccessKeyID = string(plaintext)
+		sa.AWSAccessKeyID = plaintext
 	}
 
-	if sa.AWSSecretAccessKey != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.AWSSecretAccessKey), key)
+	if len(sa.AWSSecretAccessKey) > 0 {
+		plaintext, err := repository.Decrypt(sa.AWSSecretAccessKey, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSSecretAccessKey = string(plaintext)
+		sa.AWSSecretAccessKey = plaintext
 	}
 
-	if sa.AWSClusterID != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.AWSClusterID), key)
+	if len(sa.AWSClusterID) > 0 {
+		plaintext, err := repository.Decrypt(sa.AWSClusterID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.AWSClusterID = string(plaintext)
+		sa.AWSClusterID = plaintext
 	}
 
-	if sa.OIDCIssuerURL != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCIssuerURL), key)
+	if len(sa.OIDCIssuerURL) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCIssuerURL, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCIssuerURL = string(plaintext)
+		sa.OIDCIssuerURL = plaintext
 	}
 
-	if sa.OIDCClientID != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCClientID), key)
+	if len(sa.OIDCClientID) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCClientID, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCClientID = string(plaintext)
+		sa.OIDCClientID = plaintext
 	}
 
-	if sa.OIDCClientSecret != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCClientSecret), key)
+	if len(sa.OIDCClientSecret) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCClientSecret, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCClientSecret = string(plaintext)
+		sa.OIDCClientSecret = plaintext
 	}
 
-	if sa.OIDCCertificateAuthorityData != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCCertificateAuthorityData), key)
+	if len(sa.OIDCCertificateAuthorityData) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCCertificateAuthorityData, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCCertificateAuthorityData = string(plaintext)
+		sa.OIDCCertificateAuthorityData = plaintext
 	}
 
-	if sa.OIDCIDToken != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCIDToken), key)
+	if len(sa.OIDCIDToken) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCIDToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCIDToken = string(plaintext)
+		sa.OIDCIDToken = plaintext
 	}
 
-	if sa.OIDCRefreshToken != "" {
-		plaintext, err := repository.Decrypt([]byte(sa.OIDCRefreshToken), key)
+	if len(sa.OIDCRefreshToken) > 0 {
+		plaintext, err := repository.Decrypt(sa.OIDCRefreshToken, key)
 
 		if err != nil {
 			return err
 		}
 
-		sa.OIDCRefreshToken = string(plaintext)
+		sa.OIDCRefreshToken = plaintext
 	}
 
 	for i, cluster := range sa.Clusters {

+ 3 - 3
internal/repository/gorm/serviceaccount_test.go

@@ -359,7 +359,7 @@ func TestUpdateServiceAccountToken(t *testing.T) {
 		AuthMechanism: models.GCP,
 		GCPKeyData:    []byte(`{"key":"data"}`),
 		TokenCache: models.TokenCache{
-			Token:  "token-1",
+			Token:  []byte("token-1"),
 			Expiry: time.Now().Add(-1 * time.Hour),
 		},
 	}
@@ -386,7 +386,7 @@ func TestUpdateServiceAccountToken(t *testing.T) {
 		t.Fatalf("token was not expired\n")
 	}
 
-	sa.TokenCache.Token = "token-2"
+	sa.TokenCache.Token = []byte("token-2")
 	sa.TokenCache.Expiry = time.Now().Add(24 * time.Hour)
 
 	sa, err = tester.repo.ServiceAccount.UpdateServiceAccountTokenCache(&sa.TokenCache)
@@ -412,7 +412,7 @@ func TestUpdateServiceAccountToken(t *testing.T) {
 		t.Fatalf("token was expired\n")
 	}
 
-	if sa.TokenCache.Token != "token-2" {
+	if string(sa.TokenCache.Token) != "token-2" {
 		t.Errorf("incorrect token in cache: expected %s, got %s\n", "token-2", sa.TokenCache.Token)
 	}
 }

+ 1 - 1
server/api/k8s_handler.go

@@ -74,7 +74,7 @@ func (app *App) HandleListNamespaces(w http.ResponseWriter, r *http.Request) {
 func (app *App) updateTokenCache(token string, expiry time.Time) error {
 	_, err := app.repo.ServiceAccount.UpdateServiceAccountTokenCache(
 		&models.TokenCache{
-			Token:  token,
+			Token:  []byte(token),
 			Expiry: expiry,
 		},
 	)

+ 2 - 2
server/api/oauth_github_handler.go

@@ -168,8 +168,8 @@ func (app *App) updateProjectFromToken(projectID uint, userID uint, tok *oauth2.
 		UserID:       userID,
 		RepoUserID:   uint(user.GetID()),
 		Kind:         models.RepoClientGithub,
-		AccessToken:  tok.AccessToken,
-		RefreshToken: tok.RefreshToken,
+		AccessToken:  []byte(tok.AccessToken),
+		RefreshToken: []byte(tok.RefreshToken),
 	}
 
 	repoClient, err = app.repo.RepoClient.CreateRepoClient(repoClient)

+ 2 - 2
server/api/project_handler_test.go

@@ -211,11 +211,11 @@ var createProjectSACandidatesTests = []*projTest{
 						string(sa.OIDCCertificateAuthorityData), "LS0tLS1CRUdJTiBDRVJ=")
 				}
 
-				if sa.OIDCClientID != "porter-api" {
+				if string(sa.OIDCClientID) != "porter-api" {
 					t.Errorf("service account oidc client id is not %s\n", "porter-api")
 				}
 
-				if sa.OIDCIDToken != "token" {
+				if string(sa.OIDCIDToken) != "token" {
 					t.Errorf("service account oidc id token is not %s\n", "token")
 				}
 			},

+ 2 - 2
server/api/repo_handler.go

@@ -164,8 +164,8 @@ func (app *App) githubTokenFromRequest(
 			// TODO -- refresh token is irrelevant at the moment, because the access token
 			// doesn't expire.
 			return &oauth2.Token{
-				AccessToken:  rc.AccessToken,
-				RefreshToken: rc.RefreshToken,
+				AccessToken:  string(rc.AccessToken),
+				RefreshToken: string(rc.RefreshToken),
 				TokenType:    "Bearer",
 			}, nil
 		}