/// <summary>
        /// Save a file to a blog item
        /// </summary>
        /// <param name="id">The blog item to save the file against</param>
        /// <param name="file">The file to be saved</param>
        /// <returns>The saved file</returns>
        public override BlogFile SaveFile(String id, BlogFile file)
        {
            try
            {
                // Make sure that there is an identifier
                file.Id = ((file.Id ?? "") == "") ? NewId() : file.Id;

                // Generate the path for the file item
                String fileLocation = BlogFilePath(id, file.Id, Path.GetExtension(file.Filename).Replace(".", ""));

                // Calculate the relative directory based on the path
                String combinedPath = Path.Combine(Configuration.Environment.WebRootPath, fileLocation);

                // Get the directory portion from the combined Path
                String fileDirectory = Path.GetDirectoryName(combinedPath);

                // If the directory doesn't exist then create it
                if (!Directory.Exists(fileDirectory))
                {
                    Directory.CreateDirectory(fileDirectory);
                }

                // Write the file contents
                File.WriteAllBytes(combinedPath, file.Content);
            }
            catch (Exception ex)
            {
                throw BlogException.Passthrough(ex, new CouldNotSaveBlogException(ex));
            }
            // Send the file back
            return(file);
        }
        /// <summary>
        /// Write an item to disk with a given path from a given object type
        /// </summary>
        /// <typeparam name="T">The object type to be written to disk</typeparam>
        /// <param name="path">The path to write the item to</param>
        private Boolean Write <T>(String path, T toWrite) where T : IBlogBase
        {
            try
            {
                // Calculate the relative directory based on the path
                String combinedPath = Path.Combine(Configuration.Environment.WebRootPath, path);

                // Get the filename from the combined path
                String fileName = Path.GetFileName(combinedPath);

                // Get the directory alone from the combined path
                String pathAlone = (fileName != "") ? Path.GetDirectoryName(combinedPath) : combinedPath;

                // Check to make sure the directory exists
                if (!Directory.Exists(pathAlone))
                {
                    Directory.CreateDirectory(pathAlone);
                }

                // Write the Xml to disk
                File.WriteAllText(combinedPath, toWrite.ToXmlString());

                // Check if the file exists after the write
                return(File.Exists(combinedPath));
            }
            catch (Exception ex)
            {
                // Throw that the file could not be saved
                throw BlogException.Passthrough(ex, new CouldNotSaveBlogException(ex));
            }
        }
        /// <summary>
        /// Load the content of the file to the object
        /// </summary>
        /// <param name="id">The blog item to get the file from</param>
        /// <param name="file">The file to have the content populated into</param>
        /// <returns>The populated Blog File object</returns>
        public override BlogFile LoadFile(String id, BlogFile file)
        {
            try
            {
                // Generate the path for the file item
                String fileLocation = BlogFilePath(id, file.Id, Path.GetExtension(file.Filename).Replace(".", ""));

                // Calculate the relative directory based on the path
                String combinedPath = Path.Combine(Configuration.Environment.WebRootPath, fileLocation);

                // Get the directory portion from the combined Path
                String fileDirectory = Path.GetDirectoryName(combinedPath);

                // If the directory doesn't exist then create it
                if (Directory.Exists(fileDirectory))
                {
                    // Read the file contents
                    file.Content = File.ReadAllBytes(combinedPath);
                }
            }
            catch (Exception ex)
            {
                throw BlogException.Passthrough(ex, new CouldNotLoadBlogException(ex));
            }

            // Send the file back
            return(file);
        }
