bug fixes

This commit is contained in:
Paul Schneider
2024-11-10 23:12:02 +00:00
parent 86dc1b8a2b
commit f3a63c9e46
28 changed files with 261 additions and 234 deletions

View File

@ -10,29 +10,19 @@ using Yavsc.Attributes.Validation;
using Yavsc.Interfaces; using Yavsc.Interfaces;
using Yavsc.Models.Access; using Yavsc.Models.Access;
using Yavsc.Models.Relationship; using Yavsc.Models.Relationship;
using Yavsc.ViewModels.Blog;
namespace Yavsc.Models.Blog namespace Yavsc.Models.Blog
{ {
public class BlogPost : IBlogPost, ICircleAuthorized, ITaggable<long>, IIdentified<long> public class BlogPost : BlogPostInputViewModel, IBlogPost, ICircleAuthorized, ITaggable<long>, IIdentified<long>
{ {
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Display(Name="Identifiant du post")] [Display(Name="Identifiant du post")]
public long Id { get; set; } public long Id { get; set; }
[Display(Name="Contenu")][YaStringLength(56224)]
public string Content { get; set; }
[Display(Name="Photo")][YaStringLength(1024)]
public string Photo { get; set; }
[YaStringLength(8)]
public string Lang { get; set; }
[Display(Name="Indice de qualité")] [Display(Name="Indice de qualité")]
public int Rate { get; set; } public int Rate { get; set; }
[Display(Name="Titre")][YaStringLength(1024)]
public string Title { get; set; }
[Display(Name="Identifiant de l'auteur")] [Display(Name="Identifiant de l'auteur")]
[ForeignKey("Author")] [ForeignKey("Author")]
@ -41,8 +31,6 @@ namespace Yavsc.Models.Blog
[Display(Name="Auteur")] [Display(Name="Auteur")]
public virtual ApplicationUser Author { set; get; } public virtual ApplicationUser Author { set; get; }
[Display(Name="Visible")]
public bool Visible { get; set; }
[Display(Name="Date de création")] [Display(Name="Date de création")]
public DateTime DateCreated public DateTime DateCreated
@ -68,10 +56,6 @@ namespace Yavsc.Models.Blog
get; set; get; set;
} }
[InverseProperty("Target")]
[Display(Name="Liste de contrôle d'accès")]
public virtual List<CircleAuthorizationToBlogPost> ACL { get; set; }
public bool AuthorizeCircle(long circleId) public bool AuthorizeCircle(long circleId)
{ {
return ACL?.Any( i=>i.CircleId == circleId) ?? true; return ACL?.Any( i=>i.CircleId == circleId) ?? true;

View File

@ -1,26 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using Yavsc.Models;
namespace Yavsc.Server.Models.Blog
{
public class BlogTrad
{
[Required]
public long PostId { get; set; }
[Required]
public string Lang { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string TraducerId { get; set; }
[ForeignKey("TraducerId"),JsonIgnore]
public ApplicationUser Traducer { set; get; }
}
}

View File

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Access;
namespace Yavsc.ViewModels.Blog
{
public class BlogPostInputViewModel
{
[StringLength(1024)]
public string? Photo { get; set; }
[StringLength(1024)]
public required string Title { get; set; }
[StringLength(56224)]
public required string Content { get; set; }
public bool Visible { get; set; }
[InverseProperty("Target")]
[Display(Name="Liste de contrôle d'accès")]
public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; }
}
}

View File

@ -7,6 +7,7 @@ namespace Yavsc.ViewModels.Relationship
public CirclesViewModel(ICircleAuthorized resource) public CirclesViewModel(ICircleAuthorized resource)
{ {
Target = resource; Target = resource;
if (resource!=null)
TargetTypeName = resource.GetType().Name; TargetTypeName = resource.GetType().Name;
} }
public ICircleAuthorized Target { get; set; } public ICircleAuthorized Target { get; set; }

View File

@ -65,7 +65,7 @@ namespace Yavsc.ApiControllers
} }
_logger.LogInformation($"Receiving files, saved in '{destDir}' (specified as '{subdir}')."); _logger.LogInformation($"Receiving files, saved in '{destDir}' (specified as '{subdir}').");
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var uid = User.GetUserId();
var user = dbContext.Users.Single( var user = dbContext.Users.Single(
u => u.Id == uid u => u.Id == uid
); );

View File

@ -235,9 +235,16 @@ namespace Yavsc.Controllers
/// <summary> /// <summary>
/// Show logout page /// Show logout page
/// </summary> /// </summary>
[HttpGet] [HttpGet][Authorize]
public async Task<IActionResult> Logout(string logoutId) public async Task<IActionResult> Logout(string logoutId)
{ {
if (string.IsNullOrWhiteSpace(logoutId))
{
if (User.Identity.IsAuthenticated)
{
logoutId = User.GetUserId();
}
}
// build a model so the logout page knows what to display // build a model so the logout page knows what to display
var vm = await BuildLogoutViewModelAsync(logoutId); var vm = await BuildLogoutViewModelAsync(logoutId);
@ -265,9 +272,11 @@ namespace Yavsc.Controllers
{ {
// delete local authentication cookie // delete local authentication cookie
await HttpContext.SignOutAsync(); await HttpContext.SignOutAsync();
await _signInManager.SignOutAsync();
// raise the logout event // raise the logout event
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName())); await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
} }
// check if we need to trigger sign-out at an upstream identity provider // check if we need to trigger sign-out at an upstream identity provider
@ -282,6 +291,9 @@ namespace Yavsc.Controllers
return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme); return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
} }
return View("LoggedOut", vm); return View("LoggedOut", vm);
} }

