コード例 #1
0
        private Customer AuthoriseRequest()
        {
            try {
                string authId = GetAuthId();
                //logger.Debug("Authorising request for sessionid=" + authId + ".");

                if (authId != null)
                {
                    CustomerSession customerSession = CRMSessionManager.Authenticate(authId);
                    if (customerSession == null)
                    {
                        logger.Warn("SIPProvisioningWebService AuthoriseRequest failed for " + authId + ".");
                        throw new UnauthorizedAccessException();
                    }
                    else
                    {
                        Customer customer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customerSession.CustomerUsername);
                        return(customer);
                    }
                }
                else
                {
                    logger.Warn("SIPProvisioningWebService AuthoriseRequest failed no authid header.");
                    throw new UnauthorizedAccessException();
                }
            }
            catch (UnauthorizedAccessException) {
                throw;
            }
            catch (Exception excp) {
                logger.Error("Exception AuthoriseRequest. " + excp.Message);
                throw new Exception("There was an exception authorising the request.");
            }
        }
コード例 #2
0
        private SIPRegistrarBinding GetNextExpiredBinding(DateTimeOffset expiryTime)
        {
            using (var trans = new TransactionScope())
            {
                SIPRegistrarBinding binding = m_bindingsPersistor.Get(b => b.ExpiryTime < expiryTime);

                if (binding != null)
                {
                    if (binding.ExpiryTime < DateTimeOffset.UtcNow.AddSeconds(BINDING_EXPIRY_GRACE_PERIOD * -1))
                    {
                        m_bindingsPersistor.Delete(binding);
                    }
                    else
                    {
                        logger.Warn("A binding returned from the database as expired wasn't. " + binding.SIPAccountName + " and " + binding.MangledContactURI + ", last register " +
                                    binding.LastUpdate.ToString("HH:mm:ss") + ", expiry " + binding.Expiry + ", expiry time " + binding.ExpiryTime.ToString("HH:mm:ss") +
                                    ", checkedtime " + expiryTime.ToString("HH:mm:ss") + ", now " + DateTimeOffset.UtcNow.ToString("HH:mm:ss") + ".");

                        binding = null;
                    }
                }

                trans.Complete();

                return(binding);
            }
        }
