예제 #1
0
 /// <summary>
 /// Install the specified package
 /// </summary>
 public void Install(string packageId)
 {
     try
     {
         if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkAvailable)
         {
             var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
             amiClient.Client.Credentials      = this.GetCredentials(amiClient.Client);
             amiClient.Client.ProgressChanged += (o, e) => ApplicationContext.Current.SetProgress(String.Format(Strings.locale_downloading, packageId), e.Progress);
             amiClient.Client.Description.Endpoint[0].Timeout = 30000;
             // Fetch the applet package
             using (var ms = amiClient.DownloadApplet(packageId))
             {
                 var package = AppletPackage.Load(ms);
                 this.m_tracer.TraceInfo("Upgrading {0}...", package.Meta.ToString());
                 ApplicationContext.Current.GetService <IAppletManagerService>().Install(package, true);
                 // ApplicationContext.Current.Exit(); // restart
             }
         }
         else
         {
             return;
         }
     }
     catch (Exception ex)
     {
         this.m_tracer.TraceError("Error contacting AMI: {0}", ex.Message);
         throw new InvalidOperationException(Strings.err_updateFailed);
     }
 }
        /// <summary>
        /// Get a service client
        /// </summary>
        protected AmiServiceClient GetClient(IPrincipal principal = null)
        {
            var retVal = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

            if (principal == null)
            {
                principal = AuthenticationContext.Current.Principal;
            }

            // Don't allow anonymous principals
            if (!principal.Identity.IsAuthenticated ||
                principal == AuthenticationContext.SystemPrincipal ||
                principal == AuthenticationContext.AnonymousPrincipal)
            {
                using (AuthenticationContextExtensions.TryEnterDeviceContext())
                {
                    retVal.Client.Credentials = retVal.Client.Description.Binding.Security.CredentialProvider.GetCredentials(AuthenticationContext.Current.Principal);
                }
            }
            else
            {
                retVal.Client.Credentials = retVal.Client.Description.Binding.Security.CredentialProvider.GetCredentials(principal);
            }
            return(retVal);
        }
        /// <summary>
        /// Inserts the specified identified data in the back-end
        /// </summary>
        public void Insert(IdentifiedData data)
        {
            try
            {
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                if (amiClient.Client.Credentials == null)
                {
                    return;
                }

                switch (data.GetType().Name)
                {
                case "AuditSubmission":
                    // Only send audits over wifi
                    if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkWifi ||
                        ApplicationContext.Current.GetService <IQueueManagerService>().Admin.Count() > 10)
                    {
                        amiClient.SubmitAudit(data as AuditSubmission);
                    }
                    break;

                default:
                    throw new NotSupportedException($"AMI servicing not supported for {data.GetType().Name}");
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex);
                throw;
            }
        }
        /// <summary>
        /// Perform the GET operation
        /// </summary>
        public TModel Get <TModel>(Guid key, Guid?versionKey, IntegrationQueryOptions options = null) where TModel : IdentifiedData
        {
            try
            {
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                amiClient.Client.Requesting += IntegrationQueryOptions.CreateRequestingHandler(options);
                amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                if (amiClient.Client.Credentials == null)
                {
                    return(null);
                }

                switch (typeof(TModel).Name)
                {
                case "SecurityUser":
                    return(amiClient.GetUser(key) as TModel);

                default:
                    throw new NotSupportedException($"AMI servicing not supported for {typeof(TModel).Name}");
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex);
                throw;
            }
        }
        /// <summary>
        /// Returns true if the service is available
        /// </summary>
        /// <returns></returns>
        public bool IsAvailable()
        {
            try
            {
                //var restClient = ApplicationContext.Current.GetRestClient("hdsi");
                var networkInformationService = ApplicationContext.Current.GetService <INetworkInformationService>();
                if (networkInformationService.IsNetworkAvailable)
                {
                    if (this.m_lastPing < DateTime.Now.AddSeconds(60))
                    {
                        var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                        amiClient.Client.Credentials = new NullCredentials();
                        amiClient.Client.Description.Endpoint[0].Timeout = 5000;
                        this.m_lastPing = DateTime.Now;
                        return(amiClient.Ping());
                    }

                    return(true);
                }

                return(false);
            }
            catch (Exception e)
            {
                this.m_tracer.TraceInfo($"Unable to determine network state: {e}");
                return(false);
            }
        }
        /// <summary>
        /// Attempt an update on the specified resource
        /// </summary>
        public void Update(IdentifiedData data, bool forceUpdate = false)
        {
            try
            {
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                if (amiClient.Client.Credentials == null)
                {
                    return;
                }

                switch (data.GetType().Name)
                {
                case "SecurityUser":
                    amiClient.UpdateUser(data.Key.Value, new SecurityUserInfo(data as SecurityUser));
                    break;

                default:
                    throw new NotSupportedException($"AMI servicing not supported for {data.GetType().Name}");
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex);
                throw;
            }
        }
        /// <summary>
        /// Find the specified object
        /// </summary>
        public Bundle Find <TModel>(Expression <Func <TModel, bool> > predicate, int offset, int?count, IntegrationQueryOptions options = null) where TModel : IdentifiedData
        {
            try
            {
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                amiClient.Client.Requesting += IntegrationQueryOptions.CreateRequestingHandler(options);
                amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);

                if (amiClient.Client.Credentials == null)
                {
                    return(null);
                }

                switch (typeof(TModel).Name)
                {
                case "SecurityUser":
                    return(new Bundle
                    {
                        Item = amiClient.GetUsers((Expression <Func <SecurityUser, bool> >)(Expression) predicate).CollectionItem.OfType <SecurityUserInfo>().Select(o => o.Entity as IdentifiedData).ToList()
                    });

                default:
                    return(new Bundle
                    {
                        Item = amiClient.Query <TModel>((Expression <Func <TModel, bool> >)(Expression) predicate, offset, count, out int _).CollectionItem.OfType <IdentifiedData>().ToList()
                    });
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex);
                throw;
            }
        }
