private void HandleLogout(HttpListenerContext context) { var token = RestMethods.GetToken(context.Request); if (!_tokens.TryRemove(token, out int id)) { RestMethods.WriteError(context.Response, HttpStatusCode.Unauthorized, "Authorization failed"); return; } _users.TryRemove(id, out User user); _usernames.TryRemove(user.Username, out id); CountAndDecrement(_userEvent); context.Response.StatusCode = (int)HttpStatusCode.NoContent; context.Response.OutputStream.Close(); }
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); }
void Run() { Router router = new Router(); RestMethods restMethods = new RestMethods(VerifyToken); router.AddHandler("/login", HttpMethod.Post, HandleLogin); router.AddHandler("/logout", HttpMethod.Post, HandleLogout); router.AddHandler("/users", HttpMethod.Get, (context) => { SignEventAttendance(RestMethods.GetToken(context.Request)); restMethods.PerformGet <User>(context, GetUsersByQuery); } ); router.AddHandler("/users/" + Router.IntegerUrlParameter, HttpMethod.Get, (context) => restMethods.PerformGetById <User>(context, _users.TryGetValue, context.Request.Url.Segments[2]) ); router.AddHandler("/messages", HttpMethod.Post, (context) => restMethods.PerformPost <Message>(context, AddMessage) ); router.AddHandler("/messages", HttpMethod.Get, (context) => { SignEventAttendance(RestMethods.GetToken(context.Request)); restMethods.PerformGet <Message>(context, GetMessagesByQuery); } ); router.AddHandler("/messages/" + Router.IntegerUrlParameter, HttpMethod.Get, (context) => restMethods.PerformGetById <Message>(context, _messages.TryGetValue, context.Request.Url.Segments[2]) ); router.AddHandler("/messages/" + Router.IntegerUrlParameter, HttpMethod.Delete, (context) => restMethods.PerformDelete(context, DeleteMessage, context.Request.Url.Segments[2]) ); using (HttpListener httpListener = new HttpListener()) { httpListener.Prefixes.Add("http://localhost:" + _port + "/"); httpListener.Start(); while (true) { var context = httpListener.GetContext(); HttpListenerRequest request = context.Request; Thread t = new Thread(() => { if (router.TryGetHandler(request, out HandlerFunc handler)) { handler(context); } else { RestMethods.WriteError(context.Response, HttpStatusCode.BadRequest, "no handler provided"); } }); t.Start(); } } }
private bool VerifyToken(HttpListenerRequest request) { string token = RestMethods.GetToken(request); return(_tokens.ContainsKey(token)); }