Files
galaxy-game/pkg/transcoder/user.go
T
2026-05-07 00:58:53 +03:00

778 lines
29 KiB
Go

package transcoder
import (
"errors"
"fmt"
"time"
usermodel "galaxy/model/user"
userfbs "galaxy/schema/fbs/user"
flatbuffers "github.com/google/flatbuffers/go"
)
// GetMyAccountRequestToPayload converts usermodel.GetMyAccountRequest to
// FlatBuffers bytes suitable for the authenticated gateway transport.
func GetMyAccountRequestToPayload(request *usermodel.GetMyAccountRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode get my account request payload: request is nil")
}
builder := flatbuffers.NewBuilder(32)
userfbs.GetMyAccountRequestStart(builder)
offset := userfbs.GetMyAccountRequestEnd(builder)
userfbs.FinishGetMyAccountRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToGetMyAccountRequest converts FlatBuffers payload bytes into
// usermodel.GetMyAccountRequest.
func PayloadToGetMyAccountRequest(data []byte) (result *usermodel.GetMyAccountRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode get my account request payload: data is empty")
}
defer recoverUserDecodePanic("decode get my account request payload", &result, &err)
_ = userfbs.GetRootAsGetMyAccountRequest(data, 0)
return &usermodel.GetMyAccountRequest{}, nil
}
// UpdateMyProfileRequestToPayload converts usermodel.UpdateMyProfileRequest to
// FlatBuffers bytes suitable for the authenticated gateway transport.
func UpdateMyProfileRequestToPayload(request *usermodel.UpdateMyProfileRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode update my profile request payload: request is nil")
}
builder := flatbuffers.NewBuilder(128)
displayName := builder.CreateString(request.DisplayName)
userfbs.UpdateMyProfileRequestStart(builder)
userfbs.UpdateMyProfileRequestAddDisplayName(builder, displayName)
offset := userfbs.UpdateMyProfileRequestEnd(builder)
userfbs.FinishUpdateMyProfileRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToUpdateMyProfileRequest converts FlatBuffers payload bytes into
// usermodel.UpdateMyProfileRequest.
func PayloadToUpdateMyProfileRequest(data []byte) (result *usermodel.UpdateMyProfileRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode update my profile request payload: data is empty")
}
defer recoverUserDecodePanic("decode update my profile request payload", &result, &err)
request := userfbs.GetRootAsUpdateMyProfileRequest(data, 0)
return &usermodel.UpdateMyProfileRequest{
DisplayName: string(request.DisplayName()),
}, nil
}
// UpdateMySettingsRequestToPayload converts
// usermodel.UpdateMySettingsRequest to FlatBuffers bytes suitable for the
// authenticated gateway transport.
func UpdateMySettingsRequestToPayload(request *usermodel.UpdateMySettingsRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode update my settings request payload: request is nil")
}
builder := flatbuffers.NewBuilder(128)
preferredLanguage := builder.CreateString(request.PreferredLanguage)
timeZone := builder.CreateString(request.TimeZone)
userfbs.UpdateMySettingsRequestStart(builder)
userfbs.UpdateMySettingsRequestAddPreferredLanguage(builder, preferredLanguage)
userfbs.UpdateMySettingsRequestAddTimeZone(builder, timeZone)
offset := userfbs.UpdateMySettingsRequestEnd(builder)
userfbs.FinishUpdateMySettingsRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToUpdateMySettingsRequest converts FlatBuffers payload bytes into
// usermodel.UpdateMySettingsRequest.
func PayloadToUpdateMySettingsRequest(data []byte) (result *usermodel.UpdateMySettingsRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode update my settings request payload: data is empty")
}
defer recoverUserDecodePanic("decode update my settings request payload", &result, &err)
request := userfbs.GetRootAsUpdateMySettingsRequest(data, 0)
return &usermodel.UpdateMySettingsRequest{
PreferredLanguage: string(request.PreferredLanguage()),
TimeZone: string(request.TimeZone()),
}, nil
}
// AccountResponseToPayload converts usermodel.AccountResponse to FlatBuffers
// bytes suitable for the authenticated gateway transport.
func AccountResponseToPayload(response *usermodel.AccountResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode account response payload: response is nil")
}
builder := flatbuffers.NewBuilder(512)
accountOffset, err := encodeAccount(builder, response.Account)
if err != nil {
return nil, fmt.Errorf("encode account response payload: %w", err)
}
userfbs.AccountResponseStart(builder)
userfbs.AccountResponseAddAccount(builder, accountOffset)
offset := userfbs.AccountResponseEnd(builder)
userfbs.FinishAccountResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToAccountResponse converts FlatBuffers payload bytes into
// usermodel.AccountResponse.
func PayloadToAccountResponse(data []byte) (result *usermodel.AccountResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode account response payload: data is empty")
}
defer recoverUserDecodePanic("decode account response payload", &result, &err)
response := userfbs.GetRootAsAccountResponse(data, 0)
account := response.Account(nil)
if account == nil {
return nil, errors.New("decode account response payload: account is missing")
}
decodedAccount, err := decodeAccount(account)
if err != nil {
return nil, fmt.Errorf("decode account response payload: %w", err)
}
return &usermodel.AccountResponse{Account: decodedAccount}, nil
}
// ErrorResponseToPayload converts usermodel.ErrorResponse to FlatBuffers bytes
// suitable for the authenticated gateway transport.
func ErrorResponseToPayload(response *usermodel.ErrorResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode error response payload: response is nil")
}
builder := flatbuffers.NewBuilder(128)
errorOffset := encodeErrorBody(builder, response.Error)
userfbs.ErrorResponseStart(builder)
userfbs.ErrorResponseAddError(builder, errorOffset)
offset := userfbs.ErrorResponseEnd(builder)
userfbs.FinishErrorResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToErrorResponse converts FlatBuffers payload bytes into
// usermodel.ErrorResponse.
func PayloadToErrorResponse(data []byte) (result *usermodel.ErrorResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode error response payload: data is empty")
}
defer recoverUserDecodePanic("decode error response payload", &result, &err)
response := userfbs.GetRootAsErrorResponse(data, 0)
errorBody := response.Error(nil)
if errorBody == nil {
return nil, errors.New("decode error response payload: error is missing")
}
return &usermodel.ErrorResponse{
Error: usermodel.ErrorBody{
Code: string(errorBody.Code()),
Message: string(errorBody.Message()),
},
}, nil
}
func encodeAccount(builder *flatbuffers.Builder, account usermodel.Account) (flatbuffers.UOffsetT, error) {
entitlementOffset, err := encodeEntitlementSnapshot(builder, account.Entitlement)
if err != nil {
return 0, fmt.Errorf("encode account: %w", err)
}
activeSanctionOffsets := make([]flatbuffers.UOffsetT, len(account.ActiveSanctions))
for index := range account.ActiveSanctions {
activeSanctionOffsets[index], err = encodeActiveSanction(builder, account.ActiveSanctions[index])
if err != nil {
return 0, fmt.Errorf("encode account active sanction %d: %w", index, err)
}
}
var activeSanctionsVector flatbuffers.UOffsetT
if len(activeSanctionOffsets) > 0 {
userfbs.AccountViewStartActiveSanctionsVector(builder, len(activeSanctionOffsets))
for index := len(activeSanctionOffsets) - 1; index >= 0; index-- {
builder.PrependUOffsetT(activeSanctionOffsets[index])
}
activeSanctionsVector = builder.EndVector(len(activeSanctionOffsets))
}
activeLimitOffsets := make([]flatbuffers.UOffsetT, len(account.ActiveLimits))
for index := range account.ActiveLimits {
activeLimitOffsets[index], err = encodeActiveLimit(builder, account.ActiveLimits[index])
if err != nil {
return 0, fmt.Errorf("encode account active limit %d: %w", index, err)
}
}
var activeLimitsVector flatbuffers.UOffsetT
if len(activeLimitOffsets) > 0 {
userfbs.AccountViewStartActiveLimitsVector(builder, len(activeLimitOffsets))
for index := len(activeLimitOffsets) - 1; index >= 0; index-- {
builder.PrependUOffsetT(activeLimitOffsets[index])
}
activeLimitsVector = builder.EndVector(len(activeLimitOffsets))
}
userID := builder.CreateString(account.UserID)
email := builder.CreateString(account.Email)
userName := builder.CreateString(account.UserName)
var displayName flatbuffers.UOffsetT
if account.DisplayName != "" {
displayName = builder.CreateString(account.DisplayName)
}
preferredLanguage := builder.CreateString(account.PreferredLanguage)
timeZone := builder.CreateString(account.TimeZone)
var declaredCountry flatbuffers.UOffsetT
if account.DeclaredCountry != "" {
declaredCountry = builder.CreateString(account.DeclaredCountry)
}
userfbs.AccountViewStart(builder)
userfbs.AccountViewAddUserId(builder, userID)
userfbs.AccountViewAddEmail(builder, email)
userfbs.AccountViewAddUserName(builder, userName)
if displayName != 0 {
userfbs.AccountViewAddDisplayName(builder, displayName)
}
userfbs.AccountViewAddPreferredLanguage(builder, preferredLanguage)
userfbs.AccountViewAddTimeZone(builder, timeZone)
if declaredCountry != 0 {
userfbs.AccountViewAddDeclaredCountry(builder, declaredCountry)
}
userfbs.AccountViewAddEntitlement(builder, entitlementOffset)
if activeSanctionsVector != 0 {
userfbs.AccountViewAddActiveSanctions(builder, activeSanctionsVector)
}
if activeLimitsVector != 0 {
userfbs.AccountViewAddActiveLimits(builder, activeLimitsVector)
}
userfbs.AccountViewAddCreatedAtMs(builder, account.CreatedAt.UTC().UnixMilli())
userfbs.AccountViewAddUpdatedAtMs(builder, account.UpdatedAt.UTC().UnixMilli())
return userfbs.AccountViewEnd(builder), nil
}
func decodeAccount(account *userfbs.AccountView) (usermodel.Account, error) {
entitlement := account.Entitlement(nil)
if entitlement == nil {
return usermodel.Account{}, errors.New("account entitlement is missing")
}
decodedEntitlement, err := decodeEntitlementSnapshot(entitlement)
if err != nil {
return usermodel.Account{}, fmt.Errorf("decode account entitlement: %w", err)
}
createdAt := time.UnixMilli(account.CreatedAtMs()).UTC()
updatedAt := time.UnixMilli(account.UpdatedAtMs()).UTC()
result := usermodel.Account{
UserID: string(account.UserId()),
Email: string(account.Email()),
UserName: string(account.UserName()),
DisplayName: string(account.DisplayName()),
PreferredLanguage: string(account.PreferredLanguage()),
TimeZone: string(account.TimeZone()),
DeclaredCountry: string(account.DeclaredCountry()),
Entitlement: decodedEntitlement,
ActiveSanctions: make([]usermodel.ActiveSanction, 0, account.ActiveSanctionsLength()),
ActiveLimits: make([]usermodel.ActiveLimit, 0, account.ActiveLimitsLength()),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
activeSanction := new(userfbs.ActiveSanction)
for index := 0; index < account.ActiveSanctionsLength(); index++ {
if !account.ActiveSanctions(activeSanction, index) {
return usermodel.Account{}, fmt.Errorf("account active sanction %d is missing", index)
}
decodedSanction, err := decodeActiveSanction(activeSanction)
if err != nil {
return usermodel.Account{}, fmt.Errorf("decode account active sanction %d: %w", index, err)
}
result.ActiveSanctions = append(result.ActiveSanctions, decodedSanction)
}
activeLimit := new(userfbs.ActiveLimit)
for index := 0; index < account.ActiveLimitsLength(); index++ {
if !account.ActiveLimits(activeLimit, index) {
return usermodel.Account{}, fmt.Errorf("account active limit %d is missing", index)
}
decodedLimit, err := decodeActiveLimit(activeLimit)
if err != nil {
return usermodel.Account{}, fmt.Errorf("decode account active limit %d: %w", index, err)
}
result.ActiveLimits = append(result.ActiveLimits, decodedLimit)
}
return result, nil
}
func encodeEntitlementSnapshot(builder *flatbuffers.Builder, snapshot usermodel.EntitlementSnapshot) (flatbuffers.UOffsetT, error) {
actorOffset := encodeActorRef(builder, snapshot.Actor)
planCode := builder.CreateString(snapshot.PlanCode)
source := builder.CreateString(snapshot.Source)
reasonCode := builder.CreateString(snapshot.ReasonCode)
userfbs.EntitlementSnapshotStart(builder)
userfbs.EntitlementSnapshotAddPlanCode(builder, planCode)
userfbs.EntitlementSnapshotAddIsPaid(builder, snapshot.IsPaid)
userfbs.EntitlementSnapshotAddSource(builder, source)
userfbs.EntitlementSnapshotAddActor(builder, actorOffset)
userfbs.EntitlementSnapshotAddReasonCode(builder, reasonCode)
userfbs.EntitlementSnapshotAddStartsAtMs(builder, snapshot.StartsAt.UTC().UnixMilli())
if snapshot.EndsAt != nil {
userfbs.EntitlementSnapshotAddEndsAtMs(builder, snapshot.EndsAt.UTC().UnixMilli())
}
userfbs.EntitlementSnapshotAddUpdatedAtMs(builder, snapshot.UpdatedAt.UTC().UnixMilli())
return userfbs.EntitlementSnapshotEnd(builder), nil
}
func decodeEntitlementSnapshot(snapshot *userfbs.EntitlementSnapshot) (usermodel.EntitlementSnapshot, error) {
actor := snapshot.Actor(nil)
if actor == nil {
return usermodel.EntitlementSnapshot{}, errors.New("entitlement actor is missing")
}
decodedActor, err := decodeActorRef(actor)
if err != nil {
return usermodel.EntitlementSnapshot{}, fmt.Errorf("decode entitlement actor: %w", err)
}
return usermodel.EntitlementSnapshot{
PlanCode: string(snapshot.PlanCode()),
IsPaid: snapshot.IsPaid(),
Source: string(snapshot.Source()),
Actor: decodedActor,
ReasonCode: string(snapshot.ReasonCode()),
StartsAt: time.UnixMilli(snapshot.StartsAtMs()).UTC(),
EndsAt: optionalUnixMilli(snapshot.EndsAtMs()),
UpdatedAt: time.UnixMilli(snapshot.UpdatedAtMs()).UTC(),
}, nil
}
func encodeActiveSanction(builder *flatbuffers.Builder, sanction usermodel.ActiveSanction) (flatbuffers.UOffsetT, error) {
actorOffset := encodeActorRef(builder, sanction.Actor)
sanctionCode := builder.CreateString(sanction.SanctionCode)
scope := builder.CreateString(sanction.Scope)
reasonCode := builder.CreateString(sanction.ReasonCode)
userfbs.ActiveSanctionStart(builder)
userfbs.ActiveSanctionAddSanctionCode(builder, sanctionCode)
userfbs.ActiveSanctionAddScope(builder, scope)
userfbs.ActiveSanctionAddReasonCode(builder, reasonCode)
userfbs.ActiveSanctionAddActor(builder, actorOffset)
userfbs.ActiveSanctionAddAppliedAtMs(builder, sanction.AppliedAt.UTC().UnixMilli())
if sanction.ExpiresAt != nil {
userfbs.ActiveSanctionAddExpiresAtMs(builder, sanction.ExpiresAt.UTC().UnixMilli())
}
return userfbs.ActiveSanctionEnd(builder), nil
}
func decodeActiveSanction(sanction *userfbs.ActiveSanction) (usermodel.ActiveSanction, error) {
actor := sanction.Actor(nil)
if actor == nil {
return usermodel.ActiveSanction{}, errors.New("sanction actor is missing")
}
decodedActor, err := decodeActorRef(actor)
if err != nil {
return usermodel.ActiveSanction{}, fmt.Errorf("decode sanction actor: %w", err)
}
return usermodel.ActiveSanction{
SanctionCode: string(sanction.SanctionCode()),
Scope: string(sanction.Scope()),
ReasonCode: string(sanction.ReasonCode()),
Actor: decodedActor,
AppliedAt: time.UnixMilli(sanction.AppliedAtMs()).UTC(),
ExpiresAt: optionalUnixMilli(sanction.ExpiresAtMs()),
}, nil
}
func encodeActiveLimit(builder *flatbuffers.Builder, limit usermodel.ActiveLimit) (flatbuffers.UOffsetT, error) {
actorOffset := encodeActorRef(builder, limit.Actor)
limitCode := builder.CreateString(limit.LimitCode)
reasonCode := builder.CreateString(limit.ReasonCode)
userfbs.ActiveLimitStart(builder)
userfbs.ActiveLimitAddLimitCode(builder, limitCode)
userfbs.ActiveLimitAddValue(builder, int64(limit.Value))
userfbs.ActiveLimitAddReasonCode(builder, reasonCode)
userfbs.ActiveLimitAddActor(builder, actorOffset)
userfbs.ActiveLimitAddAppliedAtMs(builder, limit.AppliedAt.UTC().UnixMilli())
if limit.ExpiresAt != nil {
userfbs.ActiveLimitAddExpiresAtMs(builder, limit.ExpiresAt.UTC().UnixMilli())
}
return userfbs.ActiveLimitEnd(builder), nil
}
func decodeActiveLimit(limit *userfbs.ActiveLimit) (usermodel.ActiveLimit, error) {
actor := limit.Actor(nil)
if actor == nil {
return usermodel.ActiveLimit{}, errors.New("limit actor is missing")
}
decodedActor, err := decodeActorRef(actor)
if err != nil {
return usermodel.ActiveLimit{}, fmt.Errorf("decode limit actor: %w", err)
}
value, err := int64ToInt(limit.Value(), "value")
if err != nil {
return usermodel.ActiveLimit{}, err
}
return usermodel.ActiveLimit{
LimitCode: string(limit.LimitCode()),
Value: value,
ReasonCode: string(limit.ReasonCode()),
Actor: decodedActor,
AppliedAt: time.UnixMilli(limit.AppliedAtMs()).UTC(),
ExpiresAt: optionalUnixMilli(limit.ExpiresAtMs()),
}, nil
}
func encodeActorRef(builder *flatbuffers.Builder, actor usermodel.ActorRef) flatbuffers.UOffsetT {
actorType := builder.CreateString(actor.Type)
var actorID flatbuffers.UOffsetT
if actor.ID != "" {
actorID = builder.CreateString(actor.ID)
}
userfbs.ActorRefStart(builder)
userfbs.ActorRefAddType(builder, actorType)
if actorID != 0 {
userfbs.ActorRefAddId(builder, actorID)
}
return userfbs.ActorRefEnd(builder)
}
func decodeActorRef(actor *userfbs.ActorRef) (usermodel.ActorRef, error) {
return usermodel.ActorRef{
Type: string(actor.Type()),
ID: string(actor.Id()),
}, nil
}
func encodeErrorBody(builder *flatbuffers.Builder, errorBody usermodel.ErrorBody) flatbuffers.UOffsetT {
code := builder.CreateString(errorBody.Code)
message := builder.CreateString(errorBody.Message)
userfbs.ErrorBodyStart(builder)
userfbs.ErrorBodyAddCode(builder, code)
userfbs.ErrorBodyAddMessage(builder, message)
return userfbs.ErrorBodyEnd(builder)
}
func optionalUnixMilli(value int64) *time.Time {
if value == 0 {
return nil
}
decoded := time.UnixMilli(value).UTC()
return &decoded
}
func recoverUserDecodePanic[T any](message string, result **T, err *error) {
if recovered := recover(); recovered != nil {
*result = nil
*err = fmt.Errorf("%s: panic recovered: %v", message, recovered)
}
}
// ListMySessionsRequestToPayload converts usermodel.ListMySessionsRequest
// to FlatBuffers bytes suitable for the authenticated gateway transport.
func ListMySessionsRequestToPayload(request *usermodel.ListMySessionsRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode list my sessions request payload: request is nil")
}
builder := flatbuffers.NewBuilder(32)
userfbs.ListMySessionsRequestStart(builder)
offset := userfbs.ListMySessionsRequestEnd(builder)
userfbs.FinishListMySessionsRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToListMySessionsRequest converts FlatBuffers payload bytes into
// usermodel.ListMySessionsRequest.
func PayloadToListMySessionsRequest(data []byte) (result *usermodel.ListMySessionsRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode list my sessions request payload: data is empty")
}
defer recoverUserDecodePanic("decode list my sessions request payload", &result, &err)
_ = userfbs.GetRootAsListMySessionsRequest(data, 0)
return &usermodel.ListMySessionsRequest{}, nil
}
// ListMySessionsResponseToPayload converts usermodel.ListMySessionsResponse
// to FlatBuffers bytes suitable for the authenticated gateway transport.
func ListMySessionsResponseToPayload(response *usermodel.ListMySessionsResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode list my sessions response payload: response is nil")
}
builder := flatbuffers.NewBuilder(256)
itemOffsets := make([]flatbuffers.UOffsetT, len(response.Items))
for index := range response.Items {
itemOffsets[index] = encodeDeviceSession(builder, response.Items[index])
}
var itemsVector flatbuffers.UOffsetT
if len(itemOffsets) > 0 {
userfbs.ListMySessionsResponseStartItemsVector(builder, len(itemOffsets))
for index := len(itemOffsets) - 1; index >= 0; index-- {
builder.PrependUOffsetT(itemOffsets[index])
}
itemsVector = builder.EndVector(len(itemOffsets))
}
userfbs.ListMySessionsResponseStart(builder)
if itemsVector != 0 {
userfbs.ListMySessionsResponseAddItems(builder, itemsVector)
}
offset := userfbs.ListMySessionsResponseEnd(builder)
userfbs.FinishListMySessionsResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToListMySessionsResponse converts FlatBuffers payload bytes into
// usermodel.ListMySessionsResponse.
func PayloadToListMySessionsResponse(data []byte) (result *usermodel.ListMySessionsResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode list my sessions response payload: data is empty")
}
defer recoverUserDecodePanic("decode list my sessions response payload", &result, &err)
response := userfbs.GetRootAsListMySessionsResponse(data, 0)
count := response.ItemsLength()
out := &usermodel.ListMySessionsResponse{
Items: make([]usermodel.DeviceSession, 0, count),
}
view := new(userfbs.DeviceSessionView)
for index := 0; index < count; index++ {
if !response.Items(view, index) {
return nil, fmt.Errorf("decode list my sessions response payload: item %d is missing", index)
}
out.Items = append(out.Items, decodeDeviceSession(view))
}
return out, nil
}
// RevokeMySessionRequestToPayload converts usermodel.RevokeMySessionRequest
// to FlatBuffers bytes suitable for the authenticated gateway transport.
func RevokeMySessionRequestToPayload(request *usermodel.RevokeMySessionRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode revoke my session request payload: request is nil")
}
builder := flatbuffers.NewBuilder(64)
deviceSessionID := builder.CreateString(request.DeviceSessionID)
userfbs.RevokeMySessionRequestStart(builder)
userfbs.RevokeMySessionRequestAddDeviceSessionId(builder, deviceSessionID)
offset := userfbs.RevokeMySessionRequestEnd(builder)
userfbs.FinishRevokeMySessionRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToRevokeMySessionRequest converts FlatBuffers payload bytes into
// usermodel.RevokeMySessionRequest.
func PayloadToRevokeMySessionRequest(data []byte) (result *usermodel.RevokeMySessionRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode revoke my session request payload: data is empty")
}
defer recoverUserDecodePanic("decode revoke my session request payload", &result, &err)
request := userfbs.GetRootAsRevokeMySessionRequest(data, 0)
return &usermodel.RevokeMySessionRequest{
DeviceSessionID: string(request.DeviceSessionId()),
}, nil
}
// RevokeMySessionResponseToPayload converts usermodel.RevokeMySessionResponse
// to FlatBuffers bytes suitable for the authenticated gateway transport.
func RevokeMySessionResponseToPayload(response *usermodel.RevokeMySessionResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode revoke my session response payload: response is nil")
}
builder := flatbuffers.NewBuilder(128)
sessionOffset := encodeDeviceSession(builder, response.Session)
userfbs.RevokeMySessionResponseStart(builder)
userfbs.RevokeMySessionResponseAddSession(builder, sessionOffset)
offset := userfbs.RevokeMySessionResponseEnd(builder)
userfbs.FinishRevokeMySessionResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToRevokeMySessionResponse converts FlatBuffers payload bytes into
// usermodel.RevokeMySessionResponse.
func PayloadToRevokeMySessionResponse(data []byte) (result *usermodel.RevokeMySessionResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode revoke my session response payload: data is empty")
}
defer recoverUserDecodePanic("decode revoke my session response payload", &result, &err)
response := userfbs.GetRootAsRevokeMySessionResponse(data, 0)
view := response.Session(nil)
if view == nil {
return nil, errors.New("decode revoke my session response payload: session is missing")
}
return &usermodel.RevokeMySessionResponse{Session: decodeDeviceSession(view)}, nil
}
// RevokeAllMySessionsRequestToPayload converts
// usermodel.RevokeAllMySessionsRequest to FlatBuffers bytes suitable for
// the authenticated gateway transport.
func RevokeAllMySessionsRequestToPayload(request *usermodel.RevokeAllMySessionsRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode revoke all my sessions request payload: request is nil")
}
builder := flatbuffers.NewBuilder(32)
userfbs.RevokeAllMySessionsRequestStart(builder)
offset := userfbs.RevokeAllMySessionsRequestEnd(builder)
userfbs.FinishRevokeAllMySessionsRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToRevokeAllMySessionsRequest converts FlatBuffers payload bytes
// into usermodel.RevokeAllMySessionsRequest.
func PayloadToRevokeAllMySessionsRequest(data []byte) (result *usermodel.RevokeAllMySessionsRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode revoke all my sessions request payload: data is empty")
}
defer recoverUserDecodePanic("decode revoke all my sessions request payload", &result, &err)
_ = userfbs.GetRootAsRevokeAllMySessionsRequest(data, 0)
return &usermodel.RevokeAllMySessionsRequest{}, nil
}
// RevokeAllMySessionsResponseToPayload converts
// usermodel.RevokeAllMySessionsResponse to FlatBuffers bytes suitable
// for the authenticated gateway transport.
func RevokeAllMySessionsResponseToPayload(response *usermodel.RevokeAllMySessionsResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode revoke all my sessions response payload: response is nil")
}
builder := flatbuffers.NewBuilder(64)
userID := builder.CreateString(response.Summary.UserID)
userfbs.DeviceSessionRevocationSummaryViewStart(builder)
userfbs.DeviceSessionRevocationSummaryViewAddUserId(builder, userID)
userfbs.DeviceSessionRevocationSummaryViewAddRevokedCount(builder, int32(response.Summary.RevokedCount))
summaryOffset := userfbs.DeviceSessionRevocationSummaryViewEnd(builder)
userfbs.RevokeAllMySessionsResponseStart(builder)
userfbs.RevokeAllMySessionsResponseAddSummary(builder, summaryOffset)
offset := userfbs.RevokeAllMySessionsResponseEnd(builder)
userfbs.FinishRevokeAllMySessionsResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToRevokeAllMySessionsResponse converts FlatBuffers payload bytes
// into usermodel.RevokeAllMySessionsResponse.
func PayloadToRevokeAllMySessionsResponse(data []byte) (result *usermodel.RevokeAllMySessionsResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode revoke all my sessions response payload: data is empty")
}
defer recoverUserDecodePanic("decode revoke all my sessions response payload", &result, &err)
response := userfbs.GetRootAsRevokeAllMySessionsResponse(data, 0)
summary := response.Summary(nil)
if summary == nil {
return nil, errors.New("decode revoke all my sessions response payload: summary is missing")
}
return &usermodel.RevokeAllMySessionsResponse{
Summary: usermodel.DeviceSessionRevocationSummary{
UserID: string(summary.UserId()),
RevokedCount: int(summary.RevokedCount()),
},
}, nil
}
func encodeDeviceSession(builder *flatbuffers.Builder, sess usermodel.DeviceSession) flatbuffers.UOffsetT {
deviceSessionID := builder.CreateString(sess.DeviceSessionID)
userID := builder.CreateString(sess.UserID)
status := builder.CreateString(sess.Status)
var clientPublicKey flatbuffers.UOffsetT
if sess.ClientPublicKey != "" {
clientPublicKey = builder.CreateString(sess.ClientPublicKey)
}
userfbs.DeviceSessionViewStart(builder)
userfbs.DeviceSessionViewAddDeviceSessionId(builder, deviceSessionID)
userfbs.DeviceSessionViewAddUserId(builder, userID)
userfbs.DeviceSessionViewAddStatus(builder, status)
if clientPublicKey != 0 {
userfbs.DeviceSessionViewAddClientPublicKey(builder, clientPublicKey)
}
userfbs.DeviceSessionViewAddCreatedAtMs(builder, sess.CreatedAt.UTC().UnixMilli())
if sess.RevokedAt != nil {
userfbs.DeviceSessionViewAddRevokedAtMs(builder, sess.RevokedAt.UTC().UnixMilli())
}
if sess.LastSeenAt != nil {
userfbs.DeviceSessionViewAddLastSeenAtMs(builder, sess.LastSeenAt.UTC().UnixMilli())
}
return userfbs.DeviceSessionViewEnd(builder)
}
func decodeDeviceSession(view *userfbs.DeviceSessionView) usermodel.DeviceSession {
return usermodel.DeviceSession{
DeviceSessionID: string(view.DeviceSessionId()),
UserID: string(view.UserId()),
Status: string(view.Status()),
ClientPublicKey: string(view.ClientPublicKey()),
CreatedAt: time.UnixMilli(view.CreatedAtMs()).UTC(),
RevokedAt: optionalUnixMilli(view.RevokedAtMs()),
LastSeenAt: optionalUnixMilli(view.LastSeenAtMs()),
}
}