View File

@ -60,7 +60,7 @@ namespace Yavsc.Controllers
{ {
ViewBag.IsAdmin = User.IsInRole(Constants.AdminGroupName); ViewBag.IsAdmin = User.IsInRole(Constants.AdminGroupName);
ViewBag.IsPerformer = User.IsInRole(Constants.PerformerGroupName); ViewBag.IsPerformer = User.IsInRole(Constants.PerformerGroupName);
ViewBag.AllowEdit = announce==null || announce.Id<=0 || !_authorizationService.AuthorizeAsync(User,announce,new EditRequirement()).IsFaulted; ViewBag.AllowEdit = announce==null || announce.Id<=0 || !_authorizationService.AuthorizeAsync(User,announce,new EditPermission()).IsFaulted;
List<SelectListItem> dl = new List<SelectListItem>(); List<SelectListItem> dl = new List<SelectListItem>();
var rnames = System.Enum.GetNames(typeof(Reason)); var rnames = System.Enum.GetNames(typeof(Reason));
var rvalues = System.Enum.GetValues(typeof(Reason)); var rvalues = System.Enum.GetValues(typeof(Reason));

View File

@ -14,6 +14,8 @@ using Yavsc.Helpers;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using Yavsc.ViewModels.Blog;
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 // For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
@ -111,30 +113,35 @@ namespace Yavsc.Controllers
[Authorize()] [Authorize()]
public IActionResult Create(string title) public IActionResult Create(string title)
{ {
var result = new BlogPost{Title=title}; var result = new BlogPostInputViewModel{Title=title,Content=""};
ViewData["PostTarget"]="Create"; ViewData["PostTarget"]="Create";
SetLangItems(); SetLangItems();
return View("Edit",result); return View(result);
} }
// POST: Blog/Create // POST: Blog/Create
[HttpPost, Authorize, ValidateAntiForgeryToken] [HttpPost, Authorize, ValidateAntiForgeryToken]
public IActionResult Create(Models.Blog.BlogPost blog) public IActionResult Create(BlogPostInputViewModel blogInput)
{ {
blog.Rate = 0;
blog.AuthorId = User.GetUserId();
blog.Id=0;
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
BlogPost post = new BlogPost
_context.Blogspot.Add(blog); {
Title = blogInput.Title,
Content = blogInput.Content,
Photo = blogInput.Photo,
Rate = 0,
AuthorId = User.GetUserId()
};
_context.Blogspot.Add(post);
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
ModelState.AddModelError("Unknown","Invalid Blog posted ..."); ModelState.AddModelError("Unknown","Invalid Blog posted ...");
ViewData["PostTarget"]="Create"; ViewData["PostTarget"]="Create";
return View("Edit",blog); return View("Edit",blogInput);
} }
[Authorize()] [Authorize()]
// GET: Blog/Edit/5 // GET: Blog/Edit/5
public async Task<IActionResult> Edit(long? id) public async Task<IActionResult> Edit(long? id)
@ -147,12 +154,11 @@ namespace Yavsc.Controllers
ViewData["PostTarget"]="Edit"; ViewData["PostTarget"]="Edit";
BlogPost blog = _context.Blogspot.Include(x => x.Author).Include(x => x.ACL).Single(m => m.Id == id); BlogPost blog = _context.Blogspot.Include(x => x.Author).Include(x => x.ACL).Single(m => m.Id == id);
if (blog == null) if (blog == null)
{ {
return NotFound(); return NotFound();
} }
if (!_authorizationService.AuthorizeAsync(User, blog, new EditRequirement()).IsFaulted) if (!_authorizationService.AuthorizeAsync(User, blog, new EditPermission()).IsFaulted)
{ {
ViewBag.ACL = _context.Circle.Where( ViewBag.ACL = _context.Circle.Where(
c=>c.OwnerId == blog.AuthorId) c=>c.OwnerId == blog.AuthorId)
@ -180,7 +186,7 @@ namespace Yavsc.Controllers
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var auth = _authorizationService.AuthorizeAsync(User, blog, new EditRequirement()); var auth = _authorizationService.AuthorizeAsync(User, blog, new EditPermission());
if (!auth.IsFaulted) if (!auth.IsFaulted)
{ {
// saves the change // saves the change

View File

@ -29,6 +29,7 @@ using Yavsc.Models.Market;
using Yavsc.Models.Workflow; using Yavsc.Models.Workflow;
using Yavsc.Services; using Yavsc.Services;
using Yavsc.Settings; using Yavsc.Settings;
using Yavsc.ViewModels.Auth;
namespace Yavsc.Extensions; namespace Yavsc.Extensions;
@ -308,7 +309,12 @@ internal static class HostingExtensions
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456")); // options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement())); // options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser()); options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
options.AddPolicy("IsTheAuthor", policy =>
policy.Requirements.Add(new EditPermission()));
}); });
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
_ = services.AddControllersWithViews() _ = services.AddControllersWithViews()
.AddNewtonsoftJson(); .AddNewtonsoftJson();
LoadGoogleConfig(builder.Configuration); LoadGoogleConfig(builder.Configuration);

View File

@ -0,0 +1,46 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Yavsc.ViewModels.Auth;
namespace Yavsc.Extensions;
public class PermissionHandler : IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();
foreach (var requirement in pendingRequirements)
{
if (requirement is ReadPermission)
{
if (IsOwner(context.User, context.Resource)
|| IsSponsor(context.User, context.Resource))
{
context.Succeed(requirement);
}
}
else if (requirement is EditPermission || requirement is DeletePermission)
{
if (IsOwner(context.User, context.Resource))
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
private static bool IsOwner(ClaimsPrincipal user, object? resource)
{
// Code omitted for brevity
return true;
}
private static bool IsSponsor(ClaimsPrincipal user, object? resource)
{
// Code omitted for brevity
return true;
}
}

View File

@ -117,7 +117,18 @@ namespace Yavsc.Helpers
InternalAnchor a = (InternalAnchor) elt; InternalAnchor a = (InternalAnchor) elt;
sb.AppendFormat("<a name=\"{0}\">{1}</a> ", a.Id, a.XRefLabel); sb.AppendFormat("<a name=\"{0}\">{1}</a> ", a.Id, a.XRefLabel);
break; break;
case "AsciiDocNet.Subscript":
sb.AppendHtml("<sup>");
Subscript sub = (Subscript)elt;
sub.ToHtml(sb);
sb.AppendHtml("</sup>");
break;
case "AsciiDocNet.Superscript":
sb.AppendHtml("<sup>");
Superscript sup = (Superscript)elt;
sup.ToHtml(sb);
sb.AppendHtml("</sup>");
break;
default: default:
string unsupportedType = elt.GetType().FullName; string unsupportedType = elt.GetType().FullName;
throw new InvalidProgramException(unsupportedType); throw new InvalidProgramException(unsupportedType);

View File

@ -35,7 +35,6 @@ namespace Yavsc.Models
using Calendar; using Calendar;
using Blog; using Blog;
using Yavsc.Abstract.Identity; using Yavsc.Abstract.Identity;
using Yavsc.Server.Models.Blog;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Yavsc.Server.Models.Calendar; using Yavsc.Server.Models.Calendar;
@ -79,7 +78,6 @@ namespace Yavsc.Models
builder.Entity<Models.Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin }); builder.Entity<Models.Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam"); builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId }); builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId });
builder.Entity<BlogTrad>().HasKey(tr => new { post = tr.PostId, lang = tr.Lang });
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument= i.InstrumentId, owner = i.OwnerId }); builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument= i.InstrumentId, owner = i.OwnerId });
foreach (var et in builder.Model.GetEntityTypes()) foreach (var et in builder.Model.GetEntityTypes())
@ -291,8 +289,6 @@ namespace Yavsc.Models
public DbSet<Project> Project { get; set; } public DbSet<Project> Project { get; set; }
public DbSet<BlogTrad> BlogTrad { get; set; }
[Obsolete("use signaled flows")] [Obsolete("use signaled flows")]
public DbSet<LiveFlow> LiveFlow { get; set; } public DbSet<LiveFlow> LiveFlow { get; set; }