コード例 #3
0
        public CustomerSession Authenticate(string sessionId)
        {
            try
            {
                CustomerSession customerSession = m_customerSessionPersistor.Get(s => s.SessionID == sessionId && !s.Expired);
                //CustomerSession customerSession = m_customerSessionPersistor.Get(s => s.Id == sessionId);

                if (customerSession != null)
                {
                    int sessionLengthMinutes = (int)DateTimeOffset.UtcNow.Subtract(customerSession.Inserted).TotalMinutes;
                    //logger.Debug("CustomerSession Inserted=" + customerSession.Inserted.ToString("o") + ", session length=" + sessionLengthMinutes + "mins.");
                    if (sessionLengthMinutes > customerSession.TimeLimitMinutes || sessionLengthMinutes > CustomerSession.MAX_SESSION_LIFETIME_MINUTES)
                    {
                        customerSession.Expired = true;
                        m_customerSessionPersistor.Update(customerSession);
                        return(null);
                    }
                    else
                    {
                        //logger.Debug("Authentication token valid for " + sessionId + ".");
                        return(customerSession);
                    }
                }
                else
                {
                    logger.Warn("Authentication token invalid for " + sessionId + ".");
                    return(null);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Authenticate CustomerSessionManager. " + excp.Message);
                throw;
            }
        }
コード例 #4
0
        public List <SIPProviderBinding> GetSIPProviderBindings(string whereExpression, int offset, int count)
        {
            Customer customer            = AuthoriseRequest();
            string   authoriseExpression = GetAuthorisedWhereExpression(customer, whereExpression);

            if (authoriseExpression.IsNullOrBlank())
            {
                return(SIPProviderBindingsPersistor.Get(null, "providername asc", offset, count));
            }
            else
            {
                return(SIPProviderBindingsPersistor.Get(DynamicExpression.ParseLambda <SIPProviderBinding, bool>(authoriseExpression), "providername asc", offset, count));
            }
        }
コード例 #5
0
        public CustomerSession Authenticate(string username, string password, string ipAddress)
        {
            try
            {
                if (username.IsNullOrBlank() || password.IsNullOrBlank())
                {
                    logger.Debug("Login failed, either username or password was not specified.");
                    return(null);
                }
                else
                {
                    logger.Debug("CustomerSessionManager authenticate requested for username " + username + " from " + ipAddress + ".");

                    // Don't do the password check via the database as different ones have different string case matching.
                    Customer customer = m_customerPersistor.Get(c => c.CustomerUsername == username);

                    if (customer != null && PasswordHash.Hash(password, customer.Salt) == customer.CustomerPassword)
                    {
                        if (!customer.EmailAddressConfirmed)
                        {
                            throw new ApplicationException("Your email address has not yet been confirmed.");
                        }
                        else if (customer.Suspended)
                        {
                            throw new ApplicationException("Your account is suspended.");
                        }
                        else
                        {
                            logger.Debug("Login successful for " + username + ".");

                            string          sessionId       = Crypto.GetRandomByteString(SESSION_ID_STRING_LENGTH / 2);
                            CustomerSession customerSession = new CustomerSession(Guid.NewGuid(), sessionId, customer.CustomerUsername, ipAddress);
                            m_customerSessionPersistor.Add(customerSession);
                            return(customerSession);
                        }
                    }
                    else
                    {
                        logger.Debug("Login failed for " + username + ".");
                        return(null);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Authenticate CustomerSessionManager. " + excp.Message);
                throw;
            }
        }
コード例 #6
0
        public List <SIPProvider> GetSIPProviders(string whereExpression, int offset, int count)
        {
            Customer customer            = AuthoriseRequest();
            string   authoriseExpression = GetAuthorisedWhereExpression(customer, whereExpression);

            if (authoriseExpression.IsNullOrBlank())
            {
                return(SIPProviderPersistor.Get(null, "providername", offset, count));
            }
            else
            {
                //logger.Debug("SIPProvisioningWebService GetSIPProviders for " + customerSession.Customer.CustomerUsername + " and where: " + authoriseExpression + ".");
                return(SIPProviderPersistor.Get(DynamicExpression.ParseLambda <SIPProvider, bool>(authoriseExpression), "providername", offset, count));
            }
        }
コード例 #7
0
        public void Read()
        {
            SipAccountDataStorage = SIPAssetPersistorFactory <SIPAccount> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename);

            SipAccountDataStorage.Added += Account_Added;
            _sipAccountsCache            = SipAccountDataStorage.Get();
        }
コード例 #8
0
        public void Read()
        {
            SIPAssetPersistor <SIPAccount> account = SIPAssetPersistorFactory <SIPAccount> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename);

            _sipAccount = account;
            _accounts   = account.Get();
        }
コード例 #9
0
ファイル: SIPDomainManager.cs プロジェクト: seasky100/Gb28059
        private void LoadSIPDomains()
        {
            try
            {
                List <SIPDomain> sipDomains = m_sipDomainPersistor.Get(null, null, 0, Int32.MaxValue);

                //if (sipDomains == null || sipDomains.Count == 0)
                //{
                //    throw new ApplicationException("No SIP domains could be loaded from the persistence store. There needs to be at least one domain.");
                //}
                //else
                //{
                m_domains.Clear();
                foreach (SIPDomain sipDomain in sipDomains)
                {
                    AddDomain(sipDomain);
                }
                //}
            }
            catch (Exception excp)
            {
                logger.Error("Exception LoadSIPDomains. " + excp.Message);
                throw;
            }
        }
コード例 #10
0
        public void SIPProviderUpdated(SIPProvider sipProvider)
        {
            try
            {
                Logger.Logger.Debug("SIPProviderBindingSynchroniser SIPProviderUpdated for " + sipProvider.Owner +
                                    " and " +
                                    sipProvider.ProviderName + ".");

                SIPProviderBinding existingBinding = m_bindingPersistor.Get(b => b.ProviderId == sipProvider.Id);

                if (sipProvider.RegisterEnabled)
                {
                    if (existingBinding == null)
                    {
                        SIPProviderBinding newBinding = new SIPProviderBinding(sipProvider);
                        m_bindingPersistor.Add(newBinding);
                    }
                    else
                    {
                        existingBinding.SetProviderFields(sipProvider);
                        existingBinding.NextRegistrationTime = DateTime.UtcNow;
                        m_bindingPersistor.Update(existingBinding);
                    }
                }
                else
                {
                    if (existingBinding != null)
                    {
                        if (existingBinding.IsRegistered)
                        {
                            // Let the registration agent know the existing binding should be expired.
                            existingBinding.BindingExpiry        = 0;
                            existingBinding.NextRegistrationTime = DateTime.UtcNow;
                            m_bindingPersistor.Update(existingBinding);
                        }
                        else
                        {
                            m_bindingPersistor.Delete(existingBinding);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception SIPProviderBindingSynchroniser SIPProviderUpdated. ->" + excp.Message);
            }
        }
コード例 #11
0
        protected Customer AuthoriseRequest()
        {
            try
            {
                string authId = ServiceAuthToken.GetAuthId();
                //logger.Debug("Authorising request for sessionid=" + authId + ".");

                if (!authId.IsNullOrBlank())
                {
                    CustomerSession customerSession = CRMSessionManager.Authenticate(authId);
                    if (customerSession == null)
                    {
                        logger.Warn("SIPSorceryAuthenticatedService AuthoriseRequest failed for " + authId + ".");
                        throw new UnauthorizedAccessException();
                    }
                    else
                    {
                        Customer customer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customerSession.CustomerUsername);
                        return(customer);
                    }
                }
                else
                {
                    string apiKey = ServiceAuthToken.GetAPIKey();

                    if (!apiKey.IsNullOrBlank())
                    {
                        Customer customer = CRMCustomerPersistor.Get(c => c.APIKey == apiKey);
                        return(customer);
                    }
                    else
                    {
                        logger.Warn("SIPSorceryAuthenticatedService AuthoriseRequest failed no authid header.");
                        throw new UnauthorizedAccessException();
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                throw;
            }
            catch (Exception excp)
            {
                logger.Error("Exception AuthoriseRequest. " + excp.Message);
                throw new Exception("There was an exception authorising the request.");
            }
        }
コード例 #12
0
        protected void Page_Load(object sender, EventArgs e)
        {
            try {
                logger.Debug("CustomerEmailConfirmation request from " + this.Context.Request.UserHostAddress + " for " + this.Request.QueryString["id"] + ".");

                string id = this.Request.QueryString["id"];
                if (!id.IsNullOrBlank())
                {
                    Guid customerId = new Guid(id);
                    m_crmPersistor = SIPAssetPersistorFactory <Customer> .CreateSIPAssetPersistor(m_crmStorageType, m_crmStorageConnStr, null);

                    Customer customer = m_crmPersistor.Get(customerId);

                    if (customer != null)
                    {
                        if (!customer.EmailAddressConfirmed)
                        {
                            customer.CreatedFromIPAddress  = this.Context.Request.UserHostAddress;
                            customer.EmailAddressConfirmed = true;

                            if (IsValidCustomer(m_validationRules, customer))
                            {
                                m_crmPersistor.Update(customer);
                                m_confirmed           = true;
                                m_confirmMessage.Text = "Thank you, your account has now been activated.";
                            }
                            else
                            {
                                customer.Suspended = true;
                                m_crmPersistor.Update(customer);
                                m_confirmed           = false;
                                m_confirmMessage.Text = "Your account has been confirmed but not approved. You will receive an email within 48 hours if it is approved.";
                            }
                        }
                        else
                        {
                            m_confirmed           = false;
                            m_confirmMessage.Text = "Your account has already been confirmed.";
                        }
                    }
                    else
                    {
                        m_confirmMessage.Text = "No matching customer record could be found. Please check that you entered the confirmation URL correctly.";
                    }
                }
                else
                {
                    m_confirmMessage.Text = "Your account could not be confirmed. Please check that you entered the confirmation URL correctly.";
                }
            }
            catch (Exception excp) {
                logger.Error("Exception CustomerEmailConfirmation. " + excp.Message);
                m_confirmMessage.Text = "There was an error confirming your account. Please check that you entered the confirmation URL correctly.";
            }
        }
コード例 #13
0
        public List <SIPDialogueAsset> GetCalls(string whereExpression, int offset, int count)
        {
            try
            {
                Customer customer = AuthoriseRequest();

                string authorisedExpression = GetAuthorisedWhereExpression(customer, whereExpression);
                //logger.Debug("SIPProvisioningWebService GetCalls for " + customerSession.Customer.CustomerUsername + " and where: " + authoriseExpression + ".");

                if (authorisedExpression.IsNullOrBlank())
                {
                    return(SIPDialoguePersistor.Get(null, null, offset, count));
                }
                else
                {
                    return(SIPDialoguePersistor.Get(DynamicExpression.ParseLambda <SIPDialogueAsset, bool>(authorisedExpression), null, offset, count));
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception GetCalls. " + excp.Message);
                throw;
            }
        }
コード例 #14
0
        protected void Page_Load(object sender, EventArgs e) {

            try {
                logger.Debug("CustomerEmailConfirmation request from " + this.Context.Request.UserHostAddress + " for " + this.Request.QueryString["id"] + ".");

                string id = this.Request.QueryString["id"];
                if (!id.IsNullOrBlank()) {
                    Guid customerId = new Guid(id);
                    m_crmPersistor = SIPAssetPersistorFactory<Customer>.CreateSIPAssetPersistor(m_crmStorageType, m_crmStorageConnStr, null);
                    Customer customer = m_crmPersistor.Get(customerId);

                    if (customer != null) {
                        if (!customer.EmailAddressConfirmed) {
                            customer.CreatedFromIPAddress = this.Context.Request.UserHostAddress;
                            customer.EmailAddressConfirmed = true;

                            if (IsValidCustomer(m_validationRules, customer)) {
                                m_crmPersistor.Update(customer);
                                m_confirmed = true;
                                m_confirmMessage.Text = "Thank you, your account has now been activated.";
                            }
                            else {
                                customer.Suspended = true;
                                m_crmPersistor.Update(customer);
                                m_confirmed = false;
                                m_confirmMessage.Text = "Your account has been confirmed but not approved. You will receive an email within 48 hours if it is approved.";
                            }
                        }
                        else {
                            m_confirmed = false;
                             m_confirmMessage.Text = "Your account has already been confirmed.";
                        }
                    }
                    else {
                        m_confirmMessage.Text = "No matching customer record could be found. Please check that you entered the confirmation URL correctly.";
                    }
                }
                else {
                    m_confirmMessage.Text = "Your account could not be confirmed. Please check that you entered the confirmation URL correctly.";
                }
            }
            catch (Exception excp) {
                logger.Error("Exception CustomerEmailConfirmation. " + excp.Message);
                m_confirmMessage.Text = "There was an error confirming your account. Please check that you entered the confirmation URL correctly.";
            }
        }
コード例 #15
0
 public List <SIPRegistrarBinding> GetRegistrarRecords(string owner, int offset, int count)
 {
     try
     {
         if (owner != null && owner.Trim().Length > 0)
         {
             return(SIPRegistrarBindingPersistor.Get(b => b.Owner == owner, "lastupdate", offset, count));
         }
         else
         {
             logger.Warn("GetRegistrarRecords was called with an empty owner.");
             return(null);
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception GetRegistrarRecords. " + excp.Message);
         throw excp;
     }
 }
コード例 #16
0
        private void LoadSIPDomains()
        {
            try
            {
                var sipDomainList = m_sipDomainPersistor.Get(null, null, 0, Int32.MaxValue);

                if (sipDomainList == null || sipDomainList.Count == 0)
                {
                    throw new ApplicationException("No SIP domains could be loaded from the persistence store. There needs to be at least one domain.");
                }
                else
                {
                    m_domains.Clear();
                    sipDomainList.ForEach(sipDomain => AddDomain(sipDomain));
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception LoadSIPDomains. " + excp.Message);
                throw;
            }
        }
コード例 #17
0
        /// <summary>
        /// 加载设备信息
        /// </summary>
        public void Read()
        {
            SIPAssetPersistor <NvrItem> nvrItem = SIPAssetPersistorFactory <NvrItem> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename);

            SIPAssetPersistor <ChannelItem> nvrChannel = SIPAssetPersistorFactory <ChannelItem> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename);

            NvrItems     = nvrItem;
            ChannelItems = nvrChannel;
            _nvrItems    = nvrItem.Get();
            var nvrChannelItems = nvrChannel.Get();

            foreach (var item in _nvrItems)
            {
                foreach (var channel in nvrChannelItems)
                {
                    if (item.NvrID == channel.NvrID)
                    {
                        item.Add(channel);
                    }
                }
            }
        }
コード例 #18
0
ファイル: SIPNotifierCore.cs プロジェクト: xycui/sipsorcery
        private void Subscribe(SIPTransaction subscribeTransaction)
        {
            try
            {
                SIPRequest sipRequest      = subscribeTransaction.TransactionRequest;
                string     fromUser        = sipRequest.Header.From.FromURI.User;
                string     fromHost        = sipRequest.Header.From.FromURI.Host;
                string     canonicalDomain = GetCanonicalDomain_External(fromHost, true);

                if (canonicalDomain == null)
                {
                    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request for " + fromHost + " rejected as no matching domain found.", null));
                    SIPResponse noDomainResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced");
                    subscribeTransaction.SendFinalResponse(noDomainResponse);
                    return;
                }

                SIPAccount sipAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain);
                SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.RemoteEndPoint, sipRequest, sipAccount, FireProxyLogEvent);

                if (!authenticationResult.Authenticated)
                {
                    // 401 Response with a fresh nonce needs to be sent.
                    SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null);
                    authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                    subscribeTransaction.SendFinalResponse(authReqdResponse);

                    if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden)
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Forbidden " + fromUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom.ToString() + ", " + sipRequest.Header.UserAgent + ".", null));
                    }
                    else
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Authentication required for " + fromUser + "@" + canonicalDomain + " from " + subscribeTransaction.RemoteEndPoint + ".", sipAccount.Owner));
                    }
                    return;
                }
                else
                {
                    if (sipRequest.Header.To.ToTag != null)
                    {
                        // Request is to renew an existing subscription.
                        SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None;
                        string errorResponseReason = null;

                        string sessionID = m_subscriptionsManager.RenewSubscription(sipRequest, out errorResponse, out errorResponseReason);
                        if (errorResponse != SIPResponseStatusCodesEnum.None)
                        {
                            // A subscription renewal attempt failed
                            SIPResponse renewalErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason);
                            subscribeTransaction.SendFinalResponse(renewalErrorResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription renewal failed for event type " + sipRequest.Header.Event + " " + sipRequest.URI.ToString() + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner));
                        }
                        else if (sipRequest.Header.Expires == 0)
                        {
                            // Existing subscription was closed.
                            SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            subscribeTransaction.SendFinalResponse(okResponse);
                        }
                        else
                        {
                            // Existing subscription was found.
                            SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            subscribeTransaction.SendFinalResponse(okResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Subscription renewal for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner));
                            m_subscriptionsManager.SendFullStateNotify(sessionID);
                        }
                    }
                    else
                    {
                        // Authenticated but the this is a new subscription request and authorisation to subscribe to the requested resource also needs to be checked.
                        SIPURI canonicalResourceURI    = sipRequest.URI.CopyOf();
                        string resourceCanonicalDomain = GetCanonicalDomain_External(canonicalResourceURI.Host, true);
                        canonicalResourceURI.Host = resourceCanonicalDomain;
                        SIPAccount resourceSIPAccount = null;

                        if (resourceCanonicalDomain == null)
                        {
                            SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain " + resourceCanonicalDomain + " not serviced");
                            subscribeTransaction.SendFinalResponse(notFoundResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", domain not serviced.", sipAccount.Owner));
                            return;
                        }

                        if (canonicalResourceURI.User != m_wildcardUser)
                        {
                            resourceSIPAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == canonicalResourceURI.User && s.SIPDomain == canonicalResourceURI.Host);

                            if (resourceSIPAccount == null)
                            {
                                SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Requested resource does not exist");
                                subscribeTransaction.SendFinalResponse(notFoundResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", SIP account does not exist.", sipAccount.Owner));
                                return;
                            }
                        }

                        // Check the owner permissions on the requesting and subscribed resources.
                        bool   authorised = false;
                        string adminID    = null;

                        if (canonicalResourceURI.User == m_wildcardUser || sipAccount.Owner == resourceSIPAccount.Owner)
                        {
                            authorised = true;
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccount.Owner));
                        }
                        else
                        {
                            // Lookup the customer record for the requestor and check the administrative level on it.
                            Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccount.Owner);
                            adminID = requestingCustomer.AdminId;
                            if (!resourceSIPAccount.AdminMemberId.IsNullOrBlank() && requestingCustomer.AdminId == resourceSIPAccount.AdminMemberId)
                            {
                                authorised = true;
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor admin permissions for domain " + resourceSIPAccount.AdminMemberId + ".", sipAccount.Owner));
                            }
                            else if (requestingCustomer.AdminId == m_topLevelAdminID)
                            {
                                authorised = true;
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor having top level admin permissions.", sipAccount.Owner));
                            }
                        }

                        if (authorised)
                        {
                            // Request is to create a new subscription.
                            SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None;
                            string errorResponseReason = null;
                            string toTag     = CallProperties.CreateNewTag();
                            string sessionID = m_subscriptionsManager.SubscribeClient(sipAccount.Owner, adminID, sipRequest, toTag, canonicalResourceURI, out errorResponse, out errorResponseReason);

                            if (errorResponse != SIPResponseStatusCodesEnum.None)
                            {
                                SIPResponse subscribeErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason);
                                subscribeTransaction.SendFinalResponse(subscribeErrorResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner));
                            }
                            else
                            {
                                SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                                okResponse.Header.To.ToTag = toTag;
                                okResponse.Header.Expires  = sipRequest.Header.Expires;
                                okResponse.Header.Contact  = new List <SIPContactHeader>()
                                {
                                    new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, subscribeTransaction.LocalSIPEndPoint))
                                };
                                subscribeTransaction.SendFinalResponse(okResponse);
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription accepted for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner));

                                if (sessionID != null)
                                {
                                    m_subscriptionsManager.SendFullStateNotify(sessionID);
                                }
                            }
                        }
                        else
                        {
                            SIPResponse forbiddenResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Requested resource not authorised");
                            subscribeTransaction.SendFinalResponse(forbiddenResponse);
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", requesting account " + sipAccount.Owner + " was not authorised.", sipAccount.Owner));
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception notifiercore subscribing. " + excp.Message + "\r\n" + subscribeTransaction.TransactionRequest.ToString());
                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Error, "Exception notifiercore subscribing. " + excp.Message, null));
                SIPResponse errorResponse = SIPTransport.GetResponse(subscribeTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null);
                subscribeTransaction.SendFinalResponse(errorResponse);
            }
        }
