Heroic Labs Documentation

Banning Users #

This example details how to effectively ban a user from future interactions and also simultaneously logout and disconnect all active sessions they currently have.

Server
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
type BanUserPayload struct {
	userId string `json:"userId"`
}

func BanUserRPC(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
	// Check the user calling the RPC has permissions depending on your criteria
	hasPermission := true
	if !hasPermission {
		logger.Error("unprivileged user attempted to use the BanUser RPC")
		return "", runtime.NewError("unauthorized", 7)
	}

	// Extract the payload
	var data BanUserPayload
	if err := json.Unmarshal([]byte(payload), &data); err != nil {
		logger.Error("unable to deserialize payload")
		return "", runtime.NewError("invalid payload", 3)
	}

	// Ban the user
	if err := nk.UsersBanId(ctx, []string { data.userId }); err != nil {
		logger.Error("unable to ban user")
		return "", runtime.NewError("unable to ban user", 13)
	}

	// Log the user out
	if err := nk.SessionLogout(data.userId, "", ""); err != nil {
		logger.Error("unable to logout user")
		return "", runtime.NewError("unable to logout user", 13)
	}

	// Get any existing connections by inspecting the notifications stream
	if presences, err := nk.StreamUserList(0, data.userId, "", "", true, true); err != nil {
		logger.Debug("no active connections found for user")
	} else {
		// For each active connection, disconnect them
		for _, presence := range presences {
			nk.SessionDisconnect(ctx, presence.GetSessionId(), runtime.PresenceReasonDisconnect)
		}
	}

	return "{}", nil
}
Server
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const BanUserRPC : nkruntime.RpcFunction = function (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string): string | void {
  // Check the user calling the RPC has permissions depending on your criteria
  let hasPermission = true
  if (!hasPermission) {
    logger.error("unprivileged user attempted to use the BanUser RPC");
    return null
  }

  // Extract the payload
  const data = JSON.parse(payload);
  if (!data.userId) {
    logger.error("unable to deserialize payload");
    return null;
  }

  // Ban the user
  nk.usersBanId([data.userId]);

  // Log the user out
  nk.sessionLogout(data.userId, null, null);

  // Get any existing connections by inspecting the notifications stream
  const presences = nk.streamUserList({ mode: 0, subject: data.userId }, true, true);
  presences.forEach(function (presence) {
    nk.sessionDisconnect(presence.sessionId);
  });

  return JSON.stringify({ });
};
Server
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
local function ban_user_rpc(context, payload)
    -- Check the user calling the RPC has permissions depending on your criteria
    local has_permission = true
    if not has_permission
        return nil
    end

    -- Extract the payload
    local data = nk.json_decode(payload)
    if data["userId"] == nil
        nk.logger_error("unable to deserialize payload")
        return nil
    end

    -- Ban the user
    nk.users_ban_id({ data["userId"] })

    -- Log the user out
    nk.session_logout(data["userId"], "", "")

    -- Get any existing connections by inspecting the notifications stream
    local presences = nk.stream_user_list({ mode = 0, subject = data["userId"] }, true, true)
    for i, presence in ipairs(presences) do
        nk.session_disconnect(presence.session_id, 0)
    end
    
    return json.encode({ success = true })
end