Esempio n. 4
0
        /// <summary>
        /// Process / fill a template with a set of key value pairs
        /// </summary>
        /// <param name="key"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public String Process(BlogViewTemplatePart key, List <BlogViewTemplateReplacement> values)
        {
            // Get the content (will return an empty content template if it fails)
            try
            {
                // Get the content
                IHtmlContent content = Get(key);

                // Something to process?
                String renderedContent = (content != null) ? HtmlHelpers.GetString(content) : "";
                if (renderedContent != "")
                {
                    // For each replacement text
                    values.ForEach(replacement =>
                    {
                        // Replace the value and check if it needs encoding for anti XSS or not
                        renderedContent = renderedContent.Replace(ReplacementStartMarker + replacement.SearchString + ReplacementEndMarker,
                                                                  replacement.Encode ? WebUtility.HtmlEncode(replacement.Content) : replacement.Content);
                    });
                }

                // Send the rendered content back
                return(renderedContent);
            }
            catch (Exception ex)
            {
                throw BlogException.Passthrough(ex, new HtmlTemplateNotProcessedBlogException(ex));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Get the instance of the data provider from an input string
        /// </summary>
        /// <param name="type">The string representing the data provider (Name of the provider)</param>
        /// <returns>The implementation of the data provider</returns>
        public IBlogDataProvider Get(String type)
        {
            // Create an instance of the implementation from containing assembly
            IBlogDataProvider provider = null;

            try
            {
                // Loop the available assemblies (not in current usually, might even be a custom provider
                // so don't make assumptions about where it is)
                foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                {
                    provider = (IBlogDataProvider)assembly.CreateInstance(type);
                    if (provider != null)
                    {
                        break;
                    }
                }

                // Raise an error if no provider could be found
                if (provider == null)
                {
                    throw new NoProviderFoundBlogException();
                }
            }
            catch (Exception ex)
            {
                // Wrap the exception correctly if it is not a blog exception type
                throw BlogException.Passthrough(ex, new ErrorFindingProviderBlogException(ex));
            }

            // Send the provider back
            return(provider);
        }
        /// <summary>
        /// Read an item from disk with a given path from a given object type
        /// </summary>
        /// <typeparam name="T">The object type to be read from disk</typeparam>
        /// <param name="path">The path to read the item from</param>
        private T Read <T>(String path) where T : IBlogBase, new()
        {
            try
            {
                // Calculate the relative directory based on the path
                String combinedPath = Path.Combine(Configuration.Environment.WebRootPath, path);

                // Get the filename from the combined path
                String fileName = Path.GetFileName(combinedPath);

                // Get the directory alone from the combined path
                String pathAlone = (fileName != "") ? Path.GetDirectoryName(combinedPath) : combinedPath;

                // Write the Xml to disk
                String XmlString = File.ReadAllText(combinedPath);

                // Generate a new object
                T result = new T();

                // Populate the object by calling the extension method to cast the incoming string
                result = (T)result.FromXmlString(XmlString);

                // Send the result back
                return(result);
            }
            catch (Exception ex)
            {
                // Throw that the file could not be saved
                throw BlogException.Passthrough(ex, new CouldNotLoadBlogException(ex));
            }
        }
        private const String blogUserFilename     = "{0}.xml";   // The file name for the user details

        /// <summary>
        /// Override for the base delete functionality
        /// </summary>
        /// <returns></returns>
        public override Boolean Delete(IList <IBlogHeader> items, Boolean permanent)
        {
            try
            {
                // List of filename to remove should it be a hard delete (done before becuase the
                // items won't exist in the index after the base method call)
                List <String> filesToDelete = permanent ?
                                              ((List <IBlogHeader>)items).Select(x => BlogItemFilename(x.Id)).ToList <String>()
                    : null;

                // Any files attached to the blogs that might be removed
                if (permanent)
                {
                    ((List <IBlogHeader>)items).ForEach(
                        header =>
                    {
                        // Get the item to check to see if there are any other files to remove
                        IBlogItem item = base.Load(header);
                        if (item != null)
                        {
                            item.Files.ForEach(file => DeleteFile(header.Id, file));
                        }
                    }
                        );
                }

                // Call the base implementation to handle the headers etc.
                if (base.Delete(items, permanent))
                {
                    // Hard delete? Remove the files ..
                    if (permanent && filesToDelete != null)
                    {
                        // Remove the blog files itself
                        filesToDelete.ForEach(file =>
                        {
                            try
                            {
                                // Attempt to delete the file from disk ..
                                File.Delete(file);
                            }
                            catch
                            {
                                // Move to the next one if failed to delete, it has no real impact on the system
                            }
                        });
                    }

                    // Save the index regardless on a hard or soft delete
                    return(WriteBlogIndex());
                }

                // Failed if it gets to here
                return(false);
            }
            catch (Exception ex)
            {
                throw BlogException.Passthrough(ex, new CouldNotRemoveBlogException(ex));
            }
        }
        public void Exception_External_Is_Not_Passed_Through()
        {
            // Arrange

            // Act
            Exception result = BlogException.Passthrough(new NotImplementedException(), new GeneralBlogException());

            // Assert
            Assert.IsType <GeneralBlogException>(result);
        }
        public void Exception_Internal_Is_Passed_Through()
        {
            // Arrange

            // Act
            Exception result = BlogException.Passthrough(new NoProviderFoundBlogException(), new GeneralBlogException());

            // Assert
            Assert.IsType <NoProviderFoundBlogException>(result);
        }
        public void Exception_Is_Internal_Negative()
        {
            // Arrange

            // Act
            Boolean result = BlogException.IsInternal(new NotImplementedException()
            {
            });

            // Assert
            Assert.False(result);
        }
        public void Exception_Is_Internal_Positive()
        {
            // Arrange

            // Act
            Boolean result = BlogException.IsInternal(new GeneralBlogException()
            {
            });

            // Assert
            Assert.True(result);
        }
        /// <summary>
        /// Initialise call made by the factory
        /// </summary>
        public override void Initialise()
        {
            // Initialise the users file if there is not already one present in the correct location
            Boolean usersInitialised = InitialiseUsers();

            if (usersInitialised)
            {
                // Check to see if there is an a file containing the index to load to initialise the blog
                try
                {
                    BlogIndex foundIndex = ReadBlogIndex();
                    items             = foundIndex;
                    items.Initialised = true;
                }
                catch (Exception ex)
                {
                    // Could not load error?
                    if (ex.GetType() == typeof(CouldNotLoadBlogException))
                    {
                        // File was not found so create a blank index file
                        if (ex.InnerException != null && ex.InnerException.GetType() == typeof(FileNotFoundException))
                        {
                            // Try and write the blank index
                            try
                            {
                                items = new BlogIndex(); // Generate the new index to be saved
                                if (WriteBlogIndex())
                                {
                                    items.Initialised = true;
                                }
                            }
                            catch (Exception ex2)
                            {
                                throw BlogException.Passthrough(ex, new CouldNotSaveBlogException(ex2)); // Could not do save of the index
                            }
                        }
                    }
                    else
                    {
                        throw BlogException.Passthrough(ex, new CouldNotLoadBlogException(ex)); // Not a handled issue (such as no index so create one)
                    }
                }
            }

            // No item index and not initialised or the users were not initialised then raise an error
            if (!usersInitialised || items == null || !items.Initialised)
            {
                throw new NotInitialisedBlogException();
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Load the templates from a stream (which needs to be in the appropriate Json format)
        /// </summary>
        /// <param name="stream">A stream object that contains the loader object</param>
        /// <returns>Success Or Failure</returns>
        public Boolean Load(Stream stream)
        {
            BlogViewTemplateLoader templateLoader = null; // Define the template loader outside the try

            try
            {
                Templates = new Dictionary <BlogViewTemplatePart, IHtmlContent>(); // Empty list of templates by default

                // Convert stream to string
                using (StreamReader reader = new StreamReader(stream))
                {
                    // Parse the XML stream as an XDocument to query
                    XDocument doc = XDocument.Parse(reader.ReadToEnd());

                    // Query the XDocument and pull out the new template loader item
                    // for each node of type "Item" in the XDocument
                    templateLoader = new BlogViewTemplateLoader()
                    {
                        Items = doc.Descendants("item").Select(item =>
                                                               new BlogViewTemplateLoaderItem()
                        {
                            // Get the Id by analysing the attributes portion
                            Id = (BlogViewTemplatePart)item.Attribute("id").Value.
                                 GetValueFromDescription <BlogViewTemplatePart>(),

                            // Get the content by selecting all sub-nodes and pulling the CData value out for the first item it finds
                            Content = item.Elements("content").Select(
                                node => node.Value
                                ).First() ?? ""
                        }).ToList()
                    };

                    // Nothing to work with? Raise the error
                    if (templateLoader == null || templateLoader.Items == null || templateLoader.Items.Count == 0)
                    {
                        throw new CastObjectBlogException();
                    }
                }
            }
            catch (Exception ex)
            {
                // Decide whether or not to pass the origional or inner exception to the user
                throw BlogException.Passthrough(ex, new HtmlTemplateLoadFailureBlogException(ex));
            }

            // Call the loader with the object and not the stream
            return(Load(templateLoader));
        }
        /// <summary>
        /// Load a list of users from the XML Location
        /// </summary>
        /// <returns>A list of users</returns>
        private BlogUsers LoadUsers()
        {
            BlogUsers users = new BlogUsers(); // The default return parameter

            try
            {
                // Check to see if the file exists
                if (!File.Exists(UserFileLocation))
                {
                    users = Read <BlogUsers>(UserFileLocation);
                }
            }
            catch (Exception ex)
            {
                // Bounce up the chain the error about loading the user's list (and not because it wasn't there)
                throw BlogException.Passthrough(ex, new UserBlogException("Failed to connect to the users repository"));
            }

            return(users); // Return the list of users
        }
        /// <summary>
        /// Wrapper for registering a controller around the testable functionality
        /// as the controller discovery cannot be tested within the context of the tests
        /// </summary>
        /// <param name="instanceType">The new blog controller (or type) to be registered</param>
        /// <param name="blogs">The list of blogs to register against (strictly ref isn't needed but added to make clear)</param>
        public Boolean Register(Type instanceType, ref Dictionary <String, IBlog> blogs)
        {
            // The result which is failed by default
            Boolean result = false;

            try
            {
                // Try and scan the attributes from the blog controller instance
                BlogSetupAttribute[] setupAttributes = (BlogSetupAttribute[])instanceType.GetCustomAttributes(typeof(BlogSetupAttribute), false);
                BlogSEOAttribute[]   seoAttributes   = (BlogSEOAttribute[])instanceType.GetCustomAttributes(typeof(BlogSEOAttribute), false);

                // Call the testable functionality from this wrapper with the derived attributes
                result = Register(instanceType.Name, setupAttributes, seoAttributes, ref blogs);
            }
            catch (Exception ex)
            {
                // Tell the caller we could not initialise the blog controller
                throw BlogException.Passthrough(ex, new NotInitialisedBlogException(ex));
            }

            return(result); // Send back the result
        }
        /// <summary>
        /// Load the item from disk
        /// </summary>
        /// <param name="request">The header of the item that is to be loaded</param>
        /// <returns>The blog item that was found</returns>
        public override IBlogItem Load(IBlogHeader request)
        {
            try
            {
                // Get the header record part from the base load
                IBlogItem headerOnly = base.Load(request);

                // Did it give us a valid header to now go and load the content from disk?
                if (headerOnly.Header.Id != "")
                {
                    return(ReadBlogItem(headerOnly.Header));
                }

                // Only should get to here if something has gone wrong
                throw new CouldNotLoadBlogException(); // Failed to load the content so error
            }
            catch (Exception ex)
            {
                // Something went wrong, explain why
                throw BlogException.Passthrough(ex, new CouldNotLoadBlogException(ex));
            }
        }
        /// <summary>
        /// Overload to take the setup attributes and blog id so that tests can
        /// be ran against them without needing it scan for the blog controller
        /// </summary>
        /// <param name="instanceName">The name of the blog controller that inherits the base class</param>
        /// <param name="setupAttributes">The collection of attributes that setup the blog</param>
        /// <param name="seoAttributes">The collection of seo attributes for the blog</param>
        /// <param name="blogs">The dictionary to add the blog to once it is set up</param>
        /// <returns></returns>
        public Boolean Register(String instanceName,
                                BlogSetupAttribute[] setupAttributes,
                                BlogSEOAttribute[] seoAttributes,
                                ref Dictionary <String, IBlog> blogs)
        {
            // Define the result as failed by default
            Boolean result = false;

            // Check to see if the blogs dictionary has been instantiated (is not from the startup routine)
            blogs = blogs ?? new Dictionary <string, IBlog>();

            // If the base controller hasn't been set up yet the go gather the information it
            // needs to connect to the blogs that have been assigned for it to manage
            if (!blogs.ContainsKey(instanceName))
            {
                try
                {
                    // Get all of the blog setup attributes for this controller / blog combination
                    if (setupAttributes.Length > 0)
                    {
                        // Get the blog Id from the calling class custom parameters
                        String blogId = setupAttributes[0].BlogId;

                        // Work out and create an instance of the correct data provider
                        IBlogDataProvider blogDataProvider = (new BlogDataProviderFactory()).Get(setupAttributes[0].Provider);
                        if (blogDataProvider != null)
                        {
                            blogDataProvider.ConnectionString = new BlogDataProviderConnectionString(setupAttributes[0].ProviderConnectionString);

                            // Initialise the data provider
                            blogDataProvider.Initialise();

                            // Get all of the blog setup attributes for this controller / blog combination
                            BlogSEOSettings blogSEOSettings = (seoAttributes.Length > 0) ? seoAttributes[0].SEOSettings : new BlogSEOSettings()
                            {
                            };

                            // Construct the parameters for setting up the blog
                            IBlogParameters blogParameters = new BlogParameters()
                            {
                                Id          = blogId,
                                Provider    = blogDataProvider,
                                SEOSettings = blogSEOSettings
                            };

                            // Assign the instantiated blog class to the static array of blogs
                            blogs[instanceName] = new Blog(blogParameters);

                            // Success
                            result = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Tell the caller we could not initialise the blog controller
                    throw BlogException.Passthrough(ex, new NotInitialisedBlogException(ex));
                }
            }

            // Return if it was successful
            return(result);
        }
Esempio n. 18
0
        /// <summary>
        /// When the action is executed, set up anything needed for any subsequent actions
        /// </summary>
        /// <param name="context">The execution context</param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            // Is a redirect?
            Boolean isRedirect = false;

            if (context.HttpContext.Request.Query.ContainsKey("redirect"))
            {
                Boolean.TryParse(context.HttpContext.Request.Query["redirect"], out isRedirect);
            }

            // Is it a password change?
            if (context.HttpContext.Request.Path.Value.Contains($"auth/passwordchange"))
            {
                isRedirect = true;
            }

            try
            {
                // Get a new login manager instance to check against the current blog
                // with the current session context
                loginManager = new BlogLoginManager(Current, context.HttpContext);
                if (loginManager != null)
                {
                    // Handle the logins (tokens etc.)
                    loginManager.HandleTokens();

                    // Current user? Is there some reason to redirect?
                    if (loginManager.CurrentUser != null)
                    {
                        // Password change required and not already on the auth screen?
                        if (loginManager.CurrentUser.PasswordChange && !isRedirect)
                        {
                            // Redirect ..
                            context.Result = new RedirectResult($"{BaseUrl}/auth/login/?redirect=true");
                            return;
                        }
                    }
                }
                else
                {
                    throw new UserBlogException("Login Manager could not be initialised.");
                }

                // Check to see if we have any security attributes applied to the current method
                ControllerActionDescriptor controllerDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
                if (controllerDescriptor != null) // Did we get a controller descriptor?
                {
                    // Get the required security level if there is one
                    BlogSecurityAttribute[] securityAttributes = (BlogSecurityAttribute[])controllerDescriptor.MethodInfo.GetCustomAttributes(typeof(BlogSecurityAttribute), false);
                    if (securityAttributes.Length != 0)
                    {
                        // Loop the items and see if any fail to meet criteria, if so then set the redirect result
                        foreach (BlogSecurityAttribute attrib in securityAttributes)
                        {
                            // Check against the current user for the security level needed
                            if (loginManager.CurrentUser == null ||
                                loginManager.CurrentUser.Permissions == null ||
                                !loginManager.CurrentUser.Permissions.Contains(attrib.Permission))
                            {
                                context.Result = new RedirectResult($"{BaseUrl}"); // Redirect to the user to the home page
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Throw the exception wrapped (if needed) in a non-initialised exception
                throw BlogException.Passthrough(ex, new UserBlogException(ex));
            }

            // Call the base method
            base.OnActionExecuting(context);
        }
        /// <summary>
        /// Save a blog item
        /// </summary>
        /// <param name="item">The item to be saved</param>
        /// <returns>The item once it has been saved</returns>
        public override IBlogItem Save(IBlogItem item)
        {
            try
            {
                // New Item?
                Boolean isNew = (item.Header.Id ?? "") == "";

                // The base class will save the item to the in-memory header
                // so we don't want to pass the content in to this. We only want to save
                // the content to the file, so copy and update the item without the content
                // to the index
                IBlogItem headerRecord = item.Duplicate();
                headerRecord.Content = "";                    // Remove the content from being saved to the header record
                headerRecord.Files   = new List <BlogFile>(); // The header record doesn't need the file listing for the header record only
                IBlogItem response = base.Save(headerRecord); // Make sure we have an Id

                // Successfully saved?
                if (response != null && response.Header != null && response.Header.Id != "")
                {
                    // Make sure that the origional record that is about to be writen has an associated Id with it
                    item.Header.Id = response.Header.Id;

                    // If we have any file attachments to save we need to do this now
                    // If the item.Files is blank then see if we already have files to attach
                    if (item.Files != null)
                    {
                        item.Files.ForEach(file =>
                        {
                            // Anything to write?
                            if (file.Content != null && file.Content.Length > 0)
                            {
                                file = SaveFile(item.Header.Id, file);
                            }
                        });
                    }
                    else
                    {
                        // Sort out the file array
                        if (isNew && item.Files == null)
                        {
                            item.Files = response.Files = new List <BlogFile>();
                        }
                        else if (!isNew && item.Files == null)
                        {
                            // Get the old blog back again to get the file listing etc.
                            response   = Load(response.Header);
                            item.Files = new List <BlogFile>();
                            if (response != null && response.Header != null && response.Header.Id != "")
                            {
                                item.Files.AddRange(response.Files);
                            }
                        }
                    }

                    // Write the blog item to disk
                    if (WriteBlogItem(item))
                    {
                        // Try and save the header records to disk so any updates are cached there too
                        if (WriteBlogIndex())
                        {
                            return(response);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw BlogException.Passthrough(ex, new CouldNotSaveBlogException(ex));
            }

            // Got to here so must have failed
            throw new CouldNotSaveBlogException();
        }