コード例 #19
0
        /// <summary>
        /// Establishes a new call with the client end tied to the proxy. Since the proxy will not be sending any audio the idea is that once
        /// the call is up it should be re-INVITED off somewhere else pronto to avoid the callee sitting their listening to dead air.
        /// </summary>
        /// <param name="dest1">The dial string of the first call to place.</param>
        /// <param name="dest2">The dial string of the second call to place.</param>
        /// <param name="delaySeconds">Delay in seconds before placing the first call. Gives the user a chance to hangup their phone if they are calling themselves back.</param>
        /// <param name="ringTimeoutLeg1">The ring timeout for the first call leg, If 0 the max timeout will be used.</param>
        /// <param name="ringTimeoutLeg1">The ring timeout for the second call leg, If 0 the max timeout will be used.</param>
        /// <param name="customHeadersCallLeg1">A | delimited string that contains a list of custom SIP headers to add to the INVITE request sent for the first call leg.</param>
        /// /// <param name="customHeadersCallLeg2">A | delimited string that contains a list of custom SIP headers to add to the INVITE request sent for the second call leg.</param>
        /// <returns>The result of the call.</returns>
        public void Callback(string dest1, string dest2, int delaySeconds, int ringTimeoutLeg1, int ringTimeoutLeg2, string customHeadersCallLeg1, string customHeadersCallLeg2)
        {
            var ts = new CancellationTokenSource();
            CancellationToken ct = ts.Token;

            try
            {
                if (delaySeconds > 0)
                {
                    delaySeconds = (delaySeconds > MAXCALLBACK_DELAY_SECONDS) ? MAXCALLBACK_DELAY_SECONDS : delaySeconds;
                    Log("Callback app delaying by " + delaySeconds + "s.");
                    Thread.Sleep(delaySeconds * 1000);
                }

                Log("Callback app commencing first leg to " + dest1 + ".");

                SIPEndPoint defaultUDPEP = m_sipTransport.GetDefaultSIPEndPoint(SIPProtocolsEnum.udp);

                SIPRequest firstLegDummyInviteRequest = GetCallbackInviteRequest(defaultUDPEP.GetIPEndPoint(), null);
                ForkCall   firstLegCall = new ForkCall(m_sipTransport, Log_External, m_callManager.QueueNewCall, null, m_username, m_adminMemberId, m_outboundProxy, m_callManager, null);
                m_firstLegDialogue = Dial(firstLegCall, dest1, ringTimeoutLeg1, 0, firstLegDummyInviteRequest, SIPCallDescriptor.ParseCustomHeaders(customHeadersCallLeg1));
                if (m_firstLegDialogue == null)
                {
                    Log("The first call leg to " + dest1 + " was unsuccessful.");
                    return;
                }

                // Persist the dialogue to the database so any hangup can be detected.
                m_sipDialoguePersistor.Add(new SIPDialogueAsset(m_firstLegDialogue));

                SDP    firstLegSDP       = SDP.ParseSDPDescription(m_firstLegDialogue.RemoteSDP);
                string call1SDPIPAddress = firstLegSDP.Connection.ConnectionAddress;
                int    call1SDPPort      = firstLegSDP.Media[0].Port;
                Log("The first call leg to " + dest1 + " was successful, audio socket=" + call1SDPIPAddress + ":" + call1SDPPort + ".");

                Log("Callback app commencing second leg to " + dest2 + ".");

                SIPRequest secondLegDummyInviteRequest = GetCallbackInviteRequest(defaultUDPEP.GetIPEndPoint(), m_firstLegDialogue.RemoteSDP);
                ForkCall   secondLegCall = new ForkCall(m_sipTransport, Log_External, m_callManager.QueueNewCall, null, m_username, m_adminMemberId, m_outboundProxy, m_callManager, null);

                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(CHECK_FIRST_LEG_FOR_HANGUP_PERIOD);

                        Console.WriteLine("Checking if first call leg is still up...");

                        if (ct.IsCancellationRequested)
                        {
                            Console.WriteLine("Checking first call leg task was cancelled.");
                            break;
                        }
                        else
                        {
                            // Check that the first call leg hasn't been hung up.
                            var dialog = m_sipDialoguePersistor.Get(m_firstLegDialogue.Id);
                            if (dialog == null)
                            {
                                Console.WriteLine("First call leg has been hungup.");

                                // The first call leg has been hungup while waiting for the second call.
                                Log("The first call leg was hungup while the second call leg was waiting for an answer.");
                                secondLegCall.CancelNotRequiredCallLegs(CallCancelCause.ClientCancelled);
                                break;
                            }
                        }
                    }

                    Console.WriteLine("Checking first call leg task finished...");
                }, ct);

                SIPDialogue secondLegDialogue = Dial(secondLegCall, dest2, ringTimeoutLeg2, 0, secondLegDummyInviteRequest, SIPCallDescriptor.ParseCustomHeaders(customHeadersCallLeg2));

                ts.Cancel();

                if (secondLegDialogue == null)
                {
                    Log("The second call leg to " + dest2 + " was unsuccessful.");
                    m_firstLegDialogue.Hangup(m_sipTransport, m_outboundProxy);
                    return;
                }

                // Check that the first call leg hasn't been hung up.
                var firstLegDialog = m_sipDialoguePersistor.Get(m_firstLegDialogue.Id);
                if (firstLegDialog == null)
                {
                    // The first call leg has been hungup while waiting for the second call.
                    Log("The first call leg was hungup while waiting for the second call leg.");
                    secondLegDialogue.Hangup(m_sipTransport, m_outboundProxy);
                    return;
                }

                SDP    secondLegSDP      = SDP.ParseSDPDescription(secondLegDialogue.RemoteSDP);
                string call2SDPIPAddress = secondLegSDP.Connection.ConnectionAddress;
                int    call2SDPPort      = secondLegSDP.Media[0].Port;
                Log("The second call leg to " + dest2 + " was successful, audio socket=" + call2SDPIPAddress + ":" + call2SDPPort + ".");

                // Persist the second leg dialogue and update the bridge ID on the first call leg.
                Guid bridgeId = Guid.NewGuid();
                secondLegDialogue.BridgeId = bridgeId;
                m_sipDialoguePersistor.Add(new SIPDialogueAsset(secondLegDialogue));
                m_sipDialoguePersistor.UpdateProperty(firstLegDialog.Id, "BridgeID", bridgeId.ToString());

                //m_callManager.CreateDialogueBridge(m_firstLegDialogue, secondLegDialogue, m_username);

                Log("Re-inviting Callback dialogues to each other.");

                m_callManager.ReInvite(m_firstLegDialogue, secondLegDialogue);
                //m_callManager.ReInvite(secondLegDialogue, m_firstLegDialogue.RemoteSDP);

                SendRTPPacket(call2SDPIPAddress + ":" + call2SDPPort, call1SDPIPAddress + ":" + call1SDPPort);
                SendRTPPacket(call1SDPIPAddress + ":" + call1SDPPort, call2SDPIPAddress + ":" + call2SDPPort);
            }
            catch (Exception excp)
            {
                logger.Error("Exception CallbackApp. " + excp);
                Log("Exception in Callback. " + excp);
            }
            finally
            {
                if (!ts.IsCancellationRequested)
                {
                    ts.Cancel();
                }
            }
        }