예제 #8
0
        public Object UpdateSecurityUser([RestMessage(RestMessageFormat.SimpleJson)] SecurityUserInfo user)
        {
            var localSecSrv = ApplicationContext.Current.GetService <IRepositoryService <SecurityUser> >();

            var amiServ = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

            if (user.PasswordOnly)
            {
                var idp = ApplicationContext.Current.GetService <IIdentityProviderService>();
                idp.ChangePassword(user.Entity.UserName.ToLower(), user.Entity.Password, AuthenticationContext.Current.Principal);
                return(AuthenticationContext.Current.Session);
            }
            else
            {
                // Session
                amiServ.Client.Credentials = new TokenCredentials(AuthenticationContext.Current.Principal);
                var remoteUser = amiServ.GetUser(user.Entity.Key.Value);
                remoteUser.Entity.Email       = user.Entity.Email;
                remoteUser.Entity.PhoneNumber = user.Entity.PhoneNumber;
                // Save the remote user in the local
                localSecSrv.Save(remoteUser.Entity);
                amiServ.UpdateUser(remoteUser.Entity.Key.Value, remoteUser);
                return(remoteUser.Entity);
            }
        }
 /// <summary>
 /// Get the reset mechanisms
 /// </summary>
 public List <TfaMechanismInfo> GetResetMechanisms()
 {
     this.EnsureAuthenticated();
     using (AmiServiceClient amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami")))
     {
         var authContext = AuthenticationContext.Current;
         AuthenticationContext.Current = this.m_authContext;
         var retVal = amiClient.GetTwoFactorMechanisms().CollectionItem;
         AuthenticationContext.Current = authContext;
         return(retVal);
     }
 }
예제 #10
0
        public ActionResult LeaveRealm(LeaveRealmModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var realm = unitOfWork.RealmRepository.FindById(model.CurrentRealm.Id);

                    if (realm == null)
                    {
                        TempData["error"] = Locale.RealmNotFound;
                        return(RedirectToAction("Index"));
                    }

                    MvcApplication.MemoryCache.Set(RealmConfig.RealmCacheKey, false, ObjectCache.InfiniteAbsoluteExpiration);

                    using (var amiServiceClient = new AmiServiceClient(new RestClientService(Constants.Ami, this.HttpContext)))
                    {
                        var currentDevice = amiServiceClient.GetDevices(d => d.Name == realm.DeviceId).CollectionItem.FirstOrDefault(d => d.Name == realm.DeviceId);

                        if (currentDevice != null)
                        {
                            currentDevice.Device.ObsoletedByKey = Guid.Parse(this.User.Identity.GetUserId());
                            currentDevice.Device.ObsoletionTime = DateTimeOffset.Now;
                            amiServiceClient.UpdateDevice(currentDevice.Id.ToString(), currentDevice);
                        }
                    }

                    realm.ObsoletionTime = DateTime.UtcNow;

                    // delete all the local references to the users when leaving a realm to avoid
                    // conflicts such as multiple accounts named "administrator" etc.
                    unitOfWork.RealmRepository.Delete(realm);
                    unitOfWork.Save();

                    this.Response.Cookies.Remove("access_token");
                    HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

                    TempData["success"] = Locale.RealmLeftSuccessfully;

                    return(RedirectToAction("JoinRealm", "Realm"));
                }
            }
            catch (Exception e)
            {
                Trace.TraceError($"Unable to leave realm: { e }");
            }

            TempData["error"] = Locale.UnableToLeaveRealm;

            return(View(model));
        }
