bug fixes
This commit is contained in:
@ -10,29 +10,19 @@ using Yavsc.Attributes.Validation;
|
||||
using Yavsc.Interfaces;
|
||||
using Yavsc.Models.Access;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.ViewModels.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)]
|
||||
[Display(Name="Identifiant du post")]
|
||||
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é")]
|
||||
public int Rate { get; set; }
|
||||
|
||||
[Display(Name="Titre")][YaStringLength(1024)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Display(Name="Identifiant de l'auteur")]
|
||||
[ForeignKey("Author")]
|
||||
@ -41,8 +31,6 @@ namespace Yavsc.Models.Blog
|
||||
[Display(Name="Auteur")]
|
||||
public virtual ApplicationUser Author { set; get; }
|
||||
|
||||
[Display(Name="Visible")]
|
||||
public bool Visible { get; set; }
|
||||
|
||||
[Display(Name="Date de création")]
|
||||
public DateTime DateCreated
|
||||
@ -68,10 +56,6 @@ namespace Yavsc.Models.Blog
|
||||
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)
|
||||
{
|
||||
return ACL?.Any( i=>i.CircleId == circleId) ?? true;
|
||||
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
26
src/Yavsc.Server/ViewModels/BlogPostInputViewModel.cs
Normal file
26
src/Yavsc.Server/ViewModels/BlogPostInputViewModel.cs
Normal 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; }
|
||||
|
||||
}
|
||||
}
|
@ -7,7 +7,8 @@ namespace Yavsc.ViewModels.Relationship
|
||||
public CirclesViewModel(ICircleAuthorized resource)
|
||||
{
|
||||
Target = resource;
|
||||
TargetTypeName = resource.GetType().Name;
|
||||
if (resource!=null)
|
||||
TargetTypeName = resource.GetType().Name;
|
||||
}
|
||||
public ICircleAuthorized Target { get; set; }
|
||||
public string TargetTypeName { get; set; }
|
||||
|
@ -65,7 +65,7 @@ namespace Yavsc.ApiControllers
|
||||
}
|
||||
_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(
|
||||
u => u.Id == uid
|
||||
);
|
||||
|
@ -235,9 +235,16 @@ namespace Yavsc.Controllers
|
||||
/// <summary>
|
||||
/// Show logout page
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[HttpGet][Authorize]
|
||||
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
|
||||
var vm = await BuildLogoutViewModelAsync(logoutId);
|
||||
|
||||
@ -265,9 +272,11 @@ namespace Yavsc.Controllers
|
||||
{
|
||||
// delete local authentication cookie
|
||||
await HttpContext.SignOutAsync();
|
||||
await _signInManager.SignOutAsync();
|
||||
|
||||
// raise the logout event
|
||||
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
|
||||
|
||||
}
|
||||
|
||||
// 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 View("LoggedOut", vm);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace Yavsc.Controllers
|
||||
{
|
||||
ViewBag.IsAdmin = User.IsInRole(Constants.AdminGroupName);
|
||||
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>();
|
||||
var rnames = System.Enum.GetNames(typeof(Reason));
|
||||
var rvalues = System.Enum.GetValues(typeof(Reason));
|
||||
|
@ -14,6 +14,8 @@ using Yavsc.Helpers;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
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
|
||||
|
||||
@ -111,30 +113,35 @@ namespace Yavsc.Controllers
|
||||
[Authorize()]
|
||||
public IActionResult Create(string title)
|
||||
{
|
||||
var result = new BlogPost{Title=title};
|
||||
var result = new BlogPostInputViewModel{Title=title,Content=""};
|
||||
ViewData["PostTarget"]="Create";
|
||||
SetLangItems();
|
||||
return View("Edit",result);
|
||||
return View(result);
|
||||
}
|
||||
|
||||
// POST: Blog/Create
|
||||
[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)
|
||||
{
|
||||
|
||||
_context.Blogspot.Add(blog);
|
||||
BlogPost post = new BlogPost
|
||||
{
|
||||
Title = blogInput.Title,
|
||||
Content = blogInput.Content,
|
||||
Photo = blogInput.Photo,
|
||||
Rate = 0,
|
||||
AuthorId = User.GetUserId()
|
||||
};
|
||||
_context.Blogspot.Add(post);
|
||||
_context.SaveChanges(User.GetUserId());
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
ModelState.AddModelError("Unknown","Invalid Blog posted ...");
|
||||
ViewData["PostTarget"]="Create";
|
||||
return View("Edit",blog);
|
||||
return View("Edit",blogInput);
|
||||
}
|
||||
|
||||
[Authorize()]
|
||||
// GET: Blog/Edit/5
|
||||
public async Task<IActionResult> Edit(long? id)
|
||||
@ -147,12 +154,11 @@ namespace Yavsc.Controllers
|
||||
ViewData["PostTarget"]="Edit";
|
||||
BlogPost blog = _context.Blogspot.Include(x => x.Author).Include(x => x.ACL).Single(m => m.Id == id);
|
||||
|
||||
|
||||
if (blog == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
if (!_authorizationService.AuthorizeAsync(User, blog, new EditRequirement()).IsFaulted)
|
||||
if (!_authorizationService.AuthorizeAsync(User, blog, new EditPermission()).IsFaulted)
|
||||
{
|
||||
ViewBag.ACL = _context.Circle.Where(
|
||||
c=>c.OwnerId == blog.AuthorId)
|
||||
@ -180,7 +186,7 @@ namespace Yavsc.Controllers
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var auth = _authorizationService.AuthorizeAsync(User, blog, new EditRequirement());
|
||||
var auth = _authorizationService.AuthorizeAsync(User, blog, new EditPermission());
|
||||
if (!auth.IsFaulted)
|
||||
{
|
||||
// saves the change
|
||||
|
@ -29,6 +29,7 @@ using Yavsc.Models.Market;
|
||||
using Yavsc.Models.Workflow;
|
||||
using Yavsc.Services;
|
||||
using Yavsc.Settings;
|
||||
using Yavsc.ViewModels.Auth;
|
||||
|
||||
namespace Yavsc.Extensions;
|
||||
|
||||
@ -308,7 +309,12 @@ internal static class HostingExtensions
|
||||
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
||||
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
|
||||
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
||||
options.AddPolicy("IsTheAuthor", policy =>
|
||||
policy.Requirements.Add(new EditPermission()));
|
||||
});
|
||||
|
||||
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
|
||||
|
||||
_ = services.AddControllersWithViews()
|
||||
.AddNewtonsoftJson();
|
||||
LoadGoogleConfig(builder.Configuration);
|
||||
|
46
src/Yavsc/Extensions/PermissionHandler.cs
Normal file
46
src/Yavsc/Extensions/PermissionHandler.cs
Normal 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;
|
||||
}
|
||||
}
|
@ -117,7 +117,18 @@ namespace Yavsc.Helpers
|
||||
InternalAnchor a = (InternalAnchor) elt;
|
||||
sb.AppendFormat("<a name=\"{0}\">{1}</a> ", a.Id, a.XRefLabel);
|
||||
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:
|
||||
string unsupportedType = elt.GetType().FullName;
|
||||
throw new InvalidProgramException(unsupportedType);
|
||||
|
@ -35,7 +35,6 @@ namespace Yavsc.Models
|
||||
using Calendar;
|
||||
using Blog;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Server.Models.Blog;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
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<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
|
||||
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 });
|
||||
|
||||
foreach (var et in builder.Model.GetEntityTypes())
|
||||
@ -291,8 +289,6 @@ namespace Yavsc.Models
|
||||
|
||||
public DbSet<Project> Project { get; set; }
|
||||
|
||||
public DbSet<BlogTrad> BlogTrad { get; set; }
|
||||
|
||||
[Obsolete("use signaled flows")]
|
||||
public DbSet<LiveFlow> LiveFlow { get; set; }
|
||||
|
||||
|
@ -20,6 +20,8 @@ namespace Yavsc.ViewComponents
|
||||
|
||||
public IViewComponentResult Invoke (ICircleAuthorized target)
|
||||
{
|
||||
if (target!=null)
|
||||
{
|
||||
var oid = target.GetOwnerId();
|
||||
ViewBag.ACL = dbContext.Circle.Where(
|
||||
c=>c.OwnerId == oid)
|
||||
@ -41,6 +43,8 @@ namespace Yavsc.ViewComponents
|
||||
Checked = target.AuthorizeCircle(c.Id),
|
||||
Value = c.Id.ToString()
|
||||
});
|
||||
}
|
||||
|
||||
return View(new CirclesViewModel(target));
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,25 @@ using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
85
src/Yavsc/Views/Blogspot/Create.cshtml
Normal file
85
src/Yavsc/Views/Blogspot/Create.cshtml
Normal 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>
|
@ -112,7 +112,7 @@ $('span.field-validation-valid[data-valmsg-for="Content"]').html(
|
||||
}
|
||||
|
||||
</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="Index" class="btn btn-link">Back to List</a>
|
||||
|
@ -1,4 +1,4 @@
|
||||
@model BlogPost
|
||||
@model Yavsc.ViewModels.Blog.BlogPostInputViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Blog post edition";
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
@section header {
|
||||
|
||||
<link href="~/css/main/quill.snow.css" rel="stylesheet">
|
||||
<link href="~/css/main/dropzone.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
@ -34,90 +33,12 @@
|
||||
|
||||
</style>
|
||||
<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>
|
||||
<label><input type="checkbox" id="vcbtn" />Editer le code source Markdown</label>
|
||||
|
||||
@ -131,47 +52,17 @@
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<form asp-action="@ViewData["PostTarget"]">
|
||||
<form>
|
||||
<div class="form-horizontal">
|
||||
|
||||
<hr />
|
||||
<p class="text-success">@ViewData["StatusMessage"]</p>
|
||||
<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">
|
||||
<label asp-for="Title" class="col-md-2 control-label"></label>
|
||||
@ -182,17 +73,6 @@
|
||||
</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">
|
||||
<label asp-for="Photo" class="col-md-2 control-label"></label>
|
||||
<div class="col-md-10">
|
||||
@ -230,9 +110,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
@await Component.InvokeAsync("Directory","")
|
||||
<div >
|
||||
@{ await Html.RenderPartialAsync("_PostFilesPartial"); }
|
||||
|
@ -46,7 +46,7 @@
|
||||
<a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a>
|
||||
</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>
|
||||
<li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<a asp-action="Details" asp-route-id="@item.Id" class="btn btn-lg">Details</a>
|
||||
</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>
|
||||
<li><a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a>
|
||||
|
@ -1,6 +1,6 @@
|
||||
@model CirclesViewModel
|
||||
|
||||
@foreach (var cb in ViewBag.Access) {
|
||||
@if (ViewBag.Access!=null)
|
||||
foreach (var cb in ViewBag.Access) {
|
||||
<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="">
|
||||
@cb.Text </label>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
@if (Model!=null) if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
|
@ -10,8 +10,7 @@
|
||||
<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"/>
|
||||
<!-- #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>
|
||||
@await RenderSectionAsync("header", false)
|
||||
</head>
|
||||
|
@ -46,7 +46,9 @@
|
||||
Manage your account
|
||||
</a>
|
||||
</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>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
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>
|
||||
</button>
|
||||
|
||||
|
Binary file not shown.
@ -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"); }
|
||||
|
||||
/* 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 {
|
||||
margin: .5em;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #ffffc8;
|
||||
font-weight: bold;
|
||||
padding: .5em; }
|
||||
|
||||
img.blogphoto {
|
||||
max-width: 100%;
|
||||
max-height: 100%; }
|
||||
|
@ -26,20 +26,6 @@
|
||||
|
||||
/* 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 {
|
||||
margin: .5em;
|
||||
@ -48,3 +34,8 @@ div.carousel-inner > div.item > div.carousel-caption-s {
|
||||
font-weight: bold;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
img.blogphoto {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
@ -615,14 +615,14 @@ namespace yavscTests
|
||||
|
||||
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "google-secret.json");
|
||||
|
||||
/* TODO
|
||||
|
||||
|
||||
ConfigureFileServerApp(app, SiteSetup, env, authorizationService);
|
||||
|
||||
app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"en-US"));
|
||||
|
||||
ConfigureWorkflow();
|
||||
*/
|
||||
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
|
Reference in New Issue
Block a user