Commit c90c13c9 authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Include disable time in runtime account get results.

parent 7ce10069
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
- New runtime function to get a single match by ID.
- New runtime functions for link operations.
- New Lua runtime function to print a log message at debug level.
- Lua runtime accounts get operations now return Facebook Instant Game IDs.
- Runtime account get operations now return account disable time if available.

### Changed
- Replace metrics implementation.
+5 −0
Original line number Diff line number Diff line
@@ -2541,6 +2541,11 @@
          "type": "string",
          "format": "date-time",
          "description": "The UNIX time when the user's email was verified."
        },
        "disable_time": {
          "type": "string",
          "format": "date-time",
          "description": "The UNIX time when the user's account was disabled/banned."
        }
      },
      "description": "A user with additional account details. Always the current user."
+6 −3
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ func (s *ApiServer) GetAccount(ctx context.Context, in *empty.Empty) (*api.Accou
		}
	}

	user, _, err := GetAccount(ctx, s.logger, s.db, s.tracker, userID)
	account, err := GetAccount(ctx, s.logger, s.db, s.tracker, userID)
	if err != nil {
		if err == ErrAccountNotFound {
			return nil, status.Error(codes.NotFound, "Account not found.")
@@ -54,17 +54,20 @@ func (s *ApiServer) GetAccount(ctx context.Context, in *empty.Empty) (*api.Accou
		return nil, status.Error(codes.Internal, "Error retrieving user account.")
	}

	// User-facing account retrieval does not expose disable time for now.
	account.DisableTime = nil

	// After hook.
	if fn := s.runtime.AfterGetAccount(); fn != nil {
		afterFn := func(clientIP, clientPort string) error {
			return fn(ctx, s.logger, userID.String(), ctx.Value(ctxUsernameKey{}).(string), ctx.Value(ctxVarsKey{}).(map[string]string), ctx.Value(ctxExpiryKey{}).(int64), clientIP, clientPort, user)
			return fn(ctx, s.logger, userID.String(), ctx.Value(ctxUsernameKey{}).(string), ctx.Value(ctxVarsKey{}).(map[string]string), ctx.Value(ctxExpiryKey{}).(int64), clientIP, clientPort, account)
		}

		// Execute the after function lambda wrapped in a trace for stats measurement.
		traceApiAfter(ctx, s.logger, s.metrics, ctx.Value(ctxFullMethodKey{}).(string), afterFn)
	}

	return user, nil
	return account, nil
}

func (s *ApiServer) UpdateAccount(ctx context.Context, in *api.UpdateAccountRequest) (*empty.Empty, error) {
+5 −7
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ func (s *ConsoleServer) GetAccount(ctx context.Context, in *console.AccountId) (
		return nil, status.Error(codes.InvalidArgument, "Requires a valid user ID.")
	}

	account, disableTime, err := GetAccount(ctx, s.logger, s.db, s.tracker, userID)
	account, err := GetAccount(ctx, s.logger, s.db, s.tracker, userID)
	if err != nil {
		// Error already logged in function above.
		if err == ErrAccountNotFound {
@@ -136,12 +136,10 @@ func (s *ConsoleServer) GetAccount(ctx context.Context, in *console.AccountId) (
		return nil, status.Error(codes.Internal, "An error occurred while trying to retrieve user account.")
	}

	acc := &console.Account{Account: account}
	if disableTime.Unix() != 0 {
		acc.DisableTime = &timestamp.Timestamp{Seconds: disableTime.Unix()}
	}

	return acc, nil
	return &console.Account{
		Account:     account,
		DisableTime: account.DisableTime,
	}, nil
}

func (s *ConsoleServer) GetFriends(ctx context.Context, in *console.AccountId) (*api.FriendList, error) {
+33 −24
Original line number Diff line number Diff line
@@ -18,26 +18,24 @@ import (
	"context"
	"database/sql"
	"encoding/json"
	"github.com/heroiclabs/nakama/v2/console"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"strconv"
	"strings"
	"time"

	"github.com/gofrs/uuid"
	"github.com/golang/protobuf/ptypes/timestamp"
	"github.com/golang/protobuf/ptypes/wrappers"
	"github.com/heroiclabs/nakama-common/api"
	"github.com/heroiclabs/nakama/v2/console"
	"github.com/jackc/pgx"
	"github.com/jackc/pgx/pgtype"
	"github.com/pkg/errors"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"strconv"
	"strings"
)

var ErrAccountNotFound = errors.New("account not found")

func GetAccount(ctx context.Context, logger *zap.Logger, db *sql.DB, tracker Tracker, userID uuid.UUID) (*api.Account, time.Time, error) {
func GetAccount(ctx context.Context, logger *zap.Logger, db *sql.DB, tracker Tracker, userID uuid.UUID) (*api.Account, error) {
	var displayName sql.NullString
	var username sql.NullString
	var avatarURL sql.NullString
@@ -69,10 +67,10 @@ WHERE u.id = $1`

	if err := db.QueryRowContext(ctx, query, userID).Scan(&username, &displayName, &avatarURL, &langTag, &location, &timezone, &metadata, &wallet, &email, &facebook, &facebookInstantGame, &google, &gamecenter, &steam, &customID, &edgeCount, &createTime, &updateTime, &verifyTime, &disableTime, &deviceIDs); err != nil {
		if err == sql.ErrNoRows {
			return nil, time.Time{}, ErrAccountNotFound
			return nil, ErrAccountNotFound
		}
		logger.Error("Error retrieving user account.", zap.Error(err))
		return nil, time.Time{}, err
		return nil, err
	}

	devices := make([]*api.AccountDevice, 0, len(deviceIDs.Elements))
@@ -84,6 +82,10 @@ WHERE u.id = $1`
	if verifyTime.Status == pgtype.Present && verifyTime.Time.Unix() != 0 {
		verifyTimestamp = &timestamp.Timestamp{Seconds: verifyTime.Time.Unix()}
	}
	var disableTimestamp *timestamp.Timestamp
	if disableTime.Status == pgtype.Present && disableTime.Time.Unix() != 0 {
		disableTimestamp = &timestamp.Timestamp{Seconds: disableTime.Time.Unix()}
	}

	online := false
	if tracker != nil {
@@ -115,7 +117,8 @@ WHERE u.id = $1`
		Devices:     devices,
		CustomId:    customID.String,
		VerifyTime:  verifyTimestamp,
	}, disableTime.Time, nil
		DisableTime: disableTimestamp,
	}, nil
}

func GetAccounts(ctx context.Context, logger *zap.Logger, db *sql.DB, tracker Tracker, userIDs []string) ([]*api.Account, error) {
@@ -129,7 +132,7 @@ func GetAccounts(ctx context.Context, logger *zap.Logger, db *sql.DB, tracker Tr
	query := `
SELECT u.id, u.username, u.display_name, u.avatar_url, u.lang_tag, u.location, u.timezone, u.metadata, u.wallet,
	u.email, u.facebook_id, u.facebook_instant_game_id, u.google_id, u.gamecenter_id, u.steam_id, u.custom_id, u.edge_count,
	u.create_time, u.update_time, u.verify_time, array(select ud.id from user_device ud where u.id = ud.user_id)
	u.create_time, u.update_time, u.verify_time, u.disable_time, array(select ud.id from user_device ud where u.id = ud.user_id)
FROM users u
WHERE u.id IN (` + strings.Join(statements, ",") + `)`
	rows, err := db.QueryContext(ctx, query, parameters...)
@@ -161,9 +164,10 @@ WHERE u.id IN (` + strings.Join(statements, ",") + `)`
		var createTime pgtype.Timestamptz
		var updateTime pgtype.Timestamptz
		var verifyTime pgtype.Timestamptz
		var disableTime pgtype.Timestamptz
		var deviceIDs pgtype.VarcharArray

		err = rows.Scan(&userID, &username, &displayName, &avatarURL, &langTag, &location, &timezone, &metadata, &wallet, &email, &facebook, &facebookInstantGame, &google, &gamecenter, &steam, &customID, &edgeCount, &createTime, &updateTime, &verifyTime, &deviceIDs)
		err = rows.Scan(&userID, &username, &displayName, &avatarURL, &langTag, &location, &timezone, &metadata, &wallet, &email, &facebook, &facebookInstantGame, &google, &gamecenter, &steam, &customID, &edgeCount, &createTime, &updateTime, &verifyTime, &disableTime, &deviceIDs)
		if err != nil {
			logger.Error("Error retrieving user accounts.", zap.Error(err))
			return nil, err
@@ -178,6 +182,10 @@ WHERE u.id IN (` + strings.Join(statements, ",") + `)`
		if verifyTime.Status == pgtype.Present && verifyTime.Time.Unix() != 0 {
			verifyTimestamp = &timestamp.Timestamp{Seconds: verifyTime.Time.Unix()}
		}
		var disableTimestamp *timestamp.Timestamp
		if disableTime.Status == pgtype.Present && disableTime.Time.Unix() != 0 {
			disableTimestamp = &timestamp.Timestamp{Seconds: disableTime.Time.Unix()}
		}

		online := false
		if tracker != nil {
@@ -209,6 +217,7 @@ WHERE u.id IN (` + strings.Join(statements, ",") + `)`
			Devices:     devices,
			CustomId:    customID.String,
			VerifyTime:  verifyTimestamp,
			DisableTime: disableTimestamp,
		})
	}

@@ -320,7 +329,7 @@ func UpdateAccount(ctx context.Context, logger *zap.Logger, db *sql.DB, userID u

func ExportAccount(ctx context.Context, logger *zap.Logger, db *sql.DB, userID uuid.UUID) (*console.AccountExport, error) {
	// Core user account.
	account, _, err := GetAccount(ctx, logger, db, nil, userID)
	account, err := GetAccount(ctx, logger, db, nil, userID)
	if err != nil {
		if err == ErrAccountNotFound {
			return nil, status.Error(codes.NotFound, "Account not found.")
Loading