コード例 #20
0
        /// <summary>
        /// Monitors the CDRs table for records that are using real-time call control and are within the limit that requires them to
        /// re-reserve credit.
        /// </summary>
        private void MonitorCDRs()
        {
            try
            {
                Thread.CurrentThread.Name = RTCC_THREAD_NAME;

                logger.Debug("RTCC Core Starting Monitor CDRs thread.");

                while (!m_exit)
                {
                    using (var db = new SIPSorceryEntities())
                    {
                        try
                        {
                            // Try and reserve credit on in progress calls.
                            DateTime reservationDue = DateTime.Now.AddSeconds(m_reserveDueSeconds);

                            var rtccReservationDue = (from rtcc in db.RTCCs1.Include("cdr")
                                                      where rtcc.AccountCode != null && rtcc.SecondsReserved != null && rtcc.SecondsReserved > 0 && rtcc.ReservationError == null && rtcc.ReconciliationResult == null &&
                                                      rtcc.cdr.HungupTime == null && rtcc.cdr.AnsweredAt != null && rtcc.cdr.AnsweredStatus >= 200 && rtcc.cdr.AnsweredStatus <= 299 &&
                                                      EntityFunctions.AddSeconds(rtcc.cdr.AnsweredAt, rtcc.SecondsReserved) <= reservationDue
                                                      orderby rtcc.cdr.AnsweredAt
                                                      select rtcc).Take(NUMBER_CDRS_PER_ROUNDTRIP);

                            while (rtccReservationDue.Count() > 0)
                            {
                                foreach (RTCC rtcc in rtccReservationDue)
                                {
                                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.DialPlan, "Reserving credit for call " + rtcc.cdr.Dst + ".", rtcc.cdr.Owner));

                                    // Attempt to re-reserve the next chunk of credit for the call.
                                    m_customerAccountDataLayer.ReserveCredit(m_reservationAmountSeconds, rtcc.ID);
                                }
                            }
                        }
                        //catch (ReflectionTypeLoadException ex)
                        //{
                        //    StringBuilder sb = new StringBuilder();
                        //    foreach (Exception exSub in ex.LoaderExceptions)
                        //    {
                        //        sb.AppendLine(exSub.Message);
                        //        if (exSub is FileNotFoundException)
                        //        {
                        //            FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
                        //            if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                        //            {
                        //                sb.AppendLine("Fusion Log:");
                        //                sb.AppendLine(exFileNotFound.FusionLog);
                        //            }
                        //        }
                        //        sb.AppendLine();
                        //    }
                        //    string errorMessage = sb.ToString();
                        //    logger.Error(errorMessage);
                        //}
                        catch (Exception monitorExcp)
                        {
                            logger.Error("Exception MonitorCDRs Credit Reservation. " + monitorExcp);
                            logger.Error("InnerException MonitorCDRs Credit Reservation. " + monitorExcp.InnerException);
                        }

                        try
                        {
                            // Terminate any calls that have reached their time limit.
                            DateTime now = DateTime.Now;
                            var      rtccTerminationDue = (from rtcc in db.RTCCs1.Include("cdr")
                                                           where !rtcc.IsHangingUp && rtcc.AccountCode != null && rtcc.cdr.HungupTime == null && rtcc.cdr.AnsweredAt != null && rtcc.SecondsReserved != null &&
                                                           rtcc.cdr.AnsweredStatus >= 200 && rtcc.cdr.AnsweredStatus <= 299 && EntityFunctions.AddSeconds(rtcc.cdr.AnsweredAt, rtcc.SecondsReserved) <= now && !rtcc.IsHangingUp &&
                                                           rtcc.ReconciliationResult == null
                                                           orderby rtcc.cdr.AnsweredAt
                                                           select rtcc).Take(NUMBER_CDRS_PER_ROUNDTRIP);

                            while (rtccTerminationDue.Count() > 0)
                            {
                                foreach (RTCC rtcc in rtccTerminationDue)
                                {
                                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.DialPlan, "Terminating call due to reservation limit being reached " + rtcc.cdr.Dst + ".", rtcc.cdr.Owner));

                                    m_customerAccountDataLayer.SetCDRIsHangingUp(rtcc.ID);

                                    var dialogue = m_sipDialoguePersistor.Get(x => x.CDRId == rtcc.CDRID, null, 0, 1).FirstOrDefault();
                                    if (dialogue != null)
                                    {
                                        m_sipDialogueManager.CallHungup(dialogue.SIPDialogue, "RTCC time limit reached", true);
                                    }
                                    else
                                    {
                                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.Warn, "A dialogue could not be found when terminating a call due to reservation limit being reached.", rtcc.cdr.Owner));
                                    }
                                }
                            }
                        }
                        catch (Exception monitorExcp)
                        {
                            logger.Error("Exception RTCCCore MonitorCDRs Call Termination. " + monitorExcp.Message);
                        }
                    }

                    Thread.Sleep(1000);
                }

                logger.Warn("RTCCCore MonitorCDRs thread stopping.");
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTCCCore MonitorCDRs. " + excp.Message);
            }
        }
