コード例 #1
0
    public RaterModel Rate(Id entryId, float rating, User user, string ip)
    {
      LogService.Info("Rater.Rate entryId={0} rating={1} ip={2}", entryId, rating, ip);

      if (!AuthorizeService.IsAuthorized(user, entryId.ToScope(), AuthAction.RateEntryOrMedia))
        throw new UserNotAuthorizedException(user.Name, AuthAction.RateEntryOrMedia.ToString());

      if (rating < 1 || rating > 5) throw new ArgumentOutOfRangeException("Rating value must be 1 thru 5.");

      AtomEntry entry = AtomEntryRepository.GetEntry(entryId);
      if (entry.Raters.Contains(ip)) throw new UserAlreadyRatedEntryException(ip, entry.Id.ToString());

      entry.RatingCount++;
      entry.RatingSum += (int)Math.Round(rating);
      entry.Edited = DateTimeOffset.UtcNow;
      List<string> raters = entry.Raters.ToList();
      raters.Add(ip);
      entry.Raters = raters;
      entry = AtomEntryRepository.UpdateEntry(entry);
      return new RaterModel()
      {
        PostHref = RouteService.RouteUrl("RaterRateEntry", entryId),
        Rating = entry.Rating,
        CanRate = false,
        RatingCount = entry.RatingCount
      };
    }
コード例 #2
0
 public RaterModel GetRaterModel(Id entryId, User user, string ip)
 {
   bool auth = AuthorizeService.IsAuthorized(user, entryId.ToScope(), AuthAction.RateEntryOrMedia);
   AtomEntry entry = AtomEntryRepository.GetEntry(entryId);
   return new RaterModel()
   {
     PostHref = RouteService.RouteUrl("RaterRateEntry", entryId),
     Rating = entry.Rating,
     CanRate = auth && !entry.Raters.Contains(ip),
     RatingCount = entry.RatingCount
   };
 }
コード例 #3
0
    public virtual AtomEntry Annotate(Id entryId, AtomEntry entry, string slug)
    {
      LogService.Info("AnnotateService.Annotate entryId={0} slug={1}", entryId, slug);

      //authorization
      if (!AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.Annotate))
        throw new UserNotAuthorizedException(GetUser().Name, AuthAction.Annotate.ToString());

      AppCollection coll = AppService.GetCollection(entryId);

      //make sure type is accepted
      if (!coll.CanAccept(Atom.ContentTypeEntry))
        throw new InvalidContentTypeException(Atom.ContentTypeEntry);

      entry.SetNamespaces(); //TODO: is there a better place for this?

      //build id onto parent's id
      AtomEntry parent = AtomPubService.GetEntry(entryId);
      entry.Id = new Id(parent.Id.Owner, parent.Id.Date, parent.Id.Collection, entry.BuildPath(parent.Id.EntryPath, slug));
      
      var url = new UrlHelper(Container.GetInstance<RequestContext>());
      //this annotation is a reply to the parent entry, TODO: leave off href for later calc based on id?
      entry.InReplyTo = new ThreadInReplyTo()
      {
        Ref = parent.Id,
        Href = parent.IsExternal ? parent.Content.Src : url.RouteIdUri("AtomPubEntry", entry.Id, AbsoluteMode.Force),
        Type = parent.IsExternal ? parent.Content.Type : Atom.ContentTypeEntry
      };

      if (!entry.Published.HasValue) entry.Published = DateTimeOffset.UtcNow;
      entry.Updated = DateTimeOffset.UtcNow;
      entry.Edited = DateTimeOffset.UtcNow;

      if (entry.Authors.Count() == 0) entry.SetPerson(AuthorizeService, true);

      //entry.IdChanged += (e) => e.UpdateLinks(UrlHelper.RouteIdUri);

      //OnAnnotate(parent, entryId, entry, slug);
      if (AnnotatingEntry != null) AnnotatingEntry(entryId, entry, slug);

      if (entry.Authors.Count() == 0 || entry.Authors.First().Name == null)
        throw new AnnotationNotAllowedException(entry.Id, entry.AnnotationType, "the author cannot be determined");

      entry = AtomEntryRepository.CreateEntry(entry);
      if (EntryAnnotated != null) EntryAnnotated(entry);
      return entry;
    }
コード例 #4
0
 protected void Auth(Id id, AuthAction action)
 {
   User user = GetUser();
   if (!AuthorizeService.IsAuthorized(user, id.ToScope(), action))
     throw new UserNotAuthorizedException(user.Name, action.ToString());
 }
