Error 400 oauth2 google cloud storage - go lang - go

// datastore1
package main
import (
"fmt"
"io/ioutil"
"log"
"time"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/cloud"
"google.golang.org/cloud/datastore"
)
const (
// ScopeDatastore grants permissions to view and/or manage datastore entities
copeDatastore = "https://www.googleapis.com/auth/datastore"
// ScopeUserEmail grants permission to view the user's email address.
// It is required to access the datastore.
ScopeUserEmail = "https://www.googleapis.com/auth/userinfo.email"
)
type ehrEntity struct {
email *datastore.Key
firstname string
lastname string
address string
age int8
dateofbirth time.Time
sex bool
}
func getCtx() *datastore.Client {
// Initialize an authorized transport with Google Developers Console
// JSON key. Read the google package examples to learn more about
// different authorization flows you can use.
// http://godoc.org/golang.org/x/oauth2/google
jsonKey, err := ioutil.ReadFile("filename.json")
opts, err := google.JWTConfigFromJSON(
jsonKey,
datastore.ScopeDatastore,
datastore.ScopeUserEmail,
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx", cloud.WithTokenSource(opts.TokenSource(ctx)))
if err != nil {
log.Fatal(err)
}
// Use the context (see other examples)
return client
}
func ExampleGet() {
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx")
if err != nil {
log.Fatal(err)
}
key := datastore.NewKey(ctx, "User", "tluu#abc.com", 0, nil)
ehr := ehrEntity{
nil,
"tri",
"luu",
"addr1",
20,
time.Date(2009, time.January, 10, 23, 0, 0, 0, time.UTC),
false}
if err := client.Get(ctx, key, ehr); err != nil {
log.Fatal(err)
}
}
func main() {
getCtx()
fmt.Println("Pass authentication")
ExampleGet()
}
When I run go file, It return error follow:
Pass authentication (Pass getCtx() function).
Error in ExampleGet()
May be at
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx")
if err != nil {
log.Fatal(err)
}
Error:
2016/01/09 22:08:43 Post https://www.googleapis.com/datastore/v1beta2/datasets/xxxx/lookup: oauth2: cannot fetch token: 400 Bad Request
Response: {
"error" : "invalid_grant"
}
How to resolve this error?

This appears to have worked for me.
If you are on linux try the following:
1. apt-get update
2. apt-get install ntp
3. /etc/init.d/ntp restart

Related

Is it possible to send email from localhost?

My goal is to create a SMTP server to send an email from noreply#myname.com containing OTP.
The problem is, I code on my personal computer. Therefore, no public address or domain, yet. I tried to send email to myname#gmail.com, but I can't find it on the spam, or the inbox folders.
What I've did:
run the go-smtp server. $ go run cmd/server/main.go
run the go-smtp client. $ go run cmd/client/main.go
The go-smtp server output
(base) jason#Jasons-Mac-mini server % go run main.go
2022/09/23 13:35:38 Starting server at :1025
2022/09/23 13:56:06 Mail from: test#localhost
2022/09/23 13:56:06 Rcpt to: // email redacted for stackoverflow
2022/09/23 13:56:06 Data: This is the email body
The go-smtp client output
(base) jason#Jasons-Mac-mini client % go run main.go
2022/09/23 13:56:06 Mail sent! time elapsed: 1.988625ms
cmd/client/main.go
package main
import (
"fmt"
"log"
"time"
"github.com/emersion/go-smtp"
)
func main() {
start := time.Now()
// Connect to the remote SMTP server.
c, err := smtp.Dial("localhost:1025")
if err != nil {
log.Fatal(err)
}
// Set the sender and recipient first
if err := c.Mail("test#localhost", nil); err != nil {
log.Fatal(err)
}
if err := c.Rcpt("jasonong713#gmail.com"); err != nil {
log.Fatal(err)
}
// Send the email body.
wc, err := c.Data()
if err != nil {
log.Fatal(err)
}
_, err = fmt.Fprintf(wc, "This is the email body")
if err != nil {
log.Fatal(err)
}
err = wc.Close()
if err != nil {
log.Fatal(err)
}
// Send the QUIT command and close the connection.
err = c.Quit()
if err != nil {
log.Fatal(err)
}
log.Println("Mail sent! time elapsed:", time.Since(start))
}
cmd/server/main.go
package main
import (
"log"
"time"
"github.com/emersion/go-smtp"
"github.com/godataid/sendemail"
)
func main() {
be := &sendemail.Backend{}
s := smtp.NewServer(be)
s.Addr = ":1025"
s.Domain = "localhost"
s.ReadTimeout = 10 * time.Second
s.WriteTimeout = 10 * time.Second
s.MaxMessageBytes = 1024 * 1024
s.MaxRecipients = 50
s.AllowInsecureAuth = true
log.Println("Starting server at", s.Addr)
if err := s.ListenAndServe(); err != nil {
log.Fatalln(err)
}
}
backend.go
package sendemail
import "github.com/emersion/go-smtp"
type Backend struct{}
// Authenticate a user. Return smtp.ErrAuthUnsupported if you don't want to
// support this.
func (be *Backend) Login(state *smtp.ConnectionState, username, password string) (smtp.Session, error) {
return nil, smtp.ErrAuthUnsupported
}
// Called if the client attempts to send mail without logging in first.
// Return smtp.ErrAuthRequired if you don't want to support this.
func (be *Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error) {
return &Session{}, nil
}
session.go
package sendemail
import (
"io"
"log"
"github.com/emersion/go-smtp"
)
type Session struct{}
// Discard currently processed message.
func (s *Session) Reset() {}
// Free all resources associated with session.
func (s *Session) Logout() error {
return nil
}
// Set return path for currently processed message.
func (s *Session) Mail(from string, opts smtp.MailOptions) error {
log.Println("Mail from:", from)
return nil
}
// Add recipient for currently processed message.
func (s *Session) Rcpt(to string) error {
log.Println("Rcpt to:", to)
return nil
}
// Set currently processed message contents and send it.
func (s *Session) Data(r io.Reader) error {
if b, err := io.ReadAll(r); err != nil {
return err
} else {
log.Println("Data:", string(b))
}
return nil
}

Google Cloud Vertex AI with Golang: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found)