View File

@ -19,6 +19,8 @@ namespace Yavsc.ViewComponents
public IViewComponentResult Invoke (ICircleAuthorized target) public IViewComponentResult Invoke (ICircleAuthorized target)
{
if (target!=null)
{ {
var oid = target.GetOwnerId(); var oid = target.GetOwnerId();
ViewBag.ACL = dbContext.Circle.Where( ViewBag.ACL = dbContext.Circle.Where(
@ -41,6 +43,8 @@ namespace Yavsc.ViewComponents
Checked = target.AuthorizeCircle(c.Id), Checked = target.AuthorizeCircle(c.Id),
Value = c.Id.ToString() Value = c.Id.ToString()
}); });
}
return View(new CirclesViewModel(target)); return View(new CirclesViewModel(target));
} }
} }

View File

@ -2,10 +2,25 @@ using Microsoft.AspNetCore.Authorization;
namespace Yavsc.ViewModels.Auth namespace Yavsc.ViewModels.Auth
{ {
public class EditRequirement : IAuthorizationRequirement public class EditPermission : IAuthorizationRequirement
{ {
public EditRequirement() public EditPermission()
{ {
} }
} }
public class ReadPermission: IAuthorizationRequirement
{
public ReadPermission()
{
}
}
public class DeletePermission: IAuthorizationRequirement
{
public DeletePermission()
{
}
}
} }