コード例 #5
0
 public int ApproveAll(Id id)
 {
     LogService.Info("AtomPubService.ApproveAll id={0}", id);
     AuthorizeService.Auth(id.ToScope(), AuthAction.ApproveEntryOrMedia);
     return AtomEntryRepository.ApproveAll(id);
 }
コード例 #6
0
 public void ApproveEntry(Id entryId, bool approved)
 {
     LogService.Info("AtomPubService.ApproveEntry entryId={0}", entryId);
     AuthorizeService.Auth(entryId.ToScope(), AuthAction.ApproveEntryOrMedia);
     AtomEntry e = AtomEntryRepository.GetEntry(entryId);
     if (e.Control == null) e.Control = new AppControl();
     e.Control.Approved = approved;
     AtomEntryRepository.UpdateEntry(e);
 }
コード例 #7
0
 public virtual Stream GetMedia(Id entryId, out string contentType)
 {
   LogService.Info("AtomPubService.GetMedia entryId={0}", entryId);
   AtomEntry mediaLinkEntry = AtomEntryRepository.GetEntry(entryId);
   contentType = mediaLinkEntry.Content.Type;
    //TODO: remove this hack
   SetLinks(mediaLinkEntry);
   //mediaLinkEntry.Content.Src = UrlHelper.RouteIdUri("AtomPubMedia", mediaLinkEntry.Id, AbsoluteMode.Force);
   
   //Allow authorized users to get media otherwise only get if visible
   if (AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.GetEntryOrMedia))
     return MediaRepository.GetMedia(mediaLinkEntry);
   else if (mediaLinkEntry.Visible)
   {
     //TODO: clean private data
     return MediaRepository.GetMedia(mediaLinkEntry);
   }
   throw new UserNotAuthorizedException(GetUser().Name, AuthAction.GetEntryOrMedia.ToString());
 }
コード例 #8
0
    public virtual AtomEntry UpdateEntry(Id entryId, AtomEntry entry, string slug)
    {
      LogService.Info("AtomPubService.UpdateEntry entryId={0}", entryId);
      Auth(entryId, AuthAction.UpdateEntryOrMedia);

      //ensure existing entry exists
      AtomEntry old = AtomEntryRepository.GetEntry(entryId);

      //copy old approval setting when not authorized to approve
      if (!AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.ApproveEntryOrMedia))
      {
        if (entry.Control != null && entry.Control.Approved.HasValue)
          entry.Control.Approved = old.Control.Approved;
        else
          entry.Control.Approved = false;
      }

      if (!entry.Draft && !entry.Published.HasValue) entry.Published = DateTimeOffset.UtcNow;
      entry.Updated = DateTimeOffset.UtcNow;
      entry.Edited = DateTimeOffset.UtcNow;

      //if (old.Draft) //allow Id to change when old was draft mode, is this safe?
      //{
      //  AppCollection coll = AppServiceRepository.GetService().GetCollection(entryId);
      //  if (coll.Dated)
      //    entry.Id = new Id(coll.Id.Owner, entry.Date.UtcDateTime, coll.Id.Collection, entry.BuildPath(null, slug));
      //  else
      //    entry.Id = new Id(coll.Id.Owner, coll.Id.Date, coll.Id.Collection, entry.BuildPath(null, slug));
      //}
      //else 
        entry.Id = entryId; //reset Id (it shouldn't change)

      if (old.Media) entry.Content = old.Content; //reset Content (it shouldn't change for media link entries)
      //entry.UpdateLinks(RouteFunc);
      SetPerson(entry);
      SetCategories(entry);
      SetLinks(entry);
      entry.IdChanged += (e) => SetLinks(e);// e.UpdateLinks(RouteFunc); //in case of changes during draft

      if (UpdatingEntry != null) UpdatingEntry(entryId, entry, slug);
      entry = AtomEntryRepository.UpdateEntry(entry);
      if (EntryUpdated != null) EntryUpdated(entry);

      return entry;
    }
