adds access by circle to blog posts

This commit is contained in:
Paul Schneider
2015-07-02 14:42:18 +02:00
parent 9da7064791
commit f25aa8ff97
32 changed files with 466 additions and 275 deletions

View File

@ -24,6 +24,8 @@ using Yavsc.Model.RolesAndMembers;
using System.Collections.Generic;
using Yavsc.Model.Circles;
using System.Web.Security;
using System.Collections.Specialized;
using Yavsc.Model;
namespace Yavsc.ApiControllers
{
@ -91,12 +93,11 @@ namespace Yavsc.ApiControllers
return c;
}
/// <summary>
/// List the circles
/// </summary>
[Authorize]
public CircleInfoCollection List()
public IEnumerable<ListItem> List()
{
string user = Membership.GetUser ().UserName;
return CircleManager.DefaultProvider.List (user);

View File

@ -1,3 +1,20 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* Web.csproj:
* Web.config:
* instdbws.sql:
* Web.config:
* Edit.aspx:
* YavscHelpers.cs:
* ThanksHelper.cs:
* Circles.aspx:
* BlogsController.cs:
* TitleNotFound.aspx:
* NotAuthorized.aspx:
* TexToPdfFormatter.cs:
* AccountController.cs:
* CircleController.cs:
2015-06-28 Paul Schneider <paul@pschneider.fr>
* AccountController.cs: Fixes the canonical login

View File

@ -309,10 +309,8 @@ namespace Yavsc.Controllers
public ActionResult Circles ()
{
string user = Membership.GetUser ().UserName;
CircleInfoCollection cic = CircleManager.DefaultProvider.List (user);
if (cic == null)
cic = new CircleInfoCollection ();
return View (cic);
ViewData["Circles"] = CircleManager.DefaultProvider.List (user);
return View ();
}
/// <summary>
/// Logout the specified returnUrl.

View File

@ -17,6 +17,7 @@ using Yavsc.ApiControllers;
using Yavsc.Model.RolesAndMembers;
using System.Net;
using System.Web.Mvc;
using Yavsc.Model.Circles;
namespace Yavsc.Controllers
{
@ -94,9 +95,6 @@ namespace Yavsc.Controllers
return View ("Index", bs);
}
// page index becomes one-based
/// <summary>
/// Users the posts.
/// </summary>
@ -112,12 +110,15 @@ namespace Yavsc.Controllers
FindBlogEntryFlags sf = FindBlogEntryFlags.MatchUserName;
ViewData ["SiteName"] = sitename;
ViewData ["BlogUser"] = user;
string readersName = null;
// displays invisible items when the logged user is also the author
if (u != null)
if (u.UserName == user)
sf |= FindBlogEntryFlags.MatchInvisible;
if (u != null) {
if (u.UserName == user || Roles.IsUserInRole ("Admin"))
sf |= FindBlogEntryFlags.MatchInvisible;
readersName = u.UserName;
}
// find entries
BlogEntryCollection c = BlogManager.FindPost (user, sf, pageIndex, pageSize, out tr);
BlogEntryCollection c = BlogManager.FindPost (readersName, user, sf, pageIndex, pageSize, out tr);
// Get author's meta data
Profile bupr = new Profile (ProfileBase.Create (user));
ViewData ["BlogUserProfile"] = bupr;
@ -155,7 +156,7 @@ namespace Yavsc.Controllers
return View ("TitleNotFound");
Profile pr = new Profile (ProfileBase.Create (e.UserName));
if (pr==null)
return View ("TitleNotFound");
return View ("NotAuthorized");
ViewData ["BlogUserProfile"] = pr;
ViewData ["BlogTitle"] = pr.BlogTitle;
ViewData ["Avatar"] = pr.avatar;
@ -163,17 +164,33 @@ namespace Yavsc.Controllers
if (u != null)
ViewData ["UserName"] = u.UserName;
if (!e.Visible || !pr.BlogVisible) {
if (u==null)
return View ("TitleNotFound");
// only deliver to admins or owner
if (u == null)
return View ("NotAuthorized");
else {
if (u.UserName!=e.UserName)
if (!Roles.IsUserInRole(u.UserName,"Admin"))
return View ("TitleNotFound");
if (u.UserName != e.UserName)
if (!Roles.IsUserInRole (u.UserName, "Admin"))
return View ("NotAuthorized");
}
} else {
if (!CanViewPost(e,u))
return View ("NotAuthorized");
}
ViewData ["Comments"] = BlogManager.GetComments (e.Id);
return View ("UserPost", e);
}
private bool CanViewPost (BlogEntry e, MembershipUser u=null) {
if (e.AllowedCircles!=null && e.AllowedCircles.Length > 0) {
// only deliver to admins, owner, or specified circle memebers
if (u == null)
return false;
if (u.UserName != e.UserName)
if (!Roles.IsUserInRole (u.UserName, "Admin"))
if (!CircleManager.DefaultProvider.Matches (e.AllowedCircles, u.UserName))
return false;
}
return true;
}
/// <summary>
/// Users the post.
/// </summary>
@ -208,26 +225,14 @@ namespace Yavsc.Controllers
if (String.IsNullOrEmpty (title))
title = "";
ViewData ["UserName"] = un;
ViewData["AllowedCircles"] = CircleManager.DefaultProvider.List (Membership.GetUser ().UserName).Select (x => new SelectListItem {
Value = x.Value,
Text = x.Text
});
return View ("Edit", new BlogEntry { Title = title });
}
/// <summary>
/// Validates the post.
/// </summary>
/// <returns>The post.</returns>
/// <param name="model">Model.</param>
[Authorize,
ValidateInput(false)]
public ActionResult ValidatePost (BlogEntry model)
{
string username = Membership.GetUser ().UserName;
ViewData ["SiteName"] = sitename;
ViewData ["BlogUser"] = username;
if (ModelState.IsValid) {
BlogManager.Post (username, model.Title, model.Content, model.Visible);
return UserPost (username, model.Title);
}
return View ("Post", model);
}
/// <summary>
/// Validates the edit.
/// </summary>
@ -241,13 +246,14 @@ namespace Yavsc.Controllers
ViewData ["BlogUser"] = Membership.GetUser ().UserName;
if (ModelState.IsValid) {
if (model.Id != 0)
BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible);
BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible, model.AllowedCircles);
else
BlogManager.Post (model.UserName, model.Title, model.Content, model.Visible);
return UserPost(model.UserName, model.Title);
model.Id = BlogManager.Post (model.UserName, model.Title, model.Content, model.Visible, model.AllowedCircles);
return RedirectToAction ("UserPost",new { user = model.UserName, title = model.Title });
}
return View ("Edit", model);
}
/// <summary>
/// Edit the specified model.
/// </summary>
@ -256,25 +262,33 @@ namespace Yavsc.Controllers
ValidateInput(false)]
public ActionResult Edit (BlogEntry model)
{
if (model != null) {
string user = Membership.GetUser ().UserName;
Profile pr = new Profile (HttpContext.Profile);
string user = Membership.GetUser ().UserName;
Profile pr = new Profile (HttpContext.Profile);
ViewData ["BlogTitle"] = pr.BlogTitle;
ViewData ["UserName"] = user;
if (model.UserName == null) {
model.UserName = user;
}
BlogEntry e = BlogManager.GetPost (model.UserName, model.Title);
if (e != null) {
if (e.UserName != user) {
return View ("TitleNotFound");
}
model = e;
ModelState.Clear ();
TryValidateModel (model);
}
ViewData ["BlogTitle"] = pr.BlogTitle;
ViewData ["UserName"] = user;
if (model.UserName == null) {
model.UserName = user;
}
BlogEntry e = BlogManager.GetPost (model.UserName, model.Title);
if (e != null) {
if (e.UserName != user) {
return View ("NotAuthorized");
}
model = e;
ModelState.Clear ();
TryValidateModel (model);
}
if (model.AllowedCircles==null)
model.AllowedCircles = new long[0];
ViewData["AllowedCircles"] = CircleManager.DefaultProvider.List (Membership.GetUser ().UserName).Select (x => new SelectListItem {
Value = x.Value,
Text = x.Text,
Selected = model.AllowedCircles.Contains(long.Parse(x.Value))
});
return View (model);
}

View File

@ -112,7 +112,12 @@ namespace Yavsc.Formatters
if (contentHeaders != null)
SetFileName(contentHeaders, value.GetHashCode ().ToString ());
}
/// <summary>
/// Sets the name of the file.
/// </summary>
/// <param name="contentHeaders">Content headers.</param>
/// <param name="basename">Basename.</param>
public static void SetFileName(HttpContentHeaders contentHeaders, string basename) {
contentHeaders.ContentDisposition = new ContentDispositionHeaderValue ("attachment") {
FileName = "doc-" + basename + ".pdf"

View File

@ -2,6 +2,8 @@ using System;
using System.Configuration;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq.Expressions;
using Yavsc.Model.Circles;
namespace Yavsc.Helpers
{
@ -55,6 +57,7 @@ namespace Yavsc.Helpers
result.Add( new Link { Url = e.Url, Image=e.Image, Text = e.Name });
return result.ToArray();
}
}
}

