PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs

#
C# | 347 lines | 272 code | 67 blank | 8 comment | 41 complexity | a12b8847e9766403f4d4030939968bb6 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, LGPL-2.1, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Web.Mvc;
  4. using System.Web.Routing;
  5. using System.Xml.Linq;
  6. using JetBrains.Annotations;
  7. using Orchard.Blogs.Models;
  8. using Orchard.ContentManagement;
  9. using Orchard.ContentManagement.Aspects;
  10. using Orchard.Core.Common.Models;
  11. using Orchard.Core.Routable.Models;
  12. using Orchard.Core.Routable.Services;
  13. using Orchard.Core.XmlRpc;
  14. using Orchard.Core.XmlRpc.Models;
  15. using Orchard.Environment.Extensions;
  16. using Orchard.Localization;
  17. using Orchard.Logging;
  18. using Orchard.Mvc.Extensions;
  19. using Orchard.Security;
  20. using Orchard.Blogs.Extensions;
  21. using Orchard.Mvc.Html;
  22. namespace Orchard.Blogs.Services {
  23. [UsedImplicitly]
  24. [OrchardFeature("Orchard.Blogs.RemotePublishing")]
  25. public class XmlRpcHandler : IXmlRpcHandler {
  26. private readonly IBlogService _blogService;
  27. private readonly IBlogPostService _blogPostService;
  28. private readonly IContentManager _contentManager;
  29. private readonly IAuthorizationService _authorizationService;
  30. private readonly IMembershipService _membershipService;
  31. private readonly IRoutableService _routableService;
  32. private readonly RouteCollection _routeCollection;
  33. public XmlRpcHandler(IBlogService blogService, IBlogPostService blogPostService, IContentManager contentManager,
  34. IAuthorizationService authorizationService, IMembershipService membershipService, IRoutableService routableService,
  35. RouteCollection routeCollection) {
  36. _blogService = blogService;
  37. _blogPostService = blogPostService;
  38. _contentManager = contentManager;
  39. _authorizationService = authorizationService;
  40. _membershipService = membershipService;
  41. _routableService = routableService;
  42. _routeCollection = routeCollection;
  43. Logger = NullLogger.Instance;
  44. T = NullLocalizer.Instance;
  45. }
  46. public ILogger Logger { get; set; }
  47. public Localizer T { get; set; }
  48. public void SetCapabilities(XElement options) {
  49. const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
  50. options.SetElementValue(XName.Get("supportsSlug", manifestUri), "Yes");
  51. }
  52. public void Process(XmlRpcContext context) {
  53. var urlHelper = new UrlHelper(context.ControllerContext.RequestContext, _routeCollection);
  54. if (context.Request.MethodName == "blogger.getUsersBlogs") {
  55. var result = MetaWeblogGetUserBlogs(urlHelper,
  56. Convert.ToString(context.Request.Params[1].Value),
  57. Convert.ToString(context.Request.Params[2].Value));
  58. context.Response = new XRpcMethodResponse().Add(result);
  59. }
  60. if (context.Request.MethodName == "metaWeblog.getRecentPosts") {
  61. var result = MetaWeblogGetRecentPosts(urlHelper,
  62. Convert.ToString(context.Request.Params[0].Value),
  63. Convert.ToString(context.Request.Params[1].Value),
  64. Convert.ToString(context.Request.Params[2].Value),
  65. Convert.ToInt32(context.Request.Params[3].Value),
  66. context._drivers);
  67. context.Response = new XRpcMethodResponse().Add(result);
  68. }
  69. if (context.Request.MethodName == "metaWeblog.newPost") {
  70. var result = MetaWeblogNewPost(
  71. Convert.ToString(context.Request.Params[0].Value),
  72. Convert.ToString(context.Request.Params[1].Value),
  73. Convert.ToString(context.Request.Params[2].Value),
  74. (XRpcStruct)context.Request.Params[3].Value,
  75. Convert.ToBoolean(context.Request.Params[4].Value),
  76. context._drivers);
  77. context.Response = new XRpcMethodResponse().Add(result);
  78. }
  79. if (context.Request.MethodName == "metaWeblog.getPost") {
  80. var result = MetaWeblogGetPost(
  81. urlHelper,
  82. Convert.ToInt32(context.Request.Params[0].Value),
  83. Convert.ToString(context.Request.Params[1].Value),
  84. Convert.ToString(context.Request.Params[2].Value),
  85. context._drivers);
  86. context.Response = new XRpcMethodResponse().Add(result);
  87. }
  88. if (context.Request.MethodName == "metaWeblog.editPost") {
  89. var result = MetaWeblogEditPost(
  90. Convert.ToInt32(context.Request.Params[0].Value),
  91. Convert.ToString(context.Request.Params[1].Value),
  92. Convert.ToString(context.Request.Params[2].Value),
  93. (XRpcStruct)context.Request.Params[3].Value,
  94. Convert.ToBoolean(context.Request.Params[4].Value),
  95. context._drivers);
  96. context.Response = new XRpcMethodResponse().Add(result);
  97. }
  98. if (context.Request.MethodName == "blogger.deletePost") {
  99. var result = MetaWeblogDeletePost(
  100. Convert.ToString(context.Request.Params[1].Value),
  101. Convert.ToString(context.Request.Params[2].Value),
  102. Convert.ToString(context.Request.Params[3].Value),
  103. context._drivers);
  104. context.Response = new XRpcMethodResponse().Add(result);
  105. }
  106. }
  107. private XRpcArray MetaWeblogGetUserBlogs(UrlHelper urlHelper,
  108. string userName,
  109. string password) {
  110. IUser user = ValidateUser(userName, password);
  111. XRpcArray array = new XRpcArray();
  112. foreach (BlogPart blog in _blogService.Get()) {
  113. // User needs to at least have permission to edit its own blog posts to access the service
  114. if (_authorizationService.TryCheckAccess(Permissions.EditBlogPost, user, blog)) {
  115. BlogPart blogPart = blog;
  116. array.Add(new XRpcStruct()
  117. .Set("url", urlHelper.AbsoluteAction(() => urlHelper.Blog(blogPart)))
  118. .Set("blogid", blog.Id)
  119. .Set("blogName", blog.Name));
  120. }
  121. }
  122. return array;
  123. }
  124. private XRpcArray MetaWeblogGetRecentPosts(
  125. UrlHelper urlHelper,
  126. string blogId,
  127. string userName,
  128. string password,
  129. int numberOfPosts,
  130. IEnumerable<IXmlRpcDriver> drivers) {
  131. IUser user = ValidateUser(userName, password);
  132. // User needs to at least have permission to edit its own blog posts to access the service
  133. _authorizationService.CheckAccess(Permissions.EditBlogPost, user, null);
  134. BlogPart blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId));
  135. if (blog == null) {
  136. throw new ArgumentException();
  137. }
  138. var array = new XRpcArray();
  139. foreach (var blogPost in _blogPostService.Get(blog, 0, numberOfPosts, VersionOptions.Latest)) {
  140. var postStruct = CreateBlogStruct(blogPost, urlHelper);
  141. foreach (var driver in drivers)
  142. driver.Process(postStruct);
  143. array.Add(postStruct);
  144. }
  145. return array;
  146. }
  147. private int MetaWeblogNewPost(
  148. string blogId,
  149. string userName,
  150. string password,
  151. XRpcStruct content,
  152. bool publish,
  153. IEnumerable<IXmlRpcDriver> drivers) {
  154. IUser user = ValidateUser(userName, password);
  155. // User needs permission to edit or publish its own blog posts
  156. _authorizationService.CheckAccess(publish ? Permissions.PublishBlogPost : Permissions.EditBlogPost, user, null);
  157. BlogPart blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId));
  158. if (blog == null)
  159. throw new ArgumentException();
  160. var title = content.Optional<string>("title");
  161. var description = content.Optional<string>("description");
  162. var slug = content.Optional<string>("wp_slug");
  163. var blogPost = _contentManager.New<BlogPostPart>("BlogPost");
  164. // BodyPart
  165. if (blogPost.Is<BodyPart>()) {
  166. blogPost.As<BodyPart>().Text = description;
  167. }
  168. //CommonPart
  169. if (blogPost.Is<ICommonPart>()) {
  170. blogPost.As<ICommonPart>().Owner = user;
  171. blogPost.As<ICommonPart>().Container = blog;
  172. }
  173. //RoutePart
  174. if (blogPost.Is<RoutePart>()) {
  175. blogPost.As<RoutePart>().Title = title;
  176. blogPost.As<RoutePart>().Slug = slug;
  177. _routableService.FillSlugFromTitle(blogPost.As<RoutePart>());
  178. blogPost.As<RoutePart>().Path = blogPost.As<RoutePart>().GetPathWithSlug(blogPost.As<RoutePart>().Slug);
  179. }
  180. _contentManager.Create(blogPost, VersionOptions.Draft);
  181. var publishedUtc = content.Optional<DateTime?>("dateCreated");
  182. if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow))
  183. _blogPostService.Publish(blogPost);
  184. foreach (var driver in drivers)
  185. driver.Process(blogPost.Id);
  186. return blogPost.Id;
  187. }
  188. private XRpcStruct MetaWeblogGetPost(
  189. UrlHelper urlHelper,
  190. int postId,
  191. string userName,
  192. string password,
  193. IEnumerable<IXmlRpcDriver> drivers) {
  194. IUser user = ValidateUser(userName, password);
  195. var blogPost = _blogPostService.Get(postId, VersionOptions.Latest);
  196. if (blogPost == null)
  197. throw new ArgumentException();
  198. _authorizationService.CheckAccess(Permissions.EditBlogPost, user, blogPost);
  199. var postStruct = CreateBlogStruct(blogPost, urlHelper);
  200. foreach (var driver in drivers)
  201. driver.Process(postStruct);
  202. return postStruct;
  203. }
  204. private bool MetaWeblogEditPost(
  205. int postId,
  206. string userName,
  207. string password,
  208. XRpcStruct content,
  209. bool publish,
  210. IEnumerable<IXmlRpcDriver> drivers) {
  211. IUser user = ValidateUser(userName, password);
  212. var blogPost = _blogPostService.Get(postId, VersionOptions.DraftRequired);
  213. if (blogPost == null)
  214. throw new ArgumentException();
  215. _authorizationService.CheckAccess(publish ? Permissions.PublishBlogPost : Permissions.EditBlogPost, user, blogPost);
  216. var title = content.Optional<string>("title");
  217. var description = content.Optional<string>("description");
  218. var slug = content.Optional<string>("wp_slug");
  219. // BodyPart
  220. if (blogPost.Is<BodyPart>()) {
  221. blogPost.As<BodyPart>().Text = description;
  222. }
  223. //RoutePart
  224. if (blogPost.Is<RoutePart>()) {
  225. blogPost.As<RoutePart>().Title = title;
  226. blogPost.As<RoutePart>().Slug = slug;
  227. _routableService.FillSlugFromTitle(blogPost.As<RoutePart>());
  228. blogPost.As<RoutePart>().Path = blogPost.As<RoutePart>().GetPathWithSlug(blogPost.As<RoutePart>().Slug);
  229. }
  230. var publishedUtc = content.Optional<DateTime?>("dateCreated");
  231. if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow))
  232. _blogPostService.Publish(blogPost);
  233. foreach (var driver in drivers)
  234. driver.Process(blogPost.Id);
  235. return true;
  236. }
  237. private bool MetaWeblogDeletePost(
  238. string postId,
  239. string userName,
  240. string password,
  241. IEnumerable<IXmlRpcDriver> drivers) {
  242. IUser user = ValidateUser(userName, password);
  243. var blogPost = _blogPostService.Get(Convert.ToInt32(postId), VersionOptions.Latest);
  244. if (blogPost == null)
  245. throw new ArgumentException();
  246. _authorizationService.CheckAccess(Permissions.DeleteBlogPost, user, blogPost);
  247. foreach (var driver in drivers)
  248. driver.Process(blogPost.Id);
  249. _blogPostService.Delete(blogPost);
  250. return true;
  251. }
  252. private IUser ValidateUser(string userName, string password) {
  253. IUser user = _membershipService.ValidateUser(userName, password);
  254. if (user == null) {
  255. throw new OrchardCoreException(T("The username or e-mail or password provided is incorrect."));
  256. }
  257. return user;
  258. }
  259. private static XRpcStruct CreateBlogStruct(
  260. BlogPostPart blogPostPart,
  261. UrlHelper urlHelper) {
  262. var url = urlHelper.AbsoluteAction(() => urlHelper.ItemDisplayUrl(blogPostPart));
  263. if (blogPostPart.HasDraft()) {
  264. url = urlHelper.AbsoluteAction("Preview", "Item", new { area = "Contents", id = blogPostPart.ContentItem.Id });
  265. }
  266. var blogStruct = new XRpcStruct()
  267. .Set("postid", blogPostPart.Id)
  268. .Set("title", blogPostPart.Title)
  269. .Set("wp_slug", blogPostPart.Slug)
  270. .Set("description", blogPostPart.Text)
  271. .Set("link", url)
  272. .Set("permaLink", url);
  273. if (blogPostPart.PublishedUtc != null) {
  274. blogStruct.Set("dateCreated", blogPostPart.PublishedUtc);
  275. blogStruct.Set("date_created_gmt", blogPostPart.PublishedUtc);
  276. }
  277. return blogStruct;
  278. }
  279. }
  280. }