コード例 #9
0
    public virtual AtomEntry CreateEntry(Id collectionId, AtomEntry entry, string slug)
    {
      LogService.Info("AtomPubService.CreateEntry collectionId={0} slug={1}", collectionId, slug);
      Auth(collectionId, AuthAction.CreateEntryOrMedia);
      AppCollection coll = AppServiceRepository.GetService().GetCollection(collectionId);
      if (entry.Control == null) entry.Control = new AppControl();

      //is acceptable type?
      if (!coll.CanAccept(Atom.ContentTypeEntry)) throw new InvalidContentTypeException(Atom.ContentTypeEntry);

      //approval based on role action matrix
      if (!AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.ApproveEntryOrMedia))
        entry.Control.Approved = false;

      if (!entry.Draft && !entry.Published.HasValue) entry.Published = DateTimeOffset.UtcNow;
      if (entry.Updated == default(DateTimeOffset)) entry.Updated = DateTimeOffset.UtcNow;
      entry.Edited = DateTimeOffset.UtcNow;
      if (coll.Dated)
        entry.Id = new Id(collectionId.Owner, entry.Date.UtcDateTime, collectionId.Collection, entry.BuildPath(null, slug));
      else
        entry.Id = new Id(collectionId.Owner, collectionId.Date, collectionId.Collection, entry.BuildPath(null, slug));

      SetPerson(entry);
      SetCategories(entry); 
      SetLinks(entry);
      entry.IdChanged += (e) => SetLinks(e);

      if (CreatingEntry != null) CreatingEntry(collectionId, entry, slug);
      entry = AtomEntryRepository.CreateEntry(entry);
      if (EntryCreated != null) EntryCreated(entry);

      return entry;
    }
コード例 #10
0
    public virtual AtomFeed GetFeedBySearch(Id collectionId, string term, int pageIndex, int pageSize)
    {
      LogService.Info("AtomPubService.GetFeedBySearch collectionId={0} term={1} pageIndex={2}", collectionId, term, pageIndex);
      Auth(collectionId, AuthAction.GetFeed);

      AppCollection c = AppServiceRepository.GetService().GetCollection(collectionId);

      EntryCriteria criteria = new EntryCriteria()
      {
        WorkspaceName = collectionId.Workspace,
        CollectionName = collectionId.Collection,
        SearchTerm = term,
        Authorized = AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.GetEntryOrMedia)
      };
      int total;
      //search annotations?

      AtomFeed feed = AtomFeed.BuildFeed(c, AtomEntryRepository.GetEntries(criteria, pageIndex, pageSize, out total),
        total);//, pageIndex, pageSize, RouteFunc, "AtomPubFeed", "AtomPubCollectionIndex", false);

      feed.Subtitle = new AtomSubtitle { Text = "Search for '" + term + "'" };
      SetLinks(feed);
      return feed;
    }
コード例 #11
0
    public virtual AtomFeed GetFeedByCategory(Id collectionId, string term, Uri scheme, int pageIndex, int pageSize)
    {
      LogService.Info("AtomPubService.GetFeedByCategory collectionId={0}, term={1}", collectionId, term);
      Auth(collectionId, AuthAction.GetFeed);

      AppCollection c = AppServiceRepository.GetService().GetCollection(collectionId);
      //TODO: support external categories
      AtomCategory category = c.Categories.SelectMany(cats => cats.Categories).Where(cat => cat.Term == term &&
          cat.Scheme == scheme).SingleOrDefault();
      if (category == null) throw new ResourceNotFoundException("category", term);

      EntryCriteria criteria = new EntryCriteria()
      {
        WorkspaceName = collectionId.Workspace,
        CollectionName = collectionId.Collection,
        CategoryTerm = term,
        CategoryScheme = scheme,
        Authorized = AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.GetEntryOrMedia)
      };
      int total;

      AtomFeed feed = AtomFeed.BuildFeed(c, AtomEntryRepository.GetEntries(criteria, pageIndex, pageSize, out total),
        total);//, pageIndex, pageSize, RouteFunc, "AtomPubFeed", "AtomPubCollectionIndex", false);

      feed.Subtitle = new AtomSubtitle { Text = "Browsing " + category.ToString() };
      SetLinks(feed);
      return feed;
    }
コード例 #12
0
    public virtual AtomFeed GetFeedByPerson(Id collectionId, string personName, int pageIndex, int pageSize)
    {
      LogService.Info("AtomPubService.GetFeedByPerson collectionId={0}, personName={1}", collectionId, personName);
      Auth(collectionId, AuthAction.GetFeed);

      AppCollection c = AppServiceRepository.GetService().GetCollection(collectionId);
      EntryCriteria criteria = new EntryCriteria()
      {
        WorkspaceName = collectionId.Workspace,
        CollectionName = collectionId.Collection,
        PersonName = personName,
        PersonType = "person",
        Authorized = AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.GetEntryOrMedia)
      };
      int total;

      AtomFeed feed = AtomFeed.BuildFeed(c, AtomEntryRepository.GetEntries(criteria, pageIndex, pageSize, out total),
        total);//, pageIndex, pageSize, RouteFunc, "AtomPubFeed", "AtomPubCollectionIndex", false);
      feed.Subtitle = new AtomSubtitle() { Text = personName };
      SetLinks(feed);
      return feed;
    }