コード例 #21
0
        public string SubscribeClient(
            string owner,
            string adminID,
            SIPRequest subscribeRequest,
            string toTag,
            SIPURI canonicalResourceURI,
            out SIPResponseStatusCodesEnum errorResponse,
            out string errorReason)
        {
            try
            {
                errorResponse = SIPResponseStatusCodesEnum.None;
                errorReason   = null;

                SIPURI          resourceURI  = subscribeRequest.URI.CopyOf();
                SIPEventPackage eventPackage = SIPEventPackage.Parse(subscribeRequest.Header.Event);
                int             expiry       = subscribeRequest.Header.Expires;

                if (!(eventPackage == SIPEventPackage.Dialog || eventPackage == SIPEventPackage.Presence))
                {
                    throw new ApplicationException("Event package " + eventPackage.ToString() + " is not supported by the subscriptions manager.");
                }
                else
                {
                    if (expiry > 0)
                    {
                        string      subscribeError    = null;
                        string      sessionID         = Guid.NewGuid().ToString();
                        SIPDialogue subscribeDialogue = new SIPDialogue(subscribeRequest, owner, adminID, toTag);

                        if (eventPackage == SIPEventPackage.Dialog)
                        {
                            string monitorFilter = "dialog " + canonicalResourceURI.ToString();
                            if (!subscribeRequest.Body.IsNullOrBlank())
                            {
                                monitorFilter += " and " + subscribeRequest.Body;
                            }

                            m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError);

                            if (subscribeError != null)
                            {
                                throw new ApplicationException(subscribeError);
                            }
                            else
                            {
                                GetSIPDialogueDelegate             getSipDialogue          = (id) => { return(GetDialogue_External(id).SIPDialogue); };
                                GetDialoguesForOwnerDelegate       getSipDialoguesForOwner = (ownr, offset, limit) => { return(GetDialogues_External(x => x.Owner == owner, "Inserted", offset, limit).Select(x => x.SIPDialogue).ToList <SIPDialogue>()); };
                                GetRemoteDialogueForBridgeDelegate getSIPDialogueForBridge = (bridgeID, localDialogueID) => { return(GetDialogues_External(d => d.BridgeId == bridgeID.ToString() && d.Id != localDialogueID, null, 0, 1).Select(x => x.SIPDialogue).FirstOrDefault()); };
                                SIPDialogEventSubscription         subscription            = new SIPDialogEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, getSipDialoguesForOwner, getSIPDialogueForBridge, getSipDialogue);
                                m_subscriptions.Add(sessionID, subscription);
                                MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New dialog subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner));
                            }
                        }
                        else if (eventPackage == SIPEventPackage.Presence)
                        {
                            string monitorFilter = "presence " + canonicalResourceURI.ToString();
                            m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError);

                            if (subscribeError != null)
                            {
                                throw new ApplicationException(subscribeError);
                            }
                            else
                            {
                                bool switchboardAccountsOnly = subscribeRequest.Body == SIPPresenceEventSubscription.SWITCHBOARD_FILTER;
                                SIPRegistrarBindingsCountDelegate getRegistrarBindingsCount = (sipAccountID) => { return(GetSIPRegistrarBindingsCount_External(x => x.SIPAccountId == sipAccountID)); };
                                GetSIPAccountsForUserDelegate     getSIPAccountsForUser     = (username, domain, offset, limit) => { return(m_sipAssetPersistor.Get(x => x.SIPUsername == username && x.SIPDomain == domain, "SIPUsername", offset, limit).Select(y => y.SIPAccount).ToList()); };
                                GetSIPAccountsForOwnerDelegate    getSIPAccountsForOwner    = (accountOwner, offset, limit) => { return(m_sipAssetPersistor.Get(x => x.Owner == accountOwner, "SIPUsername", offset, limit).Select(y => y.SIPAccount).ToList()); };
                                SIPPresenceEventSubscription      subscription = new SIPPresenceEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, getSIPAccountsForUser, getSIPAccountsForOwner, m_sipAssetPersistor.GetProperty, getRegistrarBindingsCount, switchboardAccountsOnly);
                                m_subscriptions.Add(sessionID, subscription);
                                MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New presence subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner));
                            }
                        }

                        return(sessionID);
                    }

                    return(null);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception NotifierSubscriptionsManager SubscribeClient. " + excp.Message);
                throw;
            }
        }
