Ver código fonte

Added link to anonymous

master
radivoje.milutinovic 3 anos atrás
pai
commit
157727d587

+ 1
- 0
SecureSharing.Business/Dtos/MessageDto.cs Ver arquivo

@@ -9,4 +9,5 @@ public sealed class MessageDto : BaseDto
public Guid Code { get; set; } = Guid.NewGuid();
public List<FileModel> FileNames { get; set; } = new();
public DateTime? ExpiryDate { get; set; }
public bool Anonymous { get; set; } = false;
}

+ 1
- 0
SecureSharing.Data/Data/Message.cs Ver arquivo

@@ -7,4 +7,5 @@ public sealed class Message : BaseEntity
public List<FileModel> FileNames { get; } = new();
public bool IsValid { get; set; }
public DateTime? ExpiryDate { get; set; }
public bool Anonymous { get; set; } = false;
}

+ 345
- 0
SecureSharing.Data/Migrations/20221020114243_Adding nonyomus links.Designer.cs Ver arquivo

@@ -0,0 +1,345 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SecureSharing.Data.DbContexts;

#nullable disable

namespace SecureSharing.Data.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20221020114243_Adding nonyomus links")]
partial class Addingnonyomuslinks
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 128);

SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");

b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");

b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.HasKey("Id");

b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");

b.ToTable("AspNetRoles", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");

SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");

b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");

b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");

b.HasKey("Id");

b.HasIndex("RoleId");

b.ToTable("AspNetRoleClaims", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");

b.Property<int>("AccessFailedCount")
.HasColumnType("int");

b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");

b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");

b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");

b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");

b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");

b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");

b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");

b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");

b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");

b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");

b.HasKey("Id");

b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");

b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");

b.ToTable("AspNetUsers", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");

SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");

b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");

b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");

b.HasKey("Id");

b.HasIndex("UserId");

b.ToTable("AspNetUserClaims", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");

b.Property<string>("ProviderKey")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");

b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");

b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");

b.HasKey("LoginProvider", "ProviderKey");

b.HasIndex("UserId");

b.ToTable("AspNetUserLogins", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");

b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");

b.HasKey("UserId", "RoleId");

b.HasIndex("RoleId");

b.ToTable("AspNetUserRoles", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");

b.Property<string>("LoginProvider")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");

b.Property<string>("Name")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");

b.Property<string>("Value")
.HasColumnType("nvarchar(max)");

b.HasKey("UserId", "LoginProvider", "Name");

b.ToTable("AspNetUserTokens", (string)null);
});

modelBuilder.Entity("SecureSharing.Data.Data.FileModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");

SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

b.Property<int>("MessageId")
.HasColumnType("int");

b.Property<string>("Name")
.HasColumnType("nvarchar(max)");

b.HasKey("Id");

b.HasIndex("MessageId");

b.ToTable("FileModel");
});

modelBuilder.Entity("SecureSharing.Data.Data.Message", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");

SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

b.Property<bool>("Anonymous")
.HasColumnType("bit");

b.Property<string>("Code")
.HasColumnType("nvarchar(max)");

b.Property<DateTime?>("ExpiryDate")
.HasColumnType("datetime2");

b.Property<bool>("IsValid")
.HasColumnType("bit");

b.Property<string>("Text")
.HasColumnType("nvarchar(max)");

b.HasKey("Id");

b.ToTable("Messages");
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("SecureSharing.Data.Data.FileModel", b =>
{
b.HasOne("SecureSharing.Data.Data.Message", null)
.WithMany("FileNames")
.HasForeignKey("MessageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});

modelBuilder.Entity("SecureSharing.Data.Data.Message", b =>
{
b.Navigation("FileNames");
});
#pragma warning restore 612, 618
}
}
}

+ 26
- 0
SecureSharing.Data/Migrations/20221020114243_Adding nonyomus links.cs Ver arquivo

@@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace SecureSharing.Data.Migrations
{
public partial class Addingnonyomuslinks : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Anonymous",
table: "Messages",
type: "bit",
nullable: false,
defaultValue: false);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Anonymous",
table: "Messages");
}
}
}

+ 3
- 0
SecureSharing.Data/Migrations/AppDbContextModelSnapshot.cs Ver arquivo

@@ -253,6 +253,9 @@ namespace SecureSharing.Data.Migrations

SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

b.Property<bool>("Anonymous")
.HasColumnType("bit");

b.Property<string>("Code")
.HasColumnType("nvarchar(max)");


+ 16
- 5
SecureSharing/Controllers/HomeController.cs Ver arquivo

@@ -56,18 +56,20 @@ public sealed class HomeController : Controller
[HttpPost]
public async Task<IActionResult> CreateMessage(MessageModel model)
{
if (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 && model.FilesAsText == "978682e8-3ce7-4258-b731-d027b5b213aa")
if (string.IsNullOrWhiteSpace(model.Text) && model.Files.Count == 0 &&
model.FilesAsText == "978682e8-3ce7-4258-b731-d027b5b213aa")
return Redirect("/");

model.FilesAsText = model.FilesAsText != "978682e8-3ce7-4258-b731-d027b5b213aa"
? model.FilesAsText.Split("978682e8-3ce7-4258-b731-d027b5b213aa")[1]
model.FilesAsText = model.FilesAsText != "978682e8-3ce7-4258-b731-d027b5b213aa"
? model.FilesAsText.Split("978682e8-3ce7-4258-b731-d027b5b213aa")[1]
: "";
var message = new MessageDto { Text = model.Text };
var message = new MessageDto { Text = model.Text, Anonymous = model.Anonymous };

await UploadFiles(model, message);

var code = await _messageService.Create(message, model.ChosenPeriod);

return RedirectToAction("Link", "Home", new { code, share = true });
}