View File

@ -9,6 +9,10 @@ using System.Web.Http.ModelBinding;
using Yavsc.Model.RolesAndMembers;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Mvc;
using Yavsc.Model.Circles;
using System.Web.UI;
using System.Linq.Expressions;
namespace Yavsc.Helpers
{
@ -17,9 +21,6 @@ namespace Yavsc.Helpers
/// </summary>
public static class YavscHelpers
{
private static string siteName = null;
/// <summary>
/// Gets the name of the site.

View File

@ -1,4 +1,4 @@
<%@ Page Title="Circles" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<Yavsc.Model.Circles.CircleInfoCollection>" %>
<%@ Page Title="Circles" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %>
<asp:Content ID="headContent" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript" src="<%=Url.Content("~/Scripts/stupidtable.js")%>"></script>
@ -13,9 +13,9 @@
</thead>
<tbody id="tbcb">
<% int lc=0;
foreach (CircleInfo ci in Model) { lc++; %>
<tr class="<%= (ci.Id%2==0)?"even ":"odd " %>row" id="c_<%=ci.Id%>">
<td><%=ci.Title%></td>
foreach (SelectListItem ci in ViewData["Circles"]) { lc++; %>
<tr class="<%= (lc%2==0)?"even ":"odd " %>row" id="c_<%=ci.Value%>">
<td><%=ci.Text%></td>
<td>
<input type="button" value="<%=Html.Translate("Remove")%>" class="actionlink rowbtnrm"/>
<input type="button" value="<%=Html.Translate("Members")%>" class="actionlink rowbtnvw"/>

View File

@ -1,4 +1,5 @@
<%@ Page Title="Bill edition" Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntry>" MasterPageFile="~/Models/App.master" %>
<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %>
<asp:Content ContentPlaceHolderID="head" ID="HeadContent1" runat="server">
<link rel="stylesheet" href="<%=Url.Content("~/Theme/mdd_styles.css")%>">
<script type="text/javascript" src="<%=Url.Content("~/Scripts/MarkdownDeepLib.min.js")%>">
@ -26,15 +27,26 @@
<br/>
<%= Html.CheckBox( "Visible" ) %>
<%= Html.LabelFor(model => model.Visible) %>
<%= Html.ValidationMessage("Visible", "*") %>
<%= Html.Hidden("Id") %>
<%= Html.Hidden("UserName") %>
<br/>
<%= Html.LabelFor(model => model.AllowedCircles) %>
<%= Html.ListBox("AllowedCircles") %>
<%= Html.ValidationMessage("AllowedCircles", "*") %>
<%= Html.Hidden("Id") %>
<%= Html.Hidden("UserName") %>
<br/>
<input type="submit"/>
<% } %>
<script>
$(document).ready(function () {
$("textarea.mdd_editor").MarkdownDeep({
help_location: "/Scripts/html/mdd_help.htm",

View File

@ -0,0 +1,4 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntryCollection>" MasterPageFile="~/Models/App.master"%>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
Ce contenu est d'accès restreint : &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
</asp:Content>

View File

@ -1,8 +1,5 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntryCollection>" MasterPageFile="~/Models/App.master"%>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
Pas d'article trouvé ici: &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
<br/>
<%= Html.ActionLink("Poster?","Post/", new { user = ViewData["BlogUser"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %>
</asp:Content>
Pas d'article trouvé ici: &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
<br/> <%= Html.ActionLink("Poster?","Post/", new { user = ViewData["BlogUser"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %>
</asp:Content>

View File

@ -36,7 +36,7 @@
<system.webServer>
<defaultDocument enabled="true"> <!-- this line enables default documents for a directory -->
<files>
<clear/> <!-- removes the existing default document list -->
<!-- <clear/> removes the existing default document list -->
<add value="Index"/>
</files>
</defaultDocument>

View File

@ -36,7 +36,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
affects performance, set this value to true only
during development.
-->
<compilation defaultLanguage="C#" debug="true" batch="false">
<compilation defaultLanguage="C#" debug="true" >
<assemblies>
<add assembly="System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
@ -185,14 +185,6 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql" />
</DbProviderFactories>
</system.data>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<remove name="Default" />
<add name="Default" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" />
</listeners>
</trace>
</system.diagnostics>
<catalog defaultProvider="XmlCatalogProvider">
<providers>
<add name="XmlCatalogProvider" connection="~/Catalog.xml" applicationName="/" type="SalesCatalog.XmlImplementation.XmlCatalogProvider, SalesCatalog" />
@ -255,6 +247,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="yavsc" connectionString="Server=127.0.0.1;Port=5432;Database=YavscDev;User Id=yavscdev;Password=admin;Encoding=Unicode;" providerName="Npgsql" />
</connectionStrings>
<appSettings>
<add key="MonoServerDefaultIndexFiles" value="index.html,Index.aspx" />
<add key="WorkflowContentProviderClass" value="yavsc.NpgsqlContentProvider" />
<add key="SmtpServer" value="smtp.free.fr" />
<add key="AdminEMail" value="paulschneider@free.fr" />

View File

@ -348,6 +348,7 @@
<Content Include="Views\Account\Circles.aspx" />
<Content Include="Views\Account\Register.ascx" />
<Content Include="Views\Account\ResetPassword.aspx" />
<Content Include="Views\Blogs\NotAuthorized.aspx" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@ -667,8 +667,7 @@ CREATE TABLE circle
WITH (
OIDS=FALSE
);
ALTER TABLE circle
OWNER TO yavscdev;
COMMENT ON COLUMN circle._id IS 'Circle identifier';
COMMENT ON COLUMN circle.owner IS 'creator of this circle';
COMMENT ON COLUMN circle.applicationname IS 'Application name';
@ -709,5 +708,23 @@ WITH (
);
-- Table: blog_access
-- DROP TABLE blog_access;
CREATE TABLE blog_access
(
post_id bigint NOT NULL,
circle_id bigint NOT NULL,
CONSTRAINT blog_access_pkey PRIMARY KEY (post_id, circle_id),
CONSTRAINT blog_access_circle_id_fkey FOREIGN KEY (circle_id)
REFERENCES circle (_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT blog_access_post_id_fkey FOREIGN KEY (post_id)
REFERENCES blog (_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);