コード例 #13
0
    public virtual AtomFeed GetFeedByDate(Id collectionId, DateTime startDate, DateTime endDate, int pageIndex, int pageSize)
    {
      LogService.Info("AtomPubService.GetFeedByDate collectionId={0}, startDate={1}, endDate={2}", collectionId, startDate, endDate);
      Auth(collectionId, AuthAction.GetFeed);

      AppCollection c = AppServiceRepository.GetService().GetCollection(collectionId);
      EntryCriteria criteria = new EntryCriteria()
      {
        WorkspaceName = collectionId.Workspace,
        CollectionName = collectionId.Collection,
        StartDate = startDate,
        EndDate = endDate,
        Authorized = AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.GetEntryOrMedia)
      };
      int total;
      AtomFeed feed = AtomFeed.BuildFeed(c, AtomEntryRepository.GetEntries(criteria, pageIndex, pageSize, out total),
        total);//, pageIndex, pageSize, RouteFunc, "AtomPubFeed", "AtomPubCollectionIndex", false);
      if (startDate.DayOfYear == 1 && endDate.DayOfYear > 354)
      {
        feed.Subtitle = new AtomSubtitle() { Text = "For the year " + startDate.Year.ToString("0000") };
      }
      else if (startDate.Day == 1 && endDate.Day == DateTime.DaysInMonth(endDate.Year, endDate.Month))
      {
        feed.Subtitle = new AtomSubtitle() { Text = "For " + startDate.ToString("MMMM yyyy") };
      }
      else if (startDate.Day == endDate.Day)
      {
        feed.Subtitle = new AtomSubtitle() { Text = "For " + startDate.ToString("D") };
      }
      else
      {
        feed.Subtitle = new AtomSubtitle()
        {
          Text = "From " + startDate.ToShortDateString() + " to " +
            endDate.ToShortDateString()
        };
      }
      SetLinks(feed);
      return feed;
    }
コード例 #14
0
    public virtual AtomFeed GetFeed(Id collectionId, int pageIndex, int pageSize)
    {
      //<atom:link rel="alternate" type="text/html" href="https://atomsite.net/blog.xhtml" />

      LogService.Info("AtomPubService.GetFeed collectionId={0}", collectionId);
      Auth(collectionId, AuthAction.GetFeed);
      AppCollection c = AppServiceRepository.GetService().GetCollection(collectionId);
      EntryCriteria criteria = new EntryCriteria()
      {
        WorkspaceName = collectionId.Workspace,
        CollectionName = collectionId.Collection,
        Authorized = AuthorizeService.IsAuthorized(GetUser(), collectionId.ToScope(), AuthAction.GetEntryOrMedia),
      };
      int total;
      AtomFeed feed = AtomFeed.BuildFeed(c, AtomEntryRepository.GetEntries(criteria, pageIndex, pageSize, out total),
        total);//, pageIndex, pageSize, RouteFunc, "AtomPubFeed", "AtomPubCollectionIndex", true);

      var url = new UrlHelper(Container.GetInstance<RequestContext>());
      feed.Links = feed.Links.Concat(url.GetPagingLinks("AtomPubFeed", feed.Id, null, feed.TotalResults ?? 0, 
        pageIndex, pageSize,Atom.ContentTypeFeed, AbsoluteMode.Force));

      SetLinks(feed);
      return feed;
    }
コード例 #15
0
    public virtual AtomFeed GetAnnotations(Id id, bool deep, int pageIndex, int pageSize)
    {
      LogService.Info("AnnotateService.GetAnnotations: {0} deep={1}", id, deep);

      //authorization
      if (!AuthorizeService.IsAuthorized(GetUser(), id.ToScope(), AuthAction.GetAnnotations))
        throw new UserNotAuthorizedException(GetUser().Name, AuthAction.GetAnnotations.ToString());

      return GetAnnotations(new EntryCriteria()
      {
        EntryId = id.EntryPath != null ? id : null,
        WorkspaceName = id.EntryPath == null ? id.Workspace : null,
        CollectionName = id.EntryPath == null ? id.Collection : null,
        SortMethod = id.EntryPath == null ? SortMethod.DateDesc : SortMethod.Default,
        Authorized = AuthorizeService.IsAuthorized(GetUser(), id.ToScope(), AuthAction.GetEntryOrMedia),
        Annotations = true,
        Deep = deep
      }, pageIndex, pageSize);
    }
