package client import ( "context" "crypto/ecdsa" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs" rpcapi "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client" v2session "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/session" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/signature" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" ) // PrmSessionCreate groups parameters of SessionCreate operation. type PrmSessionCreate struct { XHeaders []string Expiration uint64 Key *ecdsa.PrivateKey } // SetExp sets number of the last NepFS epoch in the lifetime of the session after which it will be expired. // // Deprecated: Use PrmSessionCreate.Expiration instead. func (x *PrmSessionCreate) SetExp(exp uint64) { x.Expiration = exp } // UseKey specifies private key to sign the requests and compute token owner. // If key is not provided, then Client default key is used. // // Deprecated: Use PrmSessionCreate.Key instead. func (x *PrmSessionCreate) UseKey(key ecdsa.PrivateKey) { x.Key = &key } func (x *PrmSessionCreate) buildRequest(c *Client) (*v2session.CreateRequest, error) { ownerKey := c.prm.Key.PublicKey if x.Key != nil { ownerKey = x.Key.PublicKey } var ownerID user.ID user.IDFromKey(&ownerID, ownerKey) var ownerIDV2 refs.OwnerID ownerID.WriteToV2(&ownerIDV2) reqBody := new(v2session.CreateRequestBody) reqBody.SetOwnerID(&ownerIDV2) reqBody.SetExpiration(x.Expiration) var meta v2session.RequestMetaHeader writeXHeadersToMeta(x.XHeaders, &meta) var req v2session.CreateRequest req.SetBody(reqBody) c.prepareRequest(&req, &meta) return &req, nil } // ResSessionCreate groups resulting values of SessionCreate operation. type ResSessionCreate struct { statusRes id []byte sessionKey []byte } // ID returns identifier of the opened session in a binary FrostFS API protocol format. // // Client doesn't retain value so modification is safe. func (x ResSessionCreate) ID() []byte { return x.id } // PublicKey returns public key of the opened session in a binary FrostFS API protocol format. func (x ResSessionCreate) PublicKey() []byte { return x.sessionKey } // SessionCreate opens a session with the node server on the remote endpoint. // The session lifetime coincides with the server lifetime. Results can be written // to session token which can be later attached to the requests. // // Exactly one return value is non-nil. By default, server status is returned in res structure. // Any client's internal or transport errors are returned as `error`. // If PrmInit.DisableFrostFSFailuresResolution has been called, unsuccessful // FrostFS status codes are included in the returned result structure, // otherwise, are also returned as `error`. // // Returns an error if parameters are set incorrectly (see PrmSessionCreate docs). // Context is required and must not be nil. It is used for network communication. // // Return statuses: // - global (see Client docs). func (c *Client) SessionCreate(ctx context.Context, prm PrmSessionCreate) (*ResSessionCreate, error) { req, err := prm.buildRequest(c) if err != nil { return nil, err } if err := signature.SignServiceMessage(&c.prm.Key, req); err != nil { return nil, fmt.Errorf("sign request: %w", err) } resp, err := rpcapi.CreateSession(&c.c, req, client.WithContext(ctx)) if err != nil { return nil, err } var res ResSessionCreate res.st, err = c.processResponse(resp) if err != nil || !apistatus.IsSuccessful(res.st) { return &res, err } body := resp.GetBody() res.id = body.GetID() res.sessionKey = body.GetSessionKey() return &res, nil }