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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  | var (
	errMarshal = runtime.NewError("cannot marshal type", 13)
	errUnmarshal = runtime.NewError("cannot unmarshal type", 13)
	errApiPost = runtime.NewError("invalid API response", 13)
	errInternal = runtime.NewError("internal server error", 13)
)
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
	// Register before hook on custom authentication
	err := initializer.RegisterBeforeAuthenticateCustom(beforeAuthenticateCustom)
	if err != nil {
		return fmt.Errorf("error registering before authentication hook: %s", err.Error())
	}
	return nil
}
func beforeAuthenticateCustom(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, in *api.AuthenticateCustomRequest) (*api.AuthenticateCustomRequest, error) {
	// Get third-party API URL from the runtime context
	env := ctx.Value(runtime.RUNTIME_CTX_ENV).(map[string]string)
	apiUrl := env["AUTHENTICATION_API_URL"]
	// Construct a payload to send to the third-party API
	payload, err := json.Marshal(map[string]string {
		"id": in.Account.Id,
	})
	if err != nil {
		logger.Error("could not marshal api payload: %s", err.Error())
		return nil, errMarshal
	}
	// Send the HTTP Post request to the API
	/*
	Expected API Response
	HTTP 200
	{
		"user_id": "<UserId>",
		"username": "<Username>"
	}
	*/
	response, err := http.Post(apiUrl, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		logger.Error("invalid API response: %s", err.Error())
		return nil, errApiPost
	}
	// Close the response when we're done
	defer response.Body.Close()
	// Read the response from the API and parse it as a map[string]string containing user info
	bytes, err := ioutil.ReadAll(response.Body)
	if err != nil {
		logger.Error("error reading API response body: %s", err.Error())
		return nil, errInternal
	}
	userInfo := make(map[string]string)
	err = json.Unmarshal(bytes, &userInfo)
	if err != nil {
		logger.Error("error unmarshaling API response: %s", err.Error())
		return nil, errUnmarshal
	}
	// Update the incoming authenticate request with the new user ID and username
	in.Account.Id = userInfo["user_id"]
	in.Username = userInfo["username"]
	return in, nil
}
  |