@@ -123,6 +125,7 @@ public sealed class HomeController : Controller
}
}

[AllowAnonymous]
public async Task<FileStreamResult> Download(string filename, Guid code)
{
var path = Path.Combine(_webHostEnvironment.WebRootPath.Split('/')[0], DefaultPath, code.ToString(), filename);
@@ -141,6 +144,14 @@ public sealed class HomeController : Controller
return View(model);
}

[AllowAnonymous]
[HttpGet]
public async Task<IActionResult> LinkAnonymous(Guid code, bool? share)
{
var model = await _modelFactory.PrepareLinkAnonymous(code, share);
return View(model);
}

public IActionResult Privacy()
{
return View();

+ 1
- 0
SecureSharing/Infrastructure/IModelFactory.cs Ver arquivo

@@ -6,4 +6,5 @@ public interface IModelFactory
{
//public MessageModel PrepareMessageVM(MessageDto message);
public Task<LinkModel> PrepareLinkVM(Guid code, bool? share);
public Task<LinkModel> PrepareLinkAnonymous(Guid code, bool? share);
}

+ 9
- 1
SecureSharing/Infrastructure/ModelFactory.cs Ver arquivo

@@ -29,7 +29,8 @@ public sealed class ModelFactory : IModelFactory
{
Code = code,
Text = message.Text,
FileNames = message.FileNames.Select(x => x.Name).ToList()
FileNames = message.FileNames.Select(x => x.Name).ToList(),
Anonymous = message.Anonymous
},
Share = share,
IsValid = message.IsValid
@@ -66,6 +67,13 @@ public sealed class ModelFactory : IModelFactory
return model;
}

public async Task<LinkModel> PrepareLinkAnonymous(Guid code, bool? share)
{
var model = await PrepareLinkVM(code, share);

return model.MessageModel.Anonymous ? model : new LinkModel { IsValid = false };
}

//public MessageModel PrepareMessageVM(MessageDto message)
//{
// throw new System.NotImplementedException();

+ 2
- 0
SecureSharing/Models/MessageModel.cs Ver arquivo

@@ -12,5 +12,7 @@ public sealed class MessageModel
public List<string> FileNames { get; init; } = new();

public string FilesAsText { get; set; } = default!;

public bool Anonymous { get; set; } = false;
// public Dictionary<int, string> AvailablePeriods { get; set; }
}

+ 11
- 1
SecureSharing/Views/Home/Index.cshtml Ver arquivo

@@ -41,7 +41,7 @@
</div>
</div>
</div>
<div class="mb-3">
<div class="label-text">
Your files
@@ -50,6 +50,16 @@
</div>
</div>

<div class="mb-3">
<label class="label-text">Should link be visible outside diligent network?</label>
<div class="button-box row">
<div class="single-button-input col-4">
<input id="Anonymous" class="radio-input" type="radio" asp-for="Anonymous" value="true">
<label for="Anonymous" class="label-available">Anonymous share</label>
</div>
</div>
</div>
<button class=" btn btn-light share-button" type="submit">Share</button>
</form>


+ 1
- 1
SecureSharing/Views/Home/Link.cshtml Ver arquivo

@@ -20,7 +20,7 @@ else
</div>
<div id="div-link" class="label-text link-show">
@{
var link = Url.Action("Link", "Home", new { code = Model.MessageModel.Code }, "https");
var link = Url.Action(Model.MessageModel.Anonymous ? "LinkAnonymous" : "Link", "Home", new { code = Model.MessageModel.Code }, "https");
}
<a id="a-link" href="@link">@link</a>
</div>

+ 76
- 0
SecureSharing/Views/Home/LinkAnonymous.cshtml Ver arquivo

@@ -0,0 +1,76 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@model LinkModel

@if (!Model.IsValid)
{
<h1>Document expired!</h1>
<a class="btn btn-light share-button" asp-controller="Home" asp-action="Index">Share message securely!</a>
}
else
{
<h1>Document is ready!</h1>
<a href="/" class="share-more-files-button">Share more files</a>


<div>
@if (Model.TimeLeft != null)
{
var time = Model.TimeLeft.Value;
if (time.Days > 0)
{
<div class="label-text-lower">
This message will expire in: @time.ToString("%d") days @time.ToString("%h") hours @time.ToString("%m") minutes
</div>
}
else
{
<div class="label-text-lower">
This message will expire in: @time.ToString(@"hh\:mm\:ss")
</div>
}
}
else
{
<div class="label-text-lower">
This message will expire when you leave this page
</div>
}
</div>

@if (!string.IsNullOrWhiteSpace(Model.MessageModel.Text))
{
<div class="label-text">
Message:
</div>
<div class="label-text link-show">
@Model.MessageModel.Text
</div>
}
@if (Model.MessageModel.FileNames.Count > 0)
{
<div class="label-text">
Files:
</div>
<div class="label-text link-show">
@foreach (var file in Model.MessageModel.FileNames)
{
<a asp-action="Download" asp-route-filename="@file" asp-route-code="@Model.MessageModel.Code">@file</a>
<br/>
}
</div>
}

<a class="btn btn-light share-button" asp-controller="Home" asp-action="Index">Share new message securely!</a>
}

<script>
copyToClipboard = () => {
// Get the text field
const copyText = document.getElementById("a-link").innerText;
// Copy the text inside the text field
navigator.clipboard.writeText(copyText);
}
</script>

Carregando…
Cancelar
Salvar