View File

@ -0,0 +1,85 @@
@model Yavsc.ViewModels.Blog.BlogPostInputViewModel
@{
ViewData["Title"] = "Blog post edition";
}
@section header {
<link href="~/css/main/dropzone.css" rel="stylesheet">
<script src="~/js/dropzone.js"></script>
@{ await Html.RenderPartialAsync("_FSScriptsPartial"); }
}
<h2>Blog post</h2>
<label><input type="checkbox" id="vcbtn" />Editer le code source Markdown</label>
<div asp-validation-summary="All" class="text-danger"></div>
<img class="blogphoto" alt="" src="@Model.Photo" title="Photo associée au post">
<h2 title="Titre du post" class="blogtitle" id="titleview" >@Model.Title</h2>
<div title="Contenu du post" id="contentview">@Model.Content</div>
<hr>
<form asp-controller="Blogspot" asp-action="Create">
<div class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group mdcoding">
<label asp-for="Title" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Title" class="form-control" data-from="titleview"/>
<span asp-validation-for="Title" class="text-danger" >
</span>
</div>
</div>
<div class="form-group">
<label asp-for="Photo" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Photo" class="form-control" />
<span asp-validation-for="Photo" class="text-danger" >
</span>
</div>
</div>
<div class="form-group mdcoding">
<label asp-for="Content" class="col-md-2 control-label" ></label>
<div class="col-md-10">
<textarea asp-for="Content" class="form-control" id="Content" data-from="contentview">
</textarea>
<span asp-validation-for="Content" class="text-danger" >
</span>
</div>
</div>
<div class="form-group">
<label asp-for="Visible" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Visible" class="form-control"/>
</div>
</div>
<div class="form-group">
<label asp-for="ACL" class="col-md-2 control-label"></label>
<div class="col-md-10">
@await Component.InvokeAsync("CirclesControl", Model)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-primary" >Save</button>
</div>
</div>
</div>
</form>
@await Component.InvokeAsync("Directory","")
<div >
@{ await Html.RenderPartialAsync("_PostFilesPartial"); }
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>