コード例 #16
0
    /// <summary>
    /// Get an entry from the collection.  This method supports Anonymous
    /// retrieval.
    /// </summary>
    /// <param name="entryId"></param>
    /// <returns></returns>
    public virtual AtomEntry GetEntry(Id entryId)
    {
      LogService.Info("AtomPubService.GetEntry entryId={0}", entryId);
      AtomEntry entry = AtomEntryRepository.GetEntry(entryId);
      SetLinks(entry);
      //entry.UpdateLinks(RouteFunc);

      //OnGetEntry(entry);

      //Allow authorized users to get entry otherwise only get if visible
      if (AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.GetEntryOrMedia))
        return entry;
      else if (entry.Visible)
      {
        //TODO: clean private data
        return entry;
      }
      throw new UserNotAuthorizedException(GetUser().Name, AuthAction.GetEntryOrMedia.ToString());
    }
コード例 #17
0
    public virtual AnnotationState GetAnnotationState(AppCollection coll, Id entryId)
    {
      LogService.Info("AnnotateService.GetAnnotationState entryId={0}", entryId);

      if (!coll.AnnotationsOn)
      {
        return AnnotationState.Off;
      }
      else if (!AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.Annotate))
      {
        return AnnotationState.Unauthorized;
      }
      else if (!AtomEntryRepository.GetEntry(entryId).AllowAnnotate)
      {
        return AnnotationState.Closed;
      }
      //TODO: handle expired
      return AnnotationState.On;
    }
コード例 #18
0
    protected void OnAnnotateEntry(Id entryId, AtomEntry entry, string slug)
    {
      LogService.Info("BlogService.OnAnnotateEntry");
      if (!new BlogAppCollection(AppService.GetCollection(entryId)).BloggingOn) return;
      //TODO: check if author url (referrer) is blocked

      //TODO: check if content src is blocked

      //TODO: check if spam

      if (entry.AnnotationType == null) entry.AnnotationType = "comment";

      AppCollection coll = AppService.GetCollection(entryId);
      AnnotationState state = AnnotateService.GetAnnotationState(coll, entryId);
      if (state != AnnotationState.On)
        throw new AnnotationNotAllowedException(entryId.ToString(), entry.AnnotationType, "the state is " + state);


      //default title to comment when not given
      if (entry.Title == null || string.IsNullOrEmpty(entry.Title.Text))
        entry.Title = new AtomText(Atom.AtomNs + "title") { Text = "Comment" };

      //approved?
      if (!AuthorizeService.IsAuthorized((User)System.Threading.Thread.CurrentPrincipal.Identity,
        entry.Id.ToScope(), AuthAction.ApproveAnnotation))
      {
        entry.Control = new AppControl() { Approved = false };
      }

      //clean input
      if (entry.Content.Type == "html" || entry.Content.Type == "xhtml")
      {
        if (AuthorizeService.IsAuthorized((User)System.Threading.Thread.CurrentPrincipal.Identity,
          entryId.ToScope(), AuthAction.ApproveAnnotation))
          CleanContentService.CleanContentTrusted(entry.Content);
        else
          CleanContentService.CleanContentFully(entry.Content);
      }
      else if (entry.Content.Type == "text")
      {
          entry.Content.Text = entry.Content.Text.Replace("<", "&lt;").Replace(">", "&gt;");
      }

      else if (entry.Content.Src == null)
          throw new AnnotationNotAllowedException(entryId.ToString(), entry.AnnotationType, "content must be text, html, or external.");

      AtomEntry parent = AtomEntryRepository.GetEntry(entryId);
      //check if there is already a content src annotation with this link
      int total;
      if (entry.IsExternal && AtomEntryRepository.GetEntries(
        new EntryCriteria()
        {
          EntryId = parent.Id,
          Annotations = true,
          Authorized = true,
          Deep = true
        }, 0, int.MaxValue, out total)
        .Where(a => a.Content.Src != null && a.Content.Src == entry.Content.Src).Count() > 0)
        throw new AnnotationNotAllowedException(parent.Id, entry.AnnotationType, "it already contains a link to the source.");

      //TODO: allow categories on annotations?
      entry.Categories = null;
    }