I have a Vertex AI model deployed on an endpoint and want to do some prediction from my app in Golang.
To do this I create code inspired by this example : https://cloud.google.com/go/docs/reference/cloud.google.com/go/aiplatform/latest/apiv1?hl=en
const file = "MY_BASE64_IMAGE"
func main() {
ctx := context.Background()
c, err := aiplatform.NewPredictionClient(cox)
if err != nil {
log.Printf("QueryVertex NewPredictionClient - Err:%s", err)
}
defer c.Close()
parameters, err := structpb.NewValue(map[string]interface{}{
"confidenceThreshold": 0.2,
"maxPredictions": 5,
})
if err != nil {
log.Printf("QueryVertex structpb.NewValue parameters - Err:%s", err)
}
instance, err := structpb.NewValue(map[string]interface{}{
"content": file,
})
if err != nil {
log.Printf("QueryVertex structpb.NewValue instance - Err:%s", err)
}
reqP := &aiplatformpb.PredictRequest{
Endpoint: "projects/PROJECT_ID/locations/LOCATION_ID/endpoints/ENDPOINT_ID",
Instances: []*structpb.Value{instance},
Parameters: parameters,
}
resp, err := c.Predict(cox, reqP)
if err != nil {
log.Printf("QueryVertex Predict - Err:%s", err)
}
log.Printf("QueryVertex Res:%+v", resp)
}
I put the path to my service account JSON file on GOOGLE_APPLICATION_CREDENTIALS environment variable.
But when I run my test app I obtain this error message:
QueryVertex Predict - Err:rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "text/html; charset=UTF-8"
QueryVertex Res:<nil>
As #DazWilkin suggested, configure the client option to specify the specific regional endpoint with a port 443:
option.WithEndpoint("<region>-aiplatform.googleapis.com:443")
Try like below:
func main() {
ctx := context.Background()
c, err := aiplatform.NewPredictionClient(
ctx,
option.WithEndpoint("<region>-aiplatform.googleapis.com:443"),
)
if err != nil {
log.Printf("QueryVertex NewPredictionClient - Err:%s", err)
}
defer c.Close()
.
.
I'm unfamiliar with Google's (Vertex?) AI Platform and unable to test this hypothesis but it appears that the API uses location-specific endpoints.
Can you try configuring the client's ClientOption to specify the specific regional endpoint, i.e.:
url := fmt.Sprintf("https://%s-aiplatform.googleapis.com", location)
opts := []option.ClientOption{
option.WithEndpoint(url),
}
And:
package main
import (
"context"
"fmt"
"log"
"os"
aiplatform "cloud.google.com/go/aiplatform/apiv1"
"google.golang.org/api/option"
aiplatformpb "google.golang.org/genproto/googleapis/cloud/aiplatform/v1"
"google.golang.org/protobuf/types/known/structpb"
)
const file = "MY_BASE64_IMAGE"
func main() {
// Values from the environment
project := os.Getenv("PROJECT")
location := os.Getenv("LOCATION")
endpoint := os.Getenv("ENDPOINT")
ctx := context.Background()
// Configure the client with a region-specific endpoint
url := fmt.Sprintf("https://%s-aiplatform.googleapis.com", location)
opts := []option.ClientOption{
option.WithEndpoint(url),
}
c, err := aiplatform.NewPredictionClient(ctx, opts...)
if err != nil {
log.Fatal(err)
}
defer c.Close()
parameters, err := structpb.NewValue(map[string]interface{}{
"confidenceThreshold": 0.2,
"maxPredictions": 5,
})
if err != nil {
log.Fatal(err)
}
instance, err := structpb.NewValue(map[string]interface{}{
"content": file,
})
if err != nil {
log.Printf("QueryVertex structpb.NewValue instance - Err:%s", err)
}
rqst := &aiplatformpb.PredictRequest{
Endpoint: fmt.Sprintf("projects/%s/locations/%s/endpoints/%s",
project,
location,
endpoint,
),
Instances: []*structpb.Value{
instance,
},
Parameters: parameters,
}
resp, err := c.Predict(ctx, rqst)
if err != nil {
log.Fatal(err)
}
log.Printf("QueryVertex Res:%+v", resp)
}
Try to do something like this
[...]
url := fmt.Sprintf("%s-aiplatform.googleapis.com:443", location)
[..]

How can I use the AWS SDK v2 for Go with DigitalOcean Spaces?

I'm trying to use the AWS v2 SDK for Go to list all objects in a given bucket on DigitalOcean Spaces. Their documentation gives examples of how to use the v1 SDK to do this, but my app uses v2. I know I could technically use both, but I'd rather not if possible.
Here's what I've got so far:
package main
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: "https://sfo2.digitaloceanspaces.com",
}, nil
})
cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithRegion("us-east-1"),
config.WithEndpointResolverWithOptions(customResolver),
config.WithCredentialsProvider(aws.AnonymousCredentials{}),
)
if err != nil {
fmt.Println(err)
}
s3Client := s3.NewFromConfig(cfg)
var continuationToken *string
continuationToken = nil
for {
output, err := s3Client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
Bucket: aws.String("stats"),
ContinuationToken: continuationToken},
)
if err != nil {
fmt.Println(err)
}
for _, obj := range output.Contents {
fmt.Println(obj)
}
if output.IsTruncated == false {
break
}
continuationToken = output.ContinuationToken
}
}
This is the error I'm getting:
operation error S3: ListObjectsV2, https response error StatusCode: 400, RequestID: tx0000000000000051339d4-00620701db-2174fe1c-sfo2a, HostID: 2174fe1c-sfo2a-sfo, api error InvalidArgument: UnknownError
The error seems to indicate there's something wrong with my request but I don't know what.
For pagination i think you need to do it via a pagination function
like this
// Create the Paginator for the ListObjectsV2 operation.
p := s3.NewListObjectsV2Paginator(client, params, func(o *s3.ListObjectsV2PaginatorOptions) {
if v := int32(maxKeys); v != 0 {
o.Limit = v
}
})
Here's a fully working example I'm using to read from a digital ocean spaces bucket
package s3
import (
"context"
"os"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func read(ctx context.Context) error {
// Define the parameters for the session you want to create.
spacesKey := os.Getenv("SPACES_KEY")
spacesSecret := os.Getenv("SPACES_SECRET")
creds := credentials.NewStaticCredentialsProvider(spacesKey, spacesSecret, "")
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: "https://sfo3.digitaloceanspaces.com",
}, nil
})
cfg, err := config.LoadDefaultConfig(ctx,
config.WithRegion("us-east-1"),
config.WithCredentialsProvider(creds),
config.WithEndpointResolverWithOptions(customResolver))
if err != nil {
return err
}
// Create an Amazon S3 service client
awsS3Client := s3.NewFromConfig(cfg)
input := &s3.GetObjectInput{
Bucket: aws.String("zeus-fyi"),
Key: aws.String("test.txt"),
}
downloader := manager.NewDownloader(awsS3Client)
newFile, err := os.Create("./local-test.txt")
if err != nil {
return err
}
defer newFile.Close()
_, err = downloader.Download(ctx, newFile, input)
if err != nil {
return err
}
return err
}

