Exemple #1
0
        private void HandleLogin(HttpListenerContext context)
        {
            LoginRequest request;

            try
            {
                request = RestMethods.ReadBody <LoginRequest>(context.Request);
            }
            catch (ArgumentException e)
            {
                RestMethods.WriteError(context.Response, HttpStatusCode.BadRequest, e.Message);
                return;
            }

            if (_usernames.TryGetValue(request.Username, out int id))
            {
                if (_users[id].Online)
                {
                    context.Response.AppendHeader(HttpResponseHeader.WwwAuthenticate.ToString(), "Token realm = 'Username is already in use'");
                    RestMethods.WriteError(context.Response, HttpStatusCode.Unauthorized, "username is already in use");
                    return;
                }
                else
                {
                    _users.TryRemove(id, out _);
                    _usernames.TryRemove(request.Username, out id);
                    _tokens.TryRemove(_tokens.First(tokenId => tokenId.Value == id).Key, out id);
                }
            }

            lock (this)
            {
                id = ++_userId;
            }
            var token = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

            var loginResponse = new LoginResponse
            {
                Username = request.Username,
                Id       = id,
                Online   = true,
                Token    = token
            };

            lock (_usernames)
            {
                if (!_usernames.TryAdd(loginResponse.Username, id))
                {
                    context.Response.AppendHeader(HttpResponseHeader.WwwAuthenticate.ToString(), "Token realm = 'Username is already in use'");
                    RestMethods.WriteError(context.Response, HttpStatusCode.Unauthorized, "username is already in use");
                }
                _users.TryAdd(id, new User
                {
                    Username = loginResponse.Username,
                    Id       = id,
                    Online   = true
                });
                _tokens.TryAdd(token, id);
            }

            CountAndDecrement(_userEvent);

            RestMethods.WriteToResponse(context.Response, loginResponse);
        }