コード例 #22
0
        public void CreateCustomer(Customer customer)
        {
            try
            {
                if (m_inviteCodeRequired && customer.InviteCode == null)
                {
                    throw new ApplicationException("Sorry new account creations currently require an invite code, please see http://sipsorcery.wordpress.com/new-accounts/.");
                }
                else if (m_newCustomersAllowedLimit != 0 && CRMCustomerPersistor.Count(null) >= m_newCustomersAllowedLimit)
                {
                    // Check whether the number of customers is within the allowed limit.
                    throw new ApplicationException("Sorry new account creations are currently disabled, please see http://sipsorcery.wordpress.com/new-accounts/.");
                }
                else
                {
                    // Check whether the username is already taken.
                    customer.CustomerUsername = customer.CustomerUsername.ToLower();
                    Customer existingCustomer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customer.CustomerUsername);
                    if (existingCustomer != null)
                    {
                        throw new ApplicationException("The requested username is already in use please try a different one.");
                    }

                    // Check whether the email address is already taken.
                    customer.EmailAddress = customer.EmailAddress.ToLower();
                    existingCustomer      = CRMCustomerPersistor.Get(c => c.EmailAddress == customer.EmailAddress);
                    if (existingCustomer != null)
                    {
                        throw new ApplicationException("The email address is already associated with an account.");
                    }

                    string validationError = Customer.ValidateAndClean(customer);
                    if (validationError != null)
                    {
                        throw new ApplicationException(validationError);
                    }

                    customer.MaxExecutionCount = Customer.DEFAULT_MAXIMUM_EXECUTION_COUNT;
                    customer.APIKey            = Crypto.GetRandomByteString(Customer.API_KEY_LENGTH / 2);

                    CRMCustomerPersistor.Add(customer);
                    logger.Debug("New customer record added for " + customer.CustomerUsername + ".");

                    // Create a default dialplan.
                    SIPDialPlan defaultDialPlan = new SIPDialPlan(customer.CustomerUsername, "default", null, "sys.Log(\"hello world\")\n", SIPDialPlanScriptTypesEnum.Ruby);
                    DialPlanPersistor.Add(defaultDialPlan);
                    logger.Debug("Default dialplan added for " + customer.CustomerUsername + ".");

                    // Get default domain name.
                    string defaultDomain = SIPDomainManager.GetDomain("local", true);

                    // Create SIP account.
                    if (SIPAccountPersistor.Get(s => s.SIPUsername == customer.CustomerUsername && s.SIPDomain == defaultDomain) == null)
                    {
                        SIPAccount sipAccount = new SIPAccount(customer.CustomerUsername, defaultDomain, customer.CustomerUsername, customer.CustomerPassword, "default");
                        SIPAccountPersistor.Add(sipAccount);
                        logger.Debug("SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " added for " + sipAccount.Owner + ".");
                    }
                    else
                    {
                        int attempts = 0;
                        while (attempts < 10)
                        {
                            string testUsername = customer.CustomerUsername + Crypto.GetRandomString(4);
                            if (SIPAccountPersistor.Get(s => s.SIPUsername == testUsername && s.SIPDomain == defaultDomain) == null)
                            {
                                SIPAccount sipAccount = new SIPAccount(customer.CustomerUsername, defaultDomain, testUsername, customer.CustomerPassword, "default");
                                SIPAccountPersistor.Add(sipAccount);
                                logger.Debug("SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " added for " + sipAccount.Owner + ".");
                                break;
                            }
                            else
                            {
                                attempts++;
                            }
                        }
                    }

                    if (!m_customerConfirmLink.IsNullOrBlank())
                    {
                        logger.Debug("Sending new account confirmation email to " + customer.EmailAddress + ".");
                        SIPSorcerySMTP.SendEmail(customer.EmailAddress, NEW_ACCOUNT_EMAIL_FROM_ADDRESS, NEW_ACCOUNT_EMAIL_SUBJECT, String.Format(NEW_ACCOUNT_EMAIL_BODY, customer.FirstName, m_customerConfirmLink, customer.Id));
                    }
                    else
                    {
                        logger.Debug("Customer confirmation email was not sent as no confirmation link has been set.");
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception CreateNewCustomer. " + excp.Message);
                throw;
            }
        }