Google Cloud "translate.NewClient: dialing: google: could not find default credentials"

I am trying to use Google Translate API on Windows(my own computer). I have an issue with default credentials.
Error: **translate.NewClient: dialing: google: could not find default credentials.
I have enough balance in google cloud.
I started Translate API. (API Enabled)
I added $env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
package main
import (
"context"
"fmt"
"log"
"cloud.google.com/go/storage"
"cloud.google.com/go/translate"
"golang.org/x/text/language"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
)
func translateTextWithModel(targetLanguage, text, model string) (string, error) {
// targetLanguage := "ja"
// text := "The Go Gopher is cute"
// model := "nmt"
ctx := context.Background()
lang, err := language.Parse(targetLanguage)
if err != nil {
return "", fmt.Errorf("language.Parse: %v", err)
}
client, err := translate.NewClient(ctx)
if err != nil {
return "", fmt.Errorf("translate.NewClient: %v", err)
}
defer client.Close()
resp, err := client.Translate(ctx, []string{text}, lang, &translate.Options{
Model: model, // Either "nmt" or "base".
})
if err != nil {
return "", fmt.Errorf("Translate: %v", err)
}
if len(resp) == 0 {
return "", nil
}
return resp[0].Text, nil
}
func main() {
Json_path := "C:/Users/Mels/Documents/GoogleTools/cred-9dfos6bb49f.json"
ProjectID := "cred"
fmt.Println("RUNNING...")
explicit(Json_path, ProjectID)
fmt.Println(translateTextWithModel("ja", "Hello World", "nmt"))
}
// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
ctx := context.Background()
client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
if err != nil {
log.Fatal(err)
}
defer client.Close()
fmt.Println("Buckets:")
it := client.Buckets(ctx, projectID)
for {
battrs, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(battrs.Name)
}
}
JSON File
{
"type": "service_account",
"project_id": "xxxxxxx",
"private_key_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----XXXXXXXX-----END PRIVATE KEY-----\n",
"client_email": "xxxxxx#xxxxxx.iam.gserviceaccount.com",
"client_id": "11111111111",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxx%xxxxxxx.iam.gserviceaccount.com"
}
If the library can't find the default credentials, then you can try to create a client with the credentials path.
Even if this might not be the best option for you (although I prefer it to the env variable), it'll help you diagnose the issue a little better.
In order to create the client with a path to the credentials file, you need to import google.golang.org/api/option, and create the client with the WithCredentialsFile option. Note in the docs that the client can be created with additional options:
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error)
A somewhat more complete example on how to create a client with options would be the following (apply the required parts to your current code as needed):
package main
import (
"cloud.google.com/go/translate"
"context"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
client, err := translate.NewClient(ctx, option.WithCredentialsFile("/path/to/your/file"))
if err != nil {
// TODO: handle error.
}
// Use the client.
// Close the client when finished.
if err := client.Close(); err != nil {
// TODO: handle error.
}
}
(This is just a copy of the example in the docs with the additional option included.)
I solved the issue. I downloaded "google cloud shell SDK" and I used "gcloud auth application-default login" code. SDK provides a JSON file and I replaced it with new JSON file.
I do not recommend cloud.google.com/translate/docs/setup instructions. Direct use Google cloud SDK.

