예제 #1
0
        /// <summary>
        /// Perform the dispatching function of the service
        /// </summary>
        internal bool Dispatch(RestRequestMessage requestMessage, RestResponseMessage responseMessage)
        {
            try
            {
                this.m_traceSource.TraceEvent(TraceEventType.Verbose, 0, "Begin service dispatch of {0} {1} > {2}", requestMessage.Method, requestMessage.Url, this.m_service.Name);

                // Endpoint
                var ep = this.m_service.Endpoints.FirstOrDefault(o => o.Dispatcher.CanDispatch(requestMessage));

                // Find the endpoint
                if (ep == null)
                {
                    throw new FaultException(404, "Resource not Found");
                }

                RestOperationContext.Current.ServiceEndpoint = ep;

                // Apply the policy on the specified context
                foreach (var pol in this.m_servicePolicies)
                {
                    RestOperationContext.Current.AddAppliedPolicy(pol);
                    pol.Apply(requestMessage);
                }

                return(ep.Dispatcher.Dispatch(this, requestMessage, responseMessage));
            }
            catch (Exception e)
            {
                return(this.HandleFault(e, responseMessage));
            }
        }
예제 #2
0
 /// <summary>
 /// Process the request from the <paramref name="state"/> passed
 /// on the action.
 /// </summary>
 private void DoProcessRequestInternal(Object accept)
 {
     {
         var context = accept as HttpListenerContext;
         try
         {
             RestOperationContext.Current = new RestOperationContext(context);
             var requestMessage = new RestRequestMessage(context.Request);
             using (var responseMessage = new RestResponseMessage(context.Response))
             {
                 this.m_serviceDispatcher.Dispatch(requestMessage, responseMessage);
                 if (requestMessage.Method.ToLowerInvariant() != "head")
                 {
                     responseMessage.FlushResponseStream();
                 }
             }
         }
         catch (Exception e)
         {
             this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
         }
         finally
         {
             RestOperationContext.Current.Dispose();
         }
     }
 }
        /// <summary>
        /// After receive a request look for the language
        /// </summary>
        /// <param name="request"></param>
        public void AfterReceiveRequest(RestRequestMessage request)
        {
            try
            {
                RestOperationContext.Current.Data.Add("originalLanguage", Thread.CurrentThread.CurrentUICulture.Name);
                var langPrincipal = AuthenticationContext.Current.Principal.GetClaimValue(SanteDBClaimTypes.Language);
                if (langPrincipal != null)
                {
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(langPrincipal);
                }
                else if (RestOperationContext.Current.Data.TryGetValue("Session", out object dataSession) && dataSession is ISession session &&
                         session.Claims.Any(o => o.Type == SanteDBClaimTypes.Language))
                {
                    langPrincipal = session.Claims.First(o => o.Type == SanteDBClaimTypes.Language)?.Value;
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(langPrincipal);
                }
                else if (request.Headers["Accept-Language"] != null)
                {
                    var language = request.Headers["Accept-Language"].Split(',');
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(language[0]);
                }

                if (request.Headers["X-SdbLanguage"] != null) // Language override
                {
                    var language = request.Headers["X-SdbLanguage"].Split(',');
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(language[0]);
                }
                RestOperationContext.Current.Data.Add("lang", Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName);
            }
        private void HandleClientDisconnected(RestDataRequestMessage message, ClientDisconnectedMessage messageContent,
                                              ref RestResponse response, RestRequestMessage request)
        {
            _context.RemoveUserBySessionCredentials(message.SessionCredentials);

            response.SetSuccessful(true, "ResultFromServerTask");
        }
        // @TODO:  ClientWantsToConnectCustomGameMessage
        private void HandleRequestJoinCustomGameMessage(RestDataRequestMessage message,
                                                        RequestJoinCustomGameMessage messageContent,
                                                        ref RestResponse response, RestRequestMessage request)
        {
            User ServerOwner = _context.FindServerHosterBy(messageContent.CustomBattleId);

            User JoiningUser = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (ServerOwner == default || JoiningUser == default)
            {
                return;
            }
            if (ServerOwner.HostedServer == null)
            {
                return;
            }


            /*@TODO:
             *  //var result =  JoinCustomGameResultMessage.CreateSuccess(new JoinGameData(properties,0,0 ));
             *  ServerOwner.QueuedMessages.Add(new ClientWantsToConnectCustomGameMessage(new PlayerJoinGameData[]{new PlayerJoinGameData(JoiningUser.PlayerData,JoiningUser.PlayerData.LastPlayerName) },msg.Password ));
             *
             *  response.EnqueueMessage(new RestDataResponseMessage(result));
             */
            ServerOwner.QueuedMessages.Enqueue(new RestDataResponseMessage(
                                                   new ClientWantsToConnectCustomGameMessage(
                                                       new[]
                                                       { new PlayerJoinGameData(JoiningUser.PlayerData, JoiningUser.PlayerData.LastPlayerName, null) },
                                                       messageContent.Password)));

            response.SetSuccessful(true, "ResultFromServerTask");
        }
예제 #6
0
 /// <summary>
 /// After receiving a request increment the max
 /// </summary>
 public void AfterReceiveRequest(RestRequestMessage request)
 {
     Interlocked.Increment(ref this.m_currentLoad);
     if (this.m_currentLoad > this.m_maxConcurrency)
     {
         RestOperationContext.Current.OutgoingResponse.Headers.Add("Retry-After", "1200");
         throw new FaultException(429, "Too Many Requests");
     }
 }
        /// <summary>
        /// Apply the authorization policy rule
        /// </summary>
        public void Apply(RestRequestMessage request)
        {
            try
            {
                this.m_traceSource.TraceInfo("CheckAccess");

                // Http message inbound
                var httpMessage = RestOperationContext.Current.IncomingRequest;

                // Get the authorize header
                String authorization = httpMessage.Headers["Authorization"];
                if (authorization == null)
                {
                    if (httpMessage.HttpMethod == "OPTIONS" || httpMessage.HttpMethod == "PING")
                    {
                        Core.Security.AuthenticationContext.Current = new Core.Security.AuthenticationContext(Core.Security.AuthenticationContext.AnonymousPrincipal);
                        return;
                    }
                    else
                    {
                        throw new SecurityTokenException("Missing Authorization header");
                    }
                }

                // Authorization method
                var auth = authorization.Split(' ').Select(o => o.Trim()).ToArray();
                switch (auth[0].ToLowerInvariant())
                {
                case "bearer":
                    this.CheckBearerAccess(auth[1]);
                    break;

                case "urn:ietf:params:oauth:token-type:jwt":     // Will use JWT authorization
                    this.CheckJwtAccess(auth[1]);
                    break;

                default:
                    throw new SecurityTokenException("Invalid authentication scheme");
                }
            }
            catch (UnauthorizedAccessException e)
            {
                this.m_traceSource.TraceEvent(EventLevel.Error, "Token Error (From: {0}) : {1}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint, e);

                throw;
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(EventLevel.Error, "Token Error (From: {0}) : {1}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint, e);
                throw new SecurityTokenException(e.Message, e);
            }
            finally
            {
                // Disposed context so reset the auth
                RestOperationContext.Current.Disposed += (o, e) => Core.Security.AuthenticationContext.Current = new Core.Security.AuthenticationContext(Core.Security.AuthenticationContext.AnonymousPrincipal);
            }
        }
예제 #8
0
        /// <summary>
        /// Apply the demand
        /// </summary>
        public void Apply(EndpointOperation operation, RestRequestMessage request)
        {
            var methInfo = this.m_behaviorType.GetMethod(operation.Description.InvokeMethod.Name, operation.Description.InvokeMethod.GetParameters().Select(p => p.ParameterType).ToArray());

            foreach (var demand in methInfo.GetCustomAttributes <DemandAttribute>())
            {
                ApplicationServiceContext.Current.GetService <IPolicyEnforcementService>().Demand(demand.PolicyId);
            }
        }
        /// <summary>
        /// After receiving a request
        /// </summary>
        public void AfterReceiveRequest(RestRequestMessage request)
        {
            var cReq = Interlocked.Increment(ref this.m_requests);

            if (cReq > this.m_settings.Limit)
            {
                throw new LimitExceededException();
            }
        }
예제 #10
0
        /// <summary>
        /// Apply the actual policy
        /// </summary>
        public void Apply(EndpointOperation operation, RestRequestMessage request)
        {
            var methInfo = this.m_behaviorType.GetMethod(operation.Description.InvokeMethod.Name, operation.Description.InvokeMethod.GetParameters().Select(p => p.ParameterType).ToArray());

            foreach (var ppe in methInfo.GetCustomAttributes <DemandAttribute>())
            {
                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, ppe.PolicyId).Demand();
            }
        }
        /// <summary>
        /// Apply the authorization policy rule
        /// </summary>
        public void Apply(RestRequestMessage request)
        {
            try
            {
                this.m_traceSource.TraceInfo("CheckAccess");

                // Http message inbound
                var httpMessage = RestOperationContext.Current.IncomingRequest;


                // Get the authorize header
                String authorization = httpMessage.Headers["Authorization"];
                if (authorization == null)
                {
                    if (httpMessage.HttpMethod == "OPTIONS" || httpMessage.HttpMethod == "PING")
                    {
                        return;
                    }
                    else
                    {
                        throw new SecuritySessionException(SessionExceptionType.NotEstablished, "Missing Authorization header", null);
                    }
                }

                // Authorization method
                var auth = authorization.Split(' ').Select(o => o.Trim()).ToArray();
                switch (auth[0].ToLowerInvariant())
                {
                case "bearer":
                    var contextToken = this.CheckBearerAccess(auth[1]);
                    RestOperationContext.Current.Disposed += (o, e) => contextToken.Dispose();
                    break;

                default:
                    throw new SecuritySessionException(SessionExceptionType.TokenType, "Invalid authentication scheme", null);
                }
            }
            catch (UnauthorizedAccessException e)
            {
                this.m_traceSource.TraceError("Token Error (From: {0}) : {1}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint, e);
                AuditUtil.AuditNetworkRequestFailure(e, RestOperationContext.Current.IncomingRequest.Url, RestOperationContext.Current.IncomingRequest.Headers, null);
                throw;
            }
            catch (KeyNotFoundException e)
            {
                this.m_traceSource.TraceError("Token Error (From: {0}) : {1}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint, e);
                AuditUtil.AuditNetworkRequestFailure(e, RestOperationContext.Current.IncomingRequest.Url, RestOperationContext.Current.IncomingRequest.Headers, null);
                throw new SecuritySessionException(SessionExceptionType.NotEstablished, e.Message, e);
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceError("Token Error (From: {0}) : {1}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint, e);
                AuditUtil.AuditNetworkRequestFailure(e, RestOperationContext.Current.IncomingRequest.Url, RestOperationContext.Current.IncomingRequest.Headers, null);
                throw new SecuritySessionException(SessionExceptionType.Other, e.Message, e);
            }
        }
예제 #12
0
        /// <summary>
        /// Apply the policy to the request
        /// </summary>
        public void Apply(RestRequestMessage request)
        {
            try
            {
                this.m_traceSource.TraceInfo("Entering OAuth BasicAuthorizationAccessPolicy");

                // Role service
                var identityService = ApplicationServiceContext.Current.GetService <IApplicationIdentityProviderService>();

                var httpRequest = RestOperationContext.Current.IncomingRequest;

                var authHeader = httpRequest.Headers["Authorization"];
                if (String.IsNullOrEmpty(authHeader) ||
                    !authHeader.ToLowerInvariant().StartsWith("basic"))
                {
                    throw new AuthenticationException("Invalid authentication scheme");
                }
                authHeader = authHeader.Substring(6);
                var b64Data = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader)).Split(':');
                if (b64Data.Length != 2)
                {
                    throw new SecurityException("Malformed HTTP Basic Header");
                }

                var principal = identityService.Authenticate(b64Data[0], b64Data[1]);
                if (principal == null)
                {
                    throw new AuthenticationException("Invalid client credentials");
                }

                // Client secret
                RestOperationContext.Current.Data.Add("symm_secret", b64Data[1]);

                // If the current principal is set-up then add the identity if not then don't
                if (AuthenticationContext.Current.Principal == AuthenticationContext.AnonymousPrincipal)
                {
                    AuthenticationContext.Current = new AuthenticationContext(principal);
                }
                else
                {
                    (AuthenticationContext.Current.Principal as IClaimsPrincipal).AddIdentity(principal.Identity);
                }

                // Disposed context so reset the auth
                RestOperationContext.Current.Disposed += (o, e) => AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.AnonymousPrincipal);
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(EventLevel.Error, e.ToString());
            }
        }
        /// <summary>
        /// After receiving the request
        /// </summary>
        /// <param name="request"></param>
        public void AfterReceiveRequest(RestRequestMessage request)
        {
            Guid httpCorrelator = Guid.NewGuid();


            this.m_traceSource.TraceEvent(EventLevel.Verbose, "HTTP RQO {0} : {1} {2} ({3}) - {4}",
                                          RestOperationContext.Current.IncomingRequest.RemoteEndPoint,
                                          request.Method,
                                          request.Url,
                                          RestOperationContext.Current.IncomingRequest.UserAgent,
                                          httpCorrelator);

            httpCorrelation = new KeyValuePair <Guid, DateTime>(httpCorrelator, DateTime.Now);
        }
        private void HandleGetPlayerBadgesMessage(RestDataRequestMessage message, GetPlayerBadgesMessage messageContent,
                                                  ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (user == default)
            {
                return;
            }
            response.FunctionResult =
                new RestDataFunctionResult(new GetPlayerBadgesMessageResult(new[]
                                                                            { user.CanHost ? "badge_taleworlds_primary_dev" : "" }));
            response.SetSuccessful(true, "ResultFromServerTask");
        }
        private void HandleGetServerStatusMessage(RestDataRequestMessage message, GetServerStatusMessage messagecontent,
                                                  ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (user == default)
            {
                return;
            }


            response.EnqueueMessage(new RestDataResponseMessage(new ServerStatusMessage(GetServerStatusForUser(user))));

            response.SetSuccessful(true, "ResultFromServerTask");
        }
예제 #16
0
        /// <summary>
        /// Determines if the dispatcher can dispatch the supplied request message
        /// </summary>
        internal bool CanDispatch(RestRequestMessage requestMessage)
        {
            this.m_traceSource.TraceEvent(TraceEventType.Verbose, 0, "EndpointDispatcher.CanDispatch -> {0} (EPRx: {1})", requestMessage.Url, this.m_endpointRegex);

            // Match the path
            if (this.m_endpointRegex.IsMatch(requestMessage.Url.ToString()))
            {
                requestMessage.OperationPath = this.GetOperationPath(requestMessage.Url);
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Deserialize the request
        /// </summary>
        public void DeserializeRequest(EndpointOperation operation, RestRequestMessage request, object[] parameters)
        {
            try
            {
                var httpRequest = RestOperationContext.Current.IncomingRequest;
                var contentType = httpRequest.Headers["Content-Type"];

                for (var pNumber = 0; pNumber < parameters.Length; pNumber++)
                {
                    var parm = operation.Description.InvokeMethod.GetParameters()[pNumber];

                    // Simple parameter
                    if (parameters[pNumber] != null)
                    {
                        continue;
                    }

                    // Use XML Serializer
                    if (contentType?.StartsWith("application/fhir+xml") == true)
                    {
                        var parser = new FhirXmlParser(this.m_settings);
                        using (var xr = XmlReader.Create(request.Body))
                        {
                            parameters[pNumber] = parser.Parse(xr);
                        }
                    }
                    // Use JSON Serializer
                    else if (contentType?.StartsWith("application/fhir+json") == true)
                    {
                        var parser = new FhirJsonParser(this.m_settings);
                        using (var sr = new StreamReader(request.Body))
                            using (var jr = new JsonTextReader(sr))
                            {
                                parameters[pNumber] = parser.Parse(jr);
                            }
                    }
                    else if (contentType != null) // TODO: Binaries
                    {
                        throw new InvalidOperationException("Invalid request format");
                    }
                }
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(EventLevel.Error, e.ToString());
                throw;
            }
        }
 /// <summary>
 /// After request is received
 /// </summary>
 public void AfterReceiveRequest(RestRequestMessage request)
 {
     try
     {
         // Handle compressed requests
         var compressionScheme = CompressionUtil.GetCompressionScheme(RestOperationContext.Current.IncomingRequest.Headers["Content-Encoding"]);
         if (compressionScheme != null)
         {
             request.Body = compressionScheme.CreateDecompressionStream(request.Body);
         }
     }
     catch (Exception e)
     {
         this.m_traceSource.TraceEvent(EventLevel.Error, e.ToString());
     }
 }
        private void HandleEndHostingCustomGameMessage(RestDataRequestMessage message,
                                                       EndHostingCustomGameMessage messageContent,
                                                       ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (user != default)
            {
                user.HostedServer = null;
            }


            response.FunctionResult =
                new RestDataFunctionResult(new EndHostingCustomGameResult());
            response.SetSuccessful(true, "ResultFromServerTask");
        }
        private void HandleUpdateCharacterMessage(RestDataRequestMessage message, UpdateCharacterMessage messagecontent,
                                                  ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (user == default)
            {
                return;
            }
            user.PlayerData.BodyProperties = messagecontent.BodyProperties;

            user.PlayerData.IsFemale =
                messagecontent.IsFemale;

            response.SetSuccessful(true, "ResultFromServerTask");
        }
예제 #21
0
        /// <summary>
        /// Apply the policy to the request message
        /// </summary>
        public void Apply(RestRequestMessage request)
        {
            var authHeader = request.Headers["Authorization"];

            try
            {
                // Validate the auth header
                if (String.IsNullOrEmpty(authHeader) && !"GET".Equals(request.Method, StringComparison.OrdinalIgnoreCase) && !"HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase))
                {
                    throw new SecurityException("Request is not authorized");
                }
                else if (!String.IsNullOrEmpty(authHeader))
                {
                    var tokenized = authHeader.Split(' ');
                    if (!"basic".Equals(tokenized[0], StringComparison.OrdinalIgnoreCase))
                    {
                        throw new SecurityException("Invalid authorization scheme");
                    }

                    var authData = Encoding.UTF8.GetString(Convert.FromBase64String(tokenized[1])).Split(':');
                    if (!2.Equals(authData.Length))
                    {
                        throw new SecurityException("Invalid authorization header");
                    }

                    // attempt auth using config
                    var authn = this.Authorize(authData[0], authData[1]);
                    if (authn == null)
                    {
                        throw new SecurityException("Authorization failure");
                    }

                    RestOperationContext.Current.Data.Add("auth", authn);
                }
            }
            catch (SecurityException)
            {
                RestOperationContext.Current.OutgoingResponse.AddHeader("WWW-Authenticate", "basic");
                throw;
            }
        }
        private void HandleResponseCustomGameClientConnectionMessage(RestDataRequestMessage message,
                                                                     ResponseCustomGameClientConnectionMessage messageContent, ref RestResponse response,
                                                                     RestRequestMessage request)
        {
            var server = _context.Users.Find(x => x.Id.SessionKey == message.SessionCredentials.SessionKey)
                         .HostedServer;

            foreach (var joindata in messageContent.PlayerJoinData)
            {
                var users = _context.Users.FindAll(usr =>
                                                   joindata.PlayerId.ConvertToPeerId() == usr.Id.PeerId && usr.HostedServer == null);

                switch (joindata.CustomGameJoinResponse)
                {
                case CustomGameJoinResponse.Success:
                    users.ForEach(u =>
                    {
                        u.QueuedMessages.Enqueue(new RestDataResponseMessage(
                                                     JoinCustomGameResultMessage.CreateSuccess(new JoinGameData(
                                                                                                   new GameServerProperties(server.entry.ServerName, server.entry.Address,
                                                                                                                            server.entry.Port, server.Region,
                                                                                                                            server.entry.GameModule, server.entry.GameType, server.entry.Map, "", "",
                                                                                                                            server.entry.MaxPlayerCount,
                                                                                                                            server.entry.IsOfficial), joindata.PeerIndex, joindata.SessionKey))));
                        server.PlayerCount++;
                    });

                    break;

                default:
                    users.ForEach(u =>
                                  u.QueuedMessages.Enqueue(
                                      new RestDataResponseMessage(
                                          JoinCustomGameResultMessage.CreateFailed(joindata.CustomGameJoinResponse))));

                    break;
                }
            }

            response.SetSuccessful(true, "ResultFromServerTask");
        }
예제 #23
0
        /// <summary>
        /// Dispatch the HttpRequest message to the appropriate service
        /// </summary>
        internal bool Dispatch(ServiceDispatcher serviceDispatcher, RestRequestMessage requestMessage, RestResponseMessage responseMessage)
        {
            // Allow message inspectors to inspect the message before next stage
            try
            {
                this.m_traceSource.TraceEvent(TraceEventType.Verbose, 0, "Begin endpoint dispatch of {0} {1} > {2}", requestMessage.Method, requestMessage.Url, this.m_serviceEndpoint.Description.Contract);

                foreach (var mfi in this.m_messageInspector)
                {
                    mfi.AfterReceiveRequest(requestMessage);
                }

                var ops = this.m_serviceEndpoint.Operations.Where(o => o.Dispatcher.CanDispatch(requestMessage));
                if (ops.Count() == 0)
                {
                    throw new FaultException(404, $"Resource not Found - {requestMessage.Url.AbsolutePath}");
                }
                var op = ops.FirstOrDefault(o => requestMessage.Method.ToLowerInvariant() == o.Description.Method.ToLowerInvariant());
                if (op == null)
                {
                    throw new FaultException(405, "Method not permitted");
                }

                RestOperationContext.Current.EndpointOperation = op;
                op.Dispatcher.Dispatch(serviceDispatcher, requestMessage, responseMessage);

                // Allow message inspectors to inspect before sending response
                foreach (var mfi in this.m_messageInspector)
                {
                    mfi.BeforeSendResponse(responseMessage);
                }

                return(true);
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                return(serviceDispatcher.HandleFault(e, responseMessage));
            }
        }
 /// <summary>
 /// Apply the service policy
 /// </summary>
 public void Apply(RestRequestMessage request)
 {
     if (request.Headers["X-OIZMagic"] == ApplicationContext.Current.ExecutionUuid.ToString() ||
         request.UserAgent == $"SanteDB-DC {ApplicationContext.Current.ExecutionUuid}" ||
         ApplicationContext.Current.ExecutionUuid.ToString() == ApplicationContext.Current.ConfigurationManager.GetAppSetting("http.bypassMagic"))
     {
         ;
     }
     else
     {
         // Something wierd with the appp, show them the nice message
         if (request.UserAgent.StartsWith("SanteDB"))
         {
             throw new FaultException <String>(403, "Hmm, something went wrong. For security's sake we can't show the information you requested. Perhaps restarting the application will help");
         }
         else // User is using a browser to try and access this? How dare they
         {
             RestOperationContext.Current.OutgoingResponse.ContentType = "text/html";
             throw new FaultException <Stream>(403, new GZipStream(typeof(AgsMagicServiceBehavior).Assembly.GetManifestResourceStream("SanteDB.DisconnectedClient.Ags.Resources.antihaxor"), SharpCompress.Compressors.CompressionMode.Decompress));
         }
     }
 }
        private void HandleRegisterCustomGameMessage(RestDataRequestMessage restDataRequestMessage,
                                                     RegisterCustomGameMessage messageContent,
                                                     ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(restDataRequestMessage.SessionCredentials);

            if (user == default)
            {
                return;
            }
            user.HostedServer = new CommunityServerEntry(new GameServerEntry(CustomBattleId.NewGuid(),
                                                                             messageContent.ServerName,
                                                                             HttpContext.Connection.RemoteIpAddress.ToString(), messageContent.Port, "EU",
                                                                             messageContent.GameModule, messageContent.GameType,
                                                                             messageContent.Map, 1, messageContent.MaxPlayerCount, true,
                                                                             !(messageContent.GamePassword == null || messageContent.GamePassword.IsEmpty())));
            Console.WriteLine(
                $"New Server: {HttpContext.Connection.RemoteIpAddress} {messageContent.Port}");
            user.ConnectedServer    = user.HostedServer.entry.Id;
            response.FunctionResult =
                new RestDataFunctionResult(new RegisterCustomGameResult(true));
            response.SetSuccessful(true, "ResultFromServerTask");
        }
        private void HandleLogin(RestDataRequestMessage message, InitializeSession messageContent,
                                 ref RestResponse response, RestRequestMessage request)
        {
            var session = new SessionCredentials(messageContent.PeerId, SessionKey.NewGuid());

            var playerdata = new PlayerData();

            playerdata.FillWithNewPlayer(messageContent.PlayerId,
                                         new[] { "FreeForAll", "Captain", "Siege", "Duel", "TeamDeathMatch", "FreeForAll" });
            playerdata.LastPlayerName = messageContent.PlayerName;
            playerdata.LastGameTypes  = new[] { "Captain" };

            var user = new User
            {
                Id = session, QueuedMessages = new Queue <RestResponseMessage>(), PlayerData = playerdata
            };

            if (messageContent.PlayerId.IsValidSteamId())
            {
                if (_context.SteamIDS.Contains(messageContent.PlayerId.Id2))
                {
                    user.CanHost = true;
                }
            }

            var userStatus = GetServerStatusForUser(user);

            _context.Users.Add(user);
            var initializeSessionResponse = new InitializeSessionResponse(playerdata, userStatus
                                                                          );

            response.FunctionResult =
                new RestDataFunctionResult(new LoginResult(session.PeerId, session.SessionKey,
                                                           initializeSessionResponse));
            response.UserCertificate = session.SessionKey.ToByteArray();
            response.SetSuccessful(true, "ResultFromServerTask");
        }
예제 #27
0
        /// <summary>
        /// Serialize the request for the operation
        /// </summary>
        public void DeserializeRequest(EndpointOperation operation, RestRequestMessage request, object[] parameters)
        {
            try
            {
                var         httpRequest       = RestOperationContext.Current.IncomingRequest;
                string      contentTypeHeader = httpRequest.Headers["Content-Type"];
                ContentType contentType       = null;
                if (!String.IsNullOrEmpty(contentTypeHeader))
                {
                    contentType = new ContentType(contentTypeHeader);
                }

                for (int pNumber = 0; pNumber < parameters.Length; pNumber++)
                {
                    var parm = operation.Description.InvokeMethod.GetParameters()[pNumber];

                    // TODO: Look for MessageFormatAttribute for override

                    // Simple parameter
                    if (parameters[pNumber] != null)
                    {
                        continue; // dispatcher already populated
                    }
                    else
                    {
                        switch (contentType.MediaType)
                        {
                        case "application/xml":
                            if (!this.m_serializers.TryGetValue(parm.ParameterType, out XmlSerializer serializer))
                            {
                                serializer = new XmlSerializer(parm.ParameterType);
                                this.m_serializers.TryAdd(parm.ParameterType, serializer);
                            }
                            var requestObject = serializer.Deserialize(request.Body);
                            parameters[pNumber] = requestObject;
                            break;

                        case "application/json":
                            using (var sr = new StreamReader(request.Body))
                            {
                                JsonSerializer jsz = new JsonSerializer()
                                {
                                    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
                                    TypeNameHandling = TypeNameHandling.All
                                };
                                jsz.Converters.Add(new StringEnumConverter());
                                var dserType = parm.ParameterType;
                                parameters[pNumber] = jsz.Deserialize(sr, dserType);
                            }
                            break;

                        case "application/octet-stream":
                            parameters[pNumber] = request.Body;
                            break;

                        case "application/x-www-form-urlencoded":
                            NameValueCollection nvc = new NameValueCollection();
                            using (var sr = new StreamReader(request.Body))
                            {
                                var ptext = sr.ReadToEnd();
                                var parms = ptext.Split('&');
                                foreach (var p in parms)
                                {
                                    var parmData = p.Split('=');
                                    parmData[1] += new string('=', parmData.Length - 2);
                                    nvc.Add(WebUtility.UrlDecode(parmData[0]), WebUtility.UrlDecode(parmData[1]));
                                }
                            }
                            parameters[pNumber] = nvc;
                            break;

                        default:
                            throw new InvalidOperationException("Invalid request format");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceEvent(TraceEventType.Error, e.HResult, e.ToString());
                throw;
            }
        }
예제 #28
0
 /// <summary>
 /// Implemented below
 /// </summary>
 public abstract void DeserializeRequest(EndpointOperation operation, RestRequestMessage request, object[] parameters);
예제 #29
0
        /// <summary>
        /// Deserialize the request
        /// </summary>
        public override void DeserializeRequest(EndpointOperation operation, RestRequestMessage request, object[] parameters)
        {
            try
            {
#if DEBUG
                this.m_traceSource.TraceInfo("Received request from: {0}", RestOperationContext.Current.IncomingRequest.RemoteEndPoint);
#endif

                var    httpRequest = RestOperationContext.Current.IncomingRequest;
                string contentType = httpRequest.Headers["Content-Type"]?.ToLowerInvariant();

                for (int pNumber = 0; pNumber < parameters.Length; pNumber++)
                {
                    var parm = operation.Description.InvokeMethod.GetParameters()[pNumber];

                    // Simple parameter
                    if (parameters[pNumber] != null)
                    {
                        continue; // dispatcher already populated
                    }
                    // Use XML Serializer
                    else if (contentType?.StartsWith("application/xml") == true)
                    {
                        using (XmlReader bodyReader = XmlReader.Create(request.Body))
                        {
                            while (bodyReader.NodeType != XmlNodeType.Element)
                            {
                                bodyReader.Read();
                            }

                            Type eType = s_knownTypes.FirstOrDefault(o => o.GetCustomAttribute <XmlRootAttribute>()?.ElementName == bodyReader.LocalName &&
                                                                     o.GetCustomAttribute <XmlRootAttribute>()?.Namespace == bodyReader.NamespaceURI);
                            var serializer = XmlModelSerializerFactory.Current.CreateSerializer(eType);
                            parameters[pNumber] = serializer.Deserialize(request.Body);
                        }
                    }
                    else if (contentType?.StartsWith("application/json+sdb-viewmodel") == true)
                    {
                        var viewModel = httpRequest.Headers["X-SanteDB-ViewModel"] ?? httpRequest.QueryString["_viewModel"];

                        // Create the view model serializer
                        var viewModelSerializer = new JsonViewModelSerializer();
                        viewModelSerializer.LoadSerializerAssembly(typeof(ActExtensionViewModelSerializer).Assembly);

                        if (!String.IsNullOrEmpty(viewModel))
                        {
                            var viewModelDescription = ApplicationContext.Current.GetService <IAppletManagerService>()?.Applets.GetViewModelDescription(viewModel);
                            viewModelSerializer.ViewModel = viewModelDescription;
                        }
                        else
                        {
                            viewModelSerializer.ViewModel = m_defaultViewModel;
                        }

                        using (var sr = new StreamReader(request.Body))
                            parameters[pNumber] = viewModelSerializer.DeSerialize(sr, parm.ParameterType);
                    }
                    else if (contentType?.StartsWith("application/json") == true)
                    {
                        using (var sr = new StreamReader(request.Body))
                            using (var jsr = new JsonTextReader(sr))
                            {
                                JsonSerializer jsz = new JsonSerializer()
                                {
                                    SerializationBinder            = new ModelSerializationBinder(parm.ParameterType),
                                    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
                                    TypeNameHandling = TypeNameHandling.All
                                };
                                jsz.Converters.Add(new StringEnumConverter());

                                // Can the binder resolve the type from the message?
                                parameters[pNumber] = jsz.Deserialize(jsr, parm.ParameterType);
                            }
                    }
                    else if (contentType == "application/octet-stream")
                    {
                        parameters[pNumber] = request.Body;
                    }
                    else if (contentType == "application/x-www-form-urlencoded")
                    {
                        NameValueCollection nvc = new NameValueCollection();
                        using (var sr = new StreamReader(request.Body))
                        {
                            var ptext = sr.ReadToEnd();
                            var parms = ptext.Split('&');
                            foreach (var p in parms)
                            {
                                var parmData = p.Split('=');
                                nvc.Add(WebUtility.UrlDecode(parmData[0]), WebUtility.UrlDecode(parmData[1]));
                            }
                        }
                        parameters[pNumber] = nvc;
                    }
                    else if (contentType != null)// TODO: Binaries
                    {
                        throw new InvalidOperationException("Invalid request format");
                    }
                }
            }
            catch (Exception e)
            {
                this.m_traceSource.TraceError("Error de-serializing dispatch request: {0}", e.ToString());
                throw;
            }
        }
        private void HandleUpdateShownBadgeIdMessage(RestDataRequestMessage message,
                                                     UpdateShownBadgeIdMessage messagecontent, ref RestResponse response, RestRequestMessage request)
        {
            var user = _context.FindUserBySessionCredentials(message.SessionCredentials);

            if (user == default)
            {
                return;
            }
            user.PlayerData.ShownBadgeId = messagecontent.ShownBadgeId;

            response.SetSuccessful(true, "ResultFromServerTask");
        }