View File

@ -112,7 +112,7 @@ $('span.field-validation-valid[data-valmsg-for="Content"]').html(
} }
</div> </div>
@if ((await AuthorizationService.AuthorizeAsync(User, Model, new EditRequirement())).Succeeded) { @if ((await AuthorizationService.AuthorizeAsync(User, Model, new EditPermission())).Succeeded) {
<a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-link">Edit</a> <a asp-action="Edit" asp-route-id="@Model.Id" class="btn btn-link">Edit</a>
} }
<a asp-action="Index" class="btn btn-link">Back to List</a> <a asp-action="Index" class="btn btn-link">Back to List</a>

View File

@ -1,4 +1,4 @@
@model BlogPost @model Yavsc.ViewModels.Blog.BlogPostInputViewModel
@{ @{
ViewData["Title"] = "Blog post edition"; ViewData["Title"] = "Blog post edition";
@ -6,7 +6,6 @@
@section header { @section header {
<link href="~/css/main/quill.snow.css" rel="stylesheet">
<link href="~/css/main/dropzone.css" rel="stylesheet"> <link href="~/css/main/dropzone.css" rel="stylesheet">
<style> <style>
@ -34,90 +33,12 @@
</style> </style>
<script src="~/js/dropzone.js"></script> <script src="~/js/dropzone.js"></script>
<script src="~/js/quill.js"></script>
<script src="~/js/to-markdown.js"></script>
@{ await Html.RenderPartialAsync("_FSScriptsPartial"); } @{ await Html.RenderPartialAsync("_FSScriptsPartial"); }
} }
@section scripts {
<script src="~/js/showdown.js" asp-append-version="true"></script>
<script src="~/js/md-helpers.js" asp-append-version="true"></script>
<script>
$(document).ready(function() {
if (typeof(allowCircleToBlog) !== 'undefined') {
$('input.Blogcirle[type=checkbox]').on('change', allowCircleToBlog);
}
$(".mdcoding").addClass('hidden');
$("#contentview").on('drop', function(){drop(event);});
$("#contentview").on('dragover', function(){allowDrop(event);});
var onchange = function(){
var nv = $(this).val();
var tid = $(this).data('from');
$('#'+tid).html(htmlize(nv));
};
$("#Content").change(onchange);
$("#Title").change(onchange);
$('#vcbtn').change(function(){
var vc = $(this).prop('checked');
if (vc) {
$("#contentview").addClass('hidden');
$("#titleview").addClass('hidden');
$(".mdcoding").removeClass('hidden');
} else {
$("#contentview").removeClass('hidden');
$("#titleview").removeClass('hidden');
$(".mdcoding").addClass('hidden');
}
});
var initQuill = function() {
var editortitre = new Quill('#titleview', {
modules: { toolbar: '#Titletoolbar' },
theme: 'snow'
});
var editorcontenu = new Quill('#contentview', {
modules: { toolbar: '#contentbar' },
theme: 'snow'
});
editortitre.on('selection-change', function(range) {
if (range) {
$('#contentbar').addClass('hidden');
$('#Titletoolbar').removeClass('hidden');
}
});
editortitre.on('text-change',function(delta,source){
if (source=='user')
{
updateMD('Title',$('#ql-editor-1').html())
}
});
editorcontenu.on('selection-change', function(range) {
if (range) {
$('#contentbar').removeClass('hidden');
$('#Titletoolbar').addClass('hidden');
}
});
editorcontenu.on('text-change',function(delta,source){
if (source=='user')
{
updateMD('Content',$('#ql-editor-2').html())
}
});
};
initQuill();
});
</script>
@Html.Partial("_ValidationScriptsPartial")
}
<h2 > Blog post edition </h2> <h2 > Blog post edition </h2>
<label><input type="checkbox" id="vcbtn" />Editer le code source Markdown</label> <label><input type="checkbox" id="vcbtn" />Editer le code source Markdown</label>
@ -131,46 +52,16 @@
</div> </div>
<img class="blogphoto" alt="" src="@Model.Photo" title="Photo associée au post"> <img class="blogphoto" alt="" src="@Model.Photo" title="Photo associée au post">
<h2 title="Titre du post" class="blogtitle" id="titleview" ismarkdown>@Model.Title</h2> <h2 title="Titre du post" class="blogtitle" id="titleview" >@Model.Title</h2>
<div id="contentbar" class="hidden ql-snow ql-toolbar">
<span class="ql-format-group">
<button class="ql-format-button ql-bold"></button>
<button class="ql-format-button ql-italic"></button>
<button class="ql-format-button ql-underline"></button>
<button class="ql-format-button ql-strike"></button>
<environment names="Development">
<button class="ql-format-button ql-link"></button>
<button class="ql-format-button ql-image"></button>
<button class="ql-format-button ql-video"></button>
<button class="ql-format-button ql-file"></button>
</environment>
</span>
<span class="ql-format-group">
<span title="List" class="ql-format-button ql-list"></span>
<span class="ql-format-separator"></span>
<span title="Bullet" class="ql-format-button ql-bullet"></span>
<span class="ql-format-separator"></span>
<select title="Text Alignment" class="ql-align">
<option value="left" label="Left" selected=""></option>
<option value="center" label="Center"></option>
<option value="right" label="Right"></option>
<option value="justify" label="Justify"></option>
</select>
</span>
</div>
<div title="Contenu du post" id="contentview" markdown="@Model.Content"></div> <div title="Contenu du post" id="contentview">@Model.Content</div>
<hr> <hr>
<form asp-action="@ViewData["PostTarget"]"> <form>
<div class="form-horizontal"> <div class="form-horizontal">
<hr />
<p class="text-success">@ViewData["StatusMessage"]</p>
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<input type="hidden" asp-for="AuthorId" />
<div class="form-group mdcoding"> <div class="form-group mdcoding">
@ -182,17 +73,6 @@
</div> </div>
</div> </div>
<div class="form-group">
<label asp-for="Lang" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="Lang" class="form-control" asp-items="@ViewBag.LangItems" >
</select>
<span asp-validation-for="Lang" class="text-danger" >
</span>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label asp-for="Photo" class="col-md-2 control-label"></label> <label asp-for="Photo" class="col-md-2 control-label"></label>
<div class="col-md-10"> <div class="col-md-10">
@ -230,9 +110,6 @@
</div> </div>
</div> </div>
</form> </form>
<div>
</div>
@await Component.InvokeAsync("Directory","") @await Component.InvokeAsync("Directory","")
<div > <div >
@{ await Html.RenderPartialAsync("_PostFilesPartial"); } @{ await Html.RenderPartialAsync("_PostFilesPartial"); }

View File

@ -46,7 +46,7 @@
<a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a> <a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a>
</li> </li>
} }
@if ((await AuthorizationService.AuthorizeAsync(User, item, new EditRequirement())).Succeeded) { @if ((await AuthorizationService.AuthorizeAsync(User, item, new EditPermission())).Succeeded) {
<li><a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-default">Edit</a> <li><a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-default">Edit</a>
</li> </li>
<li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a> <li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a>

View File

@ -49,7 +49,7 @@
<a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a> <a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a>
</li> </li>
} }
@if ((await AuthorizationService.AuthorizeAsync(User, item, new EditRequirement())).Succeeded) { @if ((await AuthorizationService.AuthorizeAsync(User, item, new EditPermission())).Succeeded) {
<li><a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-default">Edit</a> <li><a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-default">Edit</a>
</li> </li>
<li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a> <li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a>

View File

@ -1,6 +1,6 @@
@model CirclesViewModel @model CirclesViewModel
@if (ViewBag.Access!=null)
@foreach (var cb in ViewBag.Access) {  foreach (var cb in ViewBag.Access) {
<label><input type="checkbox" class="@(Model.TargetTypeName)cirle" checked="@cb.Checked" value="@cb.Text" <label><input type="checkbox" class="@(Model.TargetTypeName)cirle" checked="@cb.Checked" value="@cb.Text"
data-target-id="@Model.Target.Id" data-circle-id="@cb.Value" data-targe-type=""> data-target-id="@Model.Target.Id" data-circle-id="@cb.Value" data-targe-type="">
@cb.Text </label> @cb.Text </label>

View File

@ -6,7 +6,7 @@
<h1 class="text-danger">Error.</h1> <h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2> <h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId) @if (Model!=null) if (Model.ShowRequestId)
{ {
<p> <p>
<strong>Request ID:</strong> <code>@Model.RequestId</code> <strong>Request ID:</strong> <code>@Model.RequestId</code>

View File

@ -10,8 +10,7 @@
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-append-version="true"/> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-append-version="true"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<!-- #region jQuery Slim <!-- #region jQuery Slim
<script src="~/lib/jquery/dist/jquery.slim.min.js"></script> <script src="~/lib/jquery/dist/jquery.slim.min.js"></script> -->
-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
@await RenderSectionAsync("header", false) @await RenderSectionAsync("header", false)
</head> </head>

View File

@ -46,7 +46,9 @@
Manage your account Manage your account
</a> </a>
</li> </li>
<li><a class="dropdown-item" asp-controller="Grants" asp-action="Index">Your Grants</a></li> <li><a class="dropdown-item" asp-controller="Grants" asp-action="Index">Grants</a></li>
<li><a class="dropdown-item" asp-controller="Device" asp-action="Index">Device</a></li>
<li><a class="dropdown-item" asp-controller="Diagnostics" asp-action="Index">Diagnostics</a></li>
<li><a class="dropdown-item" asp-controller="Account" asp-action="Logout">Logout</a></li> <li><a class="dropdown-item" asp-controller="Account" asp-action="Logout">Logout</a></li>
</ul> </ul>
</li> </li>

View File

@ -5,7 +5,7 @@
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbar" aria-controls="navbar" data-bs-target="#navbar" aria-controls="navbar"
aria-expanded="false" aria-label="Toggle navigation"> aria-expanded="true" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>

View File

@ -14,21 +14,13 @@
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); }
/* bootstrap.css | http://localhost:5000/lib/bootstrap/css/bootstrap.css */ /* bootstrap.css | http://localhost:5000/lib/bootstrap/css/bootstrap.css */
.nav-link {
/* background-color: var(--bs-nav-tabs-link-active-bg); */
background-color: black; }
.dropdown-item {
/* background-color: transparent; */
background-color: black; }
.dropdown-menu {
/* background-color: var(--bs-dropdown-bg); */
background-color: black; }
div.carousel-inner > div.item > div.carousel-caption-s { div.carousel-inner > div.item > div.carousel-caption-s {
margin: .5em; margin: .5em;
background-color: rgba(0, 0, 0, 0.6); background-color: rgba(0, 0, 0, 0.6);
color: #ffffc8; color: #ffffc8;
font-weight: bold; font-weight: bold;
padding: .5em; } padding: .5em; }
img.blogphoto {
max-width: 100%;
max-height: 100%; }

View File

@ -26,20 +26,6 @@
/* bootstrap.css | http://localhost:5000/lib/bootstrap/css/bootstrap.css */ /* bootstrap.css | http://localhost:5000/lib/bootstrap/css/bootstrap.css */
.nav-link {
/* background-color: var(--bs-nav-tabs-link-active-bg); */
background-color: black;
}
.dropdown-item {
/* background-color: transparent; */
background-color: black;
}
.dropdown-menu {
/* background-color: var(--bs-dropdown-bg); */
background-color: black;
}
div.carousel-inner > div.item > div.carousel-caption-s { div.carousel-inner > div.item > div.carousel-caption-s {
margin: .5em; margin: .5em;
@ -48,3 +34,8 @@ div.carousel-inner > div.item > div.carousel-caption-s {
font-weight: bold; font-weight: bold;
padding: .5em; padding: .5em;
} }
img.blogphoto {
max-width: 100%;
max-height: 100%;
}

View File

@ -615,14 +615,14 @@ namespace yavscTests
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "google-secret.json"); Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "google-secret.json");
/* TODO
ConfigureFileServerApp(app, SiteSetup, env, authorizationService); ConfigureFileServerApp(app, SiteSetup, env, authorizationService);
app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"en-US")); app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"en-US"));
ConfigureWorkflow(); ConfigureWorkflow();
*/
app.UseMvc(routes => app.UseMvc(routes =>
{ {