How to achieve automatic authentication using GCE Go client oauth2 authentication

This code is on the basis of golang.org/x/oauth2 example test. I am trying to get instance information from Google Compute Engine using Go client. Do I have to use oauth2 authentication? There is a generated link after Visit the URL for the auth dialog:
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=xxx&redirect_uri=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&state=state
and it redirect to https://www.googleapis.com/auth/compute which shows a 'compute'.
How do I achieve automatic authentication?
package main
import (
"context"
"fmt"
"log"
"golang.org/x/oauth2"
"google.golang.org/api/compute/v1"
)
type GCE struct {
*compute.Service
}
var ctx = context.Background()
func initGCE() *GCE {
conf := &oauth2.Config{
ClientID: "xxx",
ClientSecret: "xxx",
Scopes: []string{compute.ComputeScope},
Endpoint: oauth2.Endpoint{
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://accounts.google.com/o/oauth2/auth",
},
RedirectURL: "https://www.googleapis.com/auth/compute",
}
url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline)
fmt.Printf("Visit the URL for the auth dialog: %v", url)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatal(err)
}
tok, err := conf.Exchange(ctx, code)
if err != nil {
log.Fatal(err)
}
service, err := compute.New(conf.Client(ctx, tok))
if err != nil {
log.Fatal(err)
}
return &GCE{service}
}
func (g *GCE) Instance() {
project := "arctic-cyclist-189707"
zone := "us-east1-b"
instance := "centos7"
resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
fmt.Println(err)
return
} else {
fmt.Printf("%#v\n", resp)
}
}
Solved by using code example
https://cloud.google.com/compute/docs/reference/latest/instances/get#examples
just set "GOOGLE_APPLICATION_CREDENTIALS" environment varibles as google.DefaultClient() requires.
package main
import (
"context"
"fmt"
"log"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
)
type GCE struct {
*compute.Service
}
var ctx = context.Background()
func initGCE() *GCE {
c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
if err != nil {
log.Fatal(err)
}
computeService, err := compute.New(c)
if err != nil {
log.Fatal(err)
}
return &GCE{computeService}
}
func (g *GCE) Instance(project, zone, instance string) {
resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", resp)
}
Thanks for your reply.

Resources