예제 #11
0
        /// <summary>
        /// Install the specified package
        /// </summary>
        public void Install(string packageId)
        {
            try
            {
                if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkAvailable)
                {
                    var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

                    using (this.Authenticate(amiClient.Client, out Credentials credentials))
                    {
                        amiClient.Client.Credentials      = credentials;
                        amiClient.Client.ProgressChanged += (o, e) => ApplicationContext.Current.SetProgress(string.Format(Strings.locale_downloading, packageId), e.Progress);
                        amiClient.Client.Description.Endpoint[0].Timeout = 30000;

                        // Fetch the applet package
                        if (string.IsNullOrEmpty(this.m_configuration.AppletSolution))
                        {
                            using (var ms = amiClient.DownloadApplet(packageId))
                            {
                                var package = AppletPackage.Load(ms);
                                this.m_tracer.TraceInfo("Upgrading {0}...", package.Meta.ToString());
                                ApplicationContext.Current.GetService <IAppletManagerService>().Install(package, true);
                                ApplicationServiceContext.Current.GetService <ITickleService>().SendTickle(new Tickle(Guid.Empty, TickleType.Information, string.Format(Strings.locale_updateInstalled, package.Meta.Id, package.Meta.Version)));

                                // ApplicationContext.Current.Exit(); // restart
                            }
                        }
                        else
                        {
                            using (var ms = new MemoryStream(amiClient.Client.Get($"AppletSolution/{this.m_configuration.AppletSolution}/applet/{packageId}")))
                            {
                                var package = AppletPackage.Load(ms);
                                this.m_tracer.TraceInfo("Upgrading {0}...", package.Meta.ToString());
                                ApplicationContext.Current.GetService <IAppletManagerService>().Install(package, true);
                                ApplicationServiceContext.Current.GetService <ITickleService>().SendTickle(new Tickle(Guid.Empty, TickleType.Information, string.Format(Strings.locale_updateInstalled, package.Meta.Id, package.Meta.Version)));

                                // ApplicationContext.Current.Exit(); // restart
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex.Message);
                throw new InvalidOperationException(Strings.err_updateFailed);
            }
        }
        /// <summary>
        /// Gets the security user.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>Returns the security user for the given key or null if no security user is found.</returns>
        public SecurityUser GetSecurityUser(Guid key)
        {
            try
            {
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                amiClient.Client.Requesting += IntegrationQueryOptions.CreateRequestingHandler(null);
                amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);

                return(amiClient.GetUser(key)?.Entity);
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex);
                throw;
            }
        }
예제 #13
0
        public DiagnosticReport PostBugReport([RestMessage(RestMessageFormat.Json)] BugReport report)
        {
            report.ApplicationInfo = new ApplicationInfo(false);

            if (report.IncludeData)
            {
                var logConfig = ApplicationContext.Current.Configuration.GetSection <DiagnosticsConfigurationSection>().TraceWriter.FirstOrDefault(o => o.TraceWriter.GetType() == typeof(FileTraceWriter));

                using (MemoryStream ms = new MemoryStream())
                {
                    using (GZipStream gz = new GZipStream(ms, CompressionMode.Compress))
                        ApplicationContext.Current.Configuration.Save(gz);

                    report.Attachments = new List <DiagnosticAttachmentInfo>()
                    {
                        this.CreateGZipLogAttachment(logConfig.InitializationData + ".log"),
                        this.CreateGZipLogAttachment(logConfig.InitializationData + ".log.001", true),
                        new DiagnosticBinaryAttachment()
                        {
                            Content = ms.ToArray(), FileDescription = "SanteDB.config.gz", FileName = "SanteDB.config.gz", Id = "config"
                        }
                    };
                }
            }

            // submit
            AmiServiceClient amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

            try
            {
                return(amiClient.SubmitDiagnosticReport(new DiagnosticReport()
                {
                    ApplicationInfo = (report.ApplicationInfo as ApplicationInfo)?.ToDiagnosticReport(),
                    CreatedBy = report.CreatedBy,
                    CreatedByKey = report.CreatedByKey,
                    CreationTime = DateTime.Now,
                    Attachments = report.Attachments,
                    Note = report.Note,
                    Submitter = AuthenticationContext.Current.Session.UserEntity
                }));
            }
            catch (Exception e)
            {
                this.m_tracer.TraceError("Error filing bug report: {0}", e);
                throw;
            }
        }
예제 #14
0
        public SecurityUser UpdateSecurityUser([RestMessage(RestMessageFormat.SimpleJson)] SecurityUser user)
        {
            var localSecSrv = ApplicationContext.Current.GetService <ISecurityRepositoryService>();

            var amiServ = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

            // Session
            amiServ.Client.Credentials = new TokenCredentials(AuthenticationContext.Current.Principal);
            var remoteUser = amiServ.GetUser(user.Key.ToString());

            remoteUser.User.Email       = user.Email;
            remoteUser.User.PhoneNumber = user.PhoneNumber;
            // Save the remote user in the local
            localSecSrv.SaveUser(remoteUser.User);
            amiServ.UpdateUser(remoteUser.UserId.Value, remoteUser);
            return(remoteUser.User);
        }
예제 #15
0
        /// <summary>
        /// Send the verification code
        /// </summary>
        public void SendVerificationCode(Guid mechanism, string challengeResponse, string userName, string scope)
        {
            this.EnsureAuthenticated();
            using (AmiServiceClient amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami")))
            {
                var authContext = AuthenticationContext.Current;
                AuthenticationContext.Current = this.m_authContext;

                // Next I have to request a TFA secret!!
                amiClient.SendTfaSecret(new  TfaRequestInfo()
                {
                    ResetMechanism = mechanism,
                    Verification   = challengeResponse,
                    UserName       = userName,
                    Purpose        = scope
                });

                AuthenticationContext.Current = authContext;
            }
        }
예제 #16
0
 /// <summary>
 /// Get the server version of a package
 /// </summary>
 public AppletInfo GetServerVersion(string packageId)
 {
     try
     {
         if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkAvailable)
         {
             var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
             amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
             return(amiClient.StatUpdate(packageId));
         }
         else
         {
             return(null);
         }
     }
     catch (Exception ex)
     {
         this.m_tracer.TraceError("Error contacting AMI: {0}", ex.Message);
         throw;
     }
 }
예제 #17
0
        /// <summary>
        /// Check for updates
        /// </summary>
        public void AutoUpdate()
        {
            // Check for updates
            if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkAvailable)
            {
                try
                {
                    ApplicationContext.Current.SetProgress(Strings.locale_updateCheck, 0.5f);

                    // Check for new applications
                    var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                    amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                    amiClient.Client.Description.Endpoint[0].Timeout = 10000;
                    if (amiClient.Ping())
                    {
                        amiClient.Client.Description.Endpoint[0].Timeout = 30000;
                        foreach (var i in amiClient.GetApplets().CollectionItem)
                        {
                            var installed = ApplicationContext.Current.GetService <IAppletManagerService>().GetApplet(i.AppletInfo.Id);
                            if (installed == null ||
                                new Version(installed.Info.Version) < new Version(i.AppletInfo.Version) &&
                                ApplicationContext.Current.Configuration.GetSection <AppletConfigurationSection>().AutoUpdateApplets&&
                                ApplicationContext.Current.Confirm(String.Format(Strings.locale_upgradeConfirm, i.AppletInfo.Names[0].Value, i.AppletInfo.Version, installed.Info.Version)))
                            {
                                this.Install(i.AppletInfo.Id);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.m_tracer.TraceError("Error checking for updates: {0}", ex.Message);
                }
            }
            ;
            this.m_checkedForUpdates = true;
        }
예제 #18
0
        /// <summary>
        /// Get the server version of a package
        /// </summary>
        public AppletInfo GetServerVersion(string packageId)
        {
            try
            {
                if (ApplicationContext.Current.GetService <INetworkInformationService>().IsNetworkAvailable)
                {
                    var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                    using (this.Authenticate(amiClient.Client, out Credentials credentials))
                    {
                        amiClient.Client.Credentials = credentials;

                        if (string.IsNullOrEmpty(this.m_configuration.AppletSolution))
                        {
                            return(amiClient.StatUpdate(packageId));
                        }

                        var headers = amiClient.Client.Head($"AppletSolution/{this.m_configuration.AppletSolution}/applet/{packageId}");
                        headers.TryGetValue("X-SanteDB-PakID", out string packId);
                        headers.TryGetValue("ETag", out string versionKey);

                        return(new AppletInfo
                        {
                            Id = packageId,
                            Version = versionKey
                        });
                    }
                }

                return(null);
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error contacting AMI: {0}", ex.Message);
                throw;
            }
        }
예제 #19
0
 /// <summary>
 /// Returns true if the service is available
 /// </summary>
 /// <returns></returns>
 public bool IsAvailable()
 {
     try
     {
         //var restClient = ApplicationContext.Current.GetRestClient("imsi");
         var networkInformationService = ApplicationContext.Current.GetService <INetworkInformationService>();
         if (networkInformationService.IsNetworkAvailable)
         {
             var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
             amiClient.Client.Credentials = new NullCredentials();
             amiClient.Client.Description.Endpoint[0].Timeout = 10000;
             return(amiClient.Ping());
         }
         else
         {
             return(false);
         }
     }
     catch (Exception e)
     {
         this.m_tracer.TraceError($"Unable to determine network state: {e}");
         return(false);
     }
 }
예제 #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SecurityUserService"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 public SecurityUserService(AmiServiceClient client) : base(client)
 {
 }
예제 #21
0
        /// <summary>
        /// Start the application context
        /// </summary>
        public bool Start()
        {
            this.m_tracer.TraceInfo("Starting mini-context");

            String scheme = this.m_configuration.UseTls ? "https" : "http",
                   host   = $"{scheme}://{this.m_configuration.RealmId}:{this.m_configuration.Port}/";

            this.m_tracer.TraceInfo("Contacting {0}", host);
            try
            {
                // Options on AMI
                var optionDescription = new AdminClientDescription()
                {
                    Binding = new ServiceClientBindingDescription()
                    {
                        Security = new SecurityConfigurationDescription()
                    }
                };

                if (!String.IsNullOrEmpty(this.m_configuration.Proxy))
                {
                    this.m_tracer.TraceVerbose("Setting proxy to : {0}", this.m_configuration.Proxy);
                    WebRequest.DefaultWebProxy = new WebProxy(this.m_configuration.Proxy);
                }

                this.m_tracer.TraceVerbose("Setting up endpoint : {0}/ami", host);

                optionDescription.Endpoint.Add(new AdminClientEndpointDescription($"{host}/ami"));
                var amiServiceClient = new AmiServiceClient(new RestClient(optionDescription));

                // get options
                var amiOptions = amiServiceClient.Options();

                // Server version
                if (new Version(amiOptions.InterfaceVersion.Substring(0, amiOptions.InterfaceVersion.LastIndexOf(".")) + ".0") > typeof(AmiServiceClient).Assembly.GetName().Version)
                {
                    throw new InvalidOperationException($"Server version of AMI is too new for this version of console. Expected {typeof(AmiServiceClient).Assembly.GetName().Version} got {amiOptions.InterfaceVersion}");
                }

                foreach (var itm in amiOptions.Endpoints)
                {
                    this.m_tracer.TraceInfo("Server supports {0} at {1}", itm.ServiceType, String.Join(",", itm.BaseUrl).Replace("0.0.0.0", this.m_configuration.RealmId));

                    var config = new AdminClientDescription()
                    {
                        Binding = new ServiceClientBindingDescription()
                    };
                    if (itm.Capabilities.HasFlag(ServiceEndpointCapabilities.Compression))
                    {
                        config.Binding.Optimize = true;
                    }


                    if (itm.Capabilities.HasFlag(ServiceEndpointCapabilities.BearerAuth))
                    {
                        config.Binding.Security = new SecurityConfigurationDescription()
                        {
                            CredentialProvider = new TokenCredentialProvider(),
                            Mode = Core.Http.Description.SecurityScheme.Bearer,
                            PreemptiveAuthentication = true
                        }
                    }
                    ;
                    else if (itm.Capabilities.HasFlag(ServiceEndpointCapabilities.BasicAuth))
                    {
                        if (itm.ServiceType == ServiceEndpointType.AuthenticationService)
                        {
                            config.Binding.Security = new SecurityConfigurationDescription()
                            {
                                CredentialProvider = new OAuth2CredentialProvider(),
                                Mode = Core.Http.Description.SecurityScheme.Basic,
                                PreemptiveAuthentication = true
                            }
                        }
                        ;
                        else
                        {
                            config.Binding.Security = new SecurityConfigurationDescription()
                            {
                                CredentialProvider = new HttpBasicTokenCredentialProvider(),
                                Mode = Core.Http.Description.SecurityScheme.Basic,
                                PreemptiveAuthentication = true
                            }
                        };
                    }

                    config.Endpoint.AddRange(itm.BaseUrl.Select(o => new AdminClientEndpointDescription(o.Replace("0.0.0.0", this.m_configuration.RealmId))));

                    // Add client
                    this.m_restClients.Add(itm.ServiceType, new RestClient(
                                               config
                                               ));
                }

                // Attempt to get server time from clinical interface which should challenge
                this.GetRestClient(ServiceEndpointType.ImmunizationIntegrationService)?.Get("/time");
                return(true);
            }
            catch (Exception ex)
            {
#if DEBUG
                this.m_tracer.TraceError("Cannot start services: {0}", ex);
#else
                this.m_tracer.TraceError("Cannot start services: {0}", ex);
#endif
                return(false);
            }
        }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AuditService"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 public AuditService(AmiServiceClient client) : base(client)
 {
 }
예제 #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SecurityDeviceService"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 public SecurityDeviceService(AmiServiceClient client) : base(client)
 {
 }
예제 #24
0
        /// <summary>
        /// Changes the users password.
        /// </summary>
        /// <param name="userName">The username of the user.</param>
        /// <param name="newPassword">The new password of the user.</param>
        /// <param name="principal">The authentication principal (the user that is changing the password).</param>
        public void ChangePassword(string userName, string newPassword, System.Security.Principal.IPrincipal principal)
        {
            try
            {
                // The principal must change their own password or must have the changepassword credential
                if (!userName.Equals(principal.Identity.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.ChangePassword).Demand();
                }
                else if (!principal.Identity.IsAuthenticated)
                {
                    throw new InvalidOperationException("Unauthenticated principal cannot change user password");
                }

                // Get the user's identity
                var securityUserService = ApplicationContext.Current.GetService <ISecurityRepositoryService>();
                using (AmiServiceClient client = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami")))
                {
                    client.Client.Accept = "application/xml";

                    Guid userId = Guid.Empty;
                    if (principal is ClaimsPrincipal)
                    {
                        var subjectClaim = (principal as ClaimsPrincipal).FindClaim(ClaimTypes.Sid);
                        if (subjectClaim != null)
                        {
                            userId = Guid.Parse(subjectClaim.Value);
                        }
                    }

                    // User ID not found - lookup
                    if (userId == Guid.Empty)
                    {
                        // User service is null
                        var securityUser = securityUserService.GetUser(principal.Identity);
                        if (securityUser == null)
                        {
                            var tuser = client.GetUsers(o => o.UserName == principal.Identity.Name).CollectionItem.FirstOrDefault();
                            if (tuser == null)
                            {
                                throw new ArgumentException(string.Format("User {0} not found", userName));
                            }
                            else
                            {
                                userId = tuser.UserId.Value;
                            }
                        }
                        else
                        {
                            userId = securityUser.Key.Value;
                        }
                    }

                    // Use the current configuration's credential provider
                    var user = new SecurityUserInfo()
                    {
                        UserId   = userId,
                        UserName = userName,
                        Password = newPassword
                    };

                    // Set the credentials
                    client.Client.Credentials = ApplicationContext.Current.Configuration.GetServiceDescription("ami").Binding.Security.CredentialProvider.GetCredentials(principal);

                    client.UpdateUser(user.UserId.Value, user);
                    var localIdp = new LocalIdentityService();

                    // Change locally
                    localIdp.ChangePassword(userName, newPassword);

                    // Audit - Local IDP has alerted this already
                    if (!(localIdp is ISecurityAuditEventSource))
                    {
                        this.SecurityAttributesChanged?.Invoke(this, new SecurityAuditDataEventArgs(user, "password"));
                    }
                }
            }
            catch (Exception e)
            {
                this.m_tracer.TraceError("Error changing password for user {0} : {1}", userName, e);
                throw;
            }
        }
예제 #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AmiServerInformationService"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 public AmiServerInformationService(AmiServiceClient client) : base(client)
 {
 }
        /// <summary>
        /// Run the mail synchronization service
        /// </summary>
        public void Run(object sender, EventArgs e, object[] parameters)
        {
            try
            {
                this.m_jobStateManager.SetState(this, JobStateType.Running);

                // We are to poll for alerts always (never push supported)
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                using (this.GetCredentials(amiClient.Client, out Credentials credentials))
                {
                    amiClient.Client.Credentials = credentials;

                    // When was the last time we polled an alert?
                    var lastSync = this.m_synchronizationLogService.GetLastTime(typeof(MailMessage));
                    var syncTime = new DateTimeOffset(lastSync.GetValueOrDefault());
                    // Poll action for all alerts to "everyone"
                    AmiCollection serverAlerts = amiClient.GetMailMessages(a => a.CreationTime >= syncTime && a.RcptTo.Any(o => o.UserName == "SYSTEM")); // SYSTEM WIDE ALERTS


                    // TODO: We need to filter by users in which this tablet will be interested in
                    ParameterExpression userParameter = Expression.Parameter(typeof(SecurityUser), "u");
                    // User name filter
                    Expression userNameFilter = Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(this.m_securityConfiguration.DeviceName));

                    // Or eith other users which have logged into this tablet
                    foreach (var user in ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Query(u => u.LastLoginTime != null && u.UserName != this.m_securityConfiguration.DeviceName, AuthenticationContext.SystemPrincipal))
                    {
                        userNameFilter = Expression.OrElse(userNameFilter,
                                                           Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName))
                                                           );
                    }

                    ParameterExpression parmExpr       = Expression.Parameter(typeof(MailMessage), "a");
                    Expression          timeExpression = Expression.GreaterThanOrEqual(
                        Expression.Convert(Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("CreationTime")), typeof(DateTimeOffset)),
                        Expression.Constant(syncTime)
                        ),
                    // this tablet expression
                                        userExpression = Expression.Call(
                        (MethodInfo)typeof(Enumerable).GetGenericMethod("Any", new Type[] { typeof(SecurityUser) }, new Type[] { typeof(IEnumerable <SecurityUser>), typeof(Func <SecurityUser, bool>) }),
                        Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("RcptTo")),
                        Expression.Lambda <Func <SecurityUser, bool> >(userNameFilter, userParameter));

                    serverAlerts.CollectionItem = serverAlerts.CollectionItem.Union(amiClient.GetMailMessages(Expression.Lambda <Func <MailMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList();

                    // Import the alerts
                    foreach (var itm in serverAlerts.CollectionItem.OfType <MailMessage>())
                    {
                        this.m_tracer.TraceVerbose("Importing ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject);
                        itm.Body = String.Format("<pre>{0}</pre>", itm.Body);
                        this.m_mailRepository.Broadcast(itm);
                    }

                    this.m_synchronizationLogService.Save(typeof(MailMessage), String.Empty, String.Empty, "Mail", DateTime.Now);

                    // Push alerts which I have created or updated
                    //int tc = 0;
                    //foreach(var itm in this.m_alertRepository.Find(a=> (a.TimeStamp >= lastTime ) && a.Flags != AlertMessageFlags.System, 0, null, out tc))
                    //{
                    //    if (!String.IsNullOrEmpty(itm.To))
                    //    {
                    //        this.m_tracer.TraceVerbose("Sending ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject);
                    //        if (itm.UpdatedTime != null)
                    //            amiClient.UpdateAlert(itm.Key.ToString(), new AlertMessageInfo(itm));
                    //        else
                    //            amiClient.CreateAlert(new AlertMessageInfo(itm));
                    //    }
                    //}
                    this.m_jobStateManager.SetState(this, JobStateType.Completed);
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message);
                this.m_jobStateManager.SetState(this, JobStateType.Aborted);
                this.m_jobStateManager.SetProgress(this, ex.Message, 0.0f);
            }
        }
예제 #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AmiServiceBase"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 protected AmiServiceBase(AmiServiceClient client)
 {
     this.Client = client;
 }
예제 #28
0
        public async Task <ActionResult> JoinRealmAsync(JoinRealmModel model)
        {
            HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            this.Response.Cookies.Remove("access_token");

            if (ModelState.IsValid)
            {
                model.Address = model.Address.HasTrailingBackSlash() ? model.Address.RemoveTrailingBackSlash() : model.Address;
                model.Address = model.Address.HasTrailingForwardSlash() ? model.Address.RemoveTrailingForwardSlash() : model.Address;

                Realm realm = unitOfWork.RealmRepository.Get(r => r.Address == model.Address && r.ObsoletionTime != null).AsEnumerable().SingleOrDefault();

                // remove any leading or trailing spaces
                model.Address = model.Address.Trim();

                // HACK: the UrlAttribute class thinks that http://localhost is not a valid url...
                if (model.Address.StartsWith("http://localhost"))
                {
                    model.Address = model.Address.Replace("http://localhost", "http://127.0.0.1");
                }
                else if (model.Address.StartsWith("https://localhost"))
                {
                    model.Address = model.Address.Replace("https://localhost", "https://127.0.0.1");
                }

                // is the user attempting to join a realm which they have already left?
                if (realm != null)
                {
                    realm.Map(model);
                    realm.ObsoletionTime = null;

                    unitOfWork.RealmRepository.Update(realm);
                    unitOfWork.Save();
                }
                else
                {
                    realm = unitOfWork.RealmRepository.Create();

                    realm.Map(model);
                    realm.DeviceId     = Environment.MachineName + "-" + Guid.NewGuid().ToString().ToUpper();
                    realm.DeviceSecret = Guid.NewGuid().ToString().ToUpper();

                    var activeRealms = unitOfWork.RealmRepository.AsQueryable().Where(r => r.ObsoletionTime == null).AsEnumerable();

                    foreach (var activeRealm in activeRealms)
                    {
                        activeRealm.ObsoletionTime = DateTime.UtcNow;
                        unitOfWork.RealmRepository.Update(activeRealm);
                    }

                    unitOfWork.RealmRepository.Add(realm);
                    unitOfWork.Save();
                }

                try
                {
                    var result = await this.SignInManager.PasswordSignInAsync(model.Username, model.Password, false, false);

                    switch (result)
                    {
                    case SignInStatus.Success:
                        using (var amiServiceClient = new AmiServiceClient(new RestClientService(Constants.Ami, this.HttpContext, this.SignInManager.AccessToken)))
                        {
                            var synchronizers = amiServiceClient.GetRoles(r => r.Name == "SYNCHRONIZERS").CollectionItem.FirstOrDefault();
                            var device        = amiServiceClient.GetRoles(r => r.Name == "DEVICE").CollectionItem.FirstOrDefault();

                            var securityUserInfo = new SecurityUserInfo
                            {
                                Password = realm.DeviceSecret,
                                Roles    = new List <SecurityRoleInfo>
                                {
                                    device,
                                    synchronizers
                                },
                                UserName = realm.DeviceId,
                                User     = new SecurityUser
                                {
                                    Key          = Guid.NewGuid(),
                                    UserClass    = UserClassKeys.ApplicationUser,
                                    UserName     = realm.DeviceId,
                                    SecurityHash = Guid.NewGuid().ToString()
                                },
                            };

                            amiServiceClient.CreateUser(securityUserInfo);

                            var securityDeviceInfo = new SecurityDeviceInfo
                            {
                                Device = new SecurityDevice
                                {
                                    DeviceSecret = realm.DeviceSecret,
                                    Name         = realm.DeviceId
                                }
                            };

                            amiServiceClient.CreateDevice(securityDeviceInfo);
                        }

                        MvcApplication.MemoryCache.Set(RealmConfig.RealmCacheKey, true, ObjectCache.InfiniteAbsoluteExpiration);
                        break;

                    default:
                        // always sign out the user when joining the realm
                        SignInManager.AuthenticationManager.SignOut();

                        var addedRealm = unitOfWork.RealmRepository.Get(r => r.Address == model.Address).FirstOrDefault();

                        if (addedRealm != null)
                        {
                            unitOfWork.RealmRepository.Delete(addedRealm.Id);
                            unitOfWork.Save();
                        }

                        ModelState.AddModelError("", Locale.IncorrectUsernameOrPassword);

                        return(View(model));
                    }

                    this.TempData["success"] = Locale.RealmJoinedSuccessfully;

                    return(RedirectToAction("Login", "Account"));
                }
                catch (Exception e)
                {
                    Trace.TraceError($"Unable to join realm: {e}");

                    var addedRealm = unitOfWork.RealmRepository.Get(r => r.Address == model.Address).Single();
                    unitOfWork.RealmRepository.Delete(addedRealm.Id);
                    unitOfWork.Save();
                }
                finally
                {
                    // always sign out the user when joining the realm
                    HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
                }
            }

            TempData["error"] = Locale.UnableToJoinRealm;

            return(View(model));
        }
예제 #29
0
        /// <summary>
        /// Start the daemon service
        /// </summary>
        public bool Start()
        {
            this.Starting?.Invoke(this, EventArgs.Empty);

            this.m_configuration         = ApplicationContext.Current.Configuration.GetSection <SynchronizationConfigurationSection>();
            this.m_securityConfiguration = ApplicationContext.Current.Configuration.GetSection <SecurityConfigurationSection>();

            // Application context has started
            ApplicationContext.Current.Started += (o, e) =>
            {
                try
                {
                    // We are to poll for alerts always (never push supported)
                    TimeSpan pollInterval = this.m_configuration.PollInterval == TimeSpan.MinValue ? new TimeSpan(0, 10, 0) : this.m_configuration.PollInterval;
                    this.m_alertRepository = ApplicationContext.Current.GetService <IAlertRepositoryService>();
                    Action <Object> pollAction = null;
                    pollAction = x =>
                    {
                        try
                        {
                            var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                            amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                            // Pull from alerts
                            if (!this.m_isRunning)
                            {
                                return;
                            }

                            // When was the last time we polled an alert?
                            var lastTime = SynchronizationLog.Current.GetLastTime(typeof(AlertMessage));

                            var syncTime = lastTime.HasValue ? new DateTimeOffset(lastTime.Value) : DateTimeOffset.Now.AddHours(-1);

                            // Poll action for all alerts to "everyone"
                            AmiCollection <AlertMessageInfo> serverAlerts = amiClient.GetAlerts(a => a.CreationTime >= lastTime && a.To.Contains("everyone"));


                            // TODO: We need to filter by users in which this tablet will be interested in

                            ParameterExpression userParameter = Expression.Parameter(typeof(SecurityUser), "u");
                            // User name filter
                            Expression userNameFilter = Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(this.m_securityConfiguration.DeviceName));

                            // Or eith other users which have logged into this tablet
                            foreach (var user in ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Query(u => u.LastLoginTime != null && u.UserName != this.m_securityConfiguration.DeviceName))
                            {
                                userNameFilter = Expression.OrElse(userNameFilter,
                                                                   Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName))
                                                                   );
                            }

                            ParameterExpression parmExpr       = Expression.Parameter(typeof(AlertMessage), "a");
                            Expression          timeExpression = Expression.GreaterThanOrEqual(
                                Expression.Convert(Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("CreationTime")), typeof(DateTimeOffset)),
                                Expression.Constant(syncTime)
                                ),
                            // this tablet expression
                                                userExpression = Expression.Call(
                                (MethodInfo)typeof(Enumerable).GetGenericMethod("Any", new Type[] { typeof(SecurityUser) }, new Type[] { typeof(IEnumerable <SecurityUser>), typeof(Func <SecurityUser, bool>) }),
                                Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("RcptTo")),
                                Expression.Lambda <Func <SecurityUser, bool> >(userNameFilter, userParameter));

                            serverAlerts.CollectionItem = serverAlerts.CollectionItem.Union(amiClient.GetAlerts(Expression.Lambda <Func <AlertMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList();

                            // Import the alerts
                            foreach (var itm in serverAlerts.CollectionItem)
                            {
                                this.m_tracer.TraceVerbose("Importing ALERT: [{0}]: {1}", itm.AlertMessage.TimeStamp, itm.AlertMessage.Subject);
                                itm.AlertMessage.Body = String.Format("<pre>{0}</pre>", itm.AlertMessage.Body);
                                this.m_alertRepository.BroadcastAlert(itm.AlertMessage);
                            }

                            // Push alerts which I have created or updated
                            //int tc = 0;
                            //foreach(var itm in this.m_alertRepository.Find(a=> (a.TimeStamp >= lastTime ) && a.Flags != AlertMessageFlags.System, 0, null, out tc))
                            //{
                            //    if (!String.IsNullOrEmpty(itm.To))
                            //    {
                            //        this.m_tracer.TraceVerbose("Sending ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject);
                            //        if (itm.UpdatedTime != null)
                            //            amiClient.UpdateAlert(itm.Key.ToString(), new AlertMessageInfo(itm));
                            //        else
                            //            amiClient.CreateAlert(new AlertMessageInfo(itm));
                            //    }
                            //}

                            SynchronizationLog.Current.Save(typeof(AlertMessage), null, null, null);
                        }
                        catch (Exception ex)
                        {
                            this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message);
                        }
                        finally
                        {
                            // Re-schedule myself in the poll interval time
                            ApplicationContext.Current.GetService <IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                        }
                    };

                    //ApplicationContext.Current.GetService<IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                    this.m_isRunning = true;

                    pollAction(null);
                }
                catch (Exception ex)
                {
                    this.m_tracer.TraceError("Error starting Alert Sync: {0}", ex.Message);
                }
                //this.m_alertRepository.Committed +=
            };

            this.Started?.Invoke(this, EventArgs.Empty);

            return(true);
        }
예제 #30
0
        public List <AppletSolutionInfo> GetAppletSolutions()
        {
            var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));

            return(amiClient.GetAppletSolutions().CollectionItem.OfType <AppletSolutionInfo>().ToList());
        }