Skip to content

Commit e987724

Browse files
committed
feat(asp): add
1 parent 0128fd6 commit e987724

9 files changed

Lines changed: 230 additions & 5 deletions

File tree

Lavcode.Asp/Controllers/FolderController.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ public async Task<IActionResult> GetFolders()
4040
public async Task<IActionResult> CreateFolder([FromBody] CreateFolderDto dto)
4141
{
4242
var order = await _databaseContext.Folders.OrderByDescending(f => f.Order).Select(f => f.Order).FirstOrDefaultAsync();
43+
var folderId = Guid.NewGuid().ToString();
4344
var newFolder = await _databaseContext.Folders.AddAsync(new FolderEntity()
4445
{
45-
Id = Guid.NewGuid().ToString(),
46+
Id = folderId,
4647
Icon = new IconEntity()
4748
{
4849
IconType = dto.Icon.IconType,
4950
Value = dto.Icon.Value,
50-
Id = Guid.NewGuid().ToString()
51+
Id = folderId,
5152
},
5253
Name = dto.Name,
5354
Order = order += 1,
@@ -83,7 +84,7 @@ public async Task<IActionResult> UpdateFolder([FromBody] UpdateFolderDto dto, [F
8384
}
8485
await _databaseContext.SaveChangesAsync();
8586

86-
var newFolder = await _databaseContext.Folders.Where(f => f.Id == folderId).Include(f => f.Icon).ToArrayAsync();
87+
var newFolder = await _databaseContext.Folders.Where(f => f.Id == folderId).Include(f => f.Icon).FirstOrDefaultAsync();
8788
return Ok(newFolder);
8889
}
8990

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
using Lavcode.Asp.Dtos;
2+
using Lavcode.Asp.Entities;
3+
using Microsoft.AspNetCore.Authorization;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
7+
namespace Lavcode.Asp.Controllers
8+
{
9+
[ApiController]
10+
[Route("password")]
11+
[Authorize]
12+
public class PasswordController : ControllerBase
13+
{
14+
private readonly DatabaseContext _databaseContext;
15+
public PasswordController(DatabaseContext databaseContext)
16+
{
17+
_databaseContext = databaseContext;
18+
}
19+
20+
/// <summary>
21+
/// Get passwords
22+
/// </summary>
23+
/// <param name="folderId"></param>
24+
/// <returns></returns>
25+
[HttpGet("")]
26+
public async Task<IActionResult> GetPasswords([FromQuery(Name = "folderId")] string folderId)
27+
{
28+
var folders = await _databaseContext.Passwords
29+
.Where(item => item.FolderId == folderId)
30+
.Include(p => p.Icon)
31+
.Include(p => p.KeyValuePairs)
32+
.OrderBy(p => p.Order)
33+
.ToArrayAsync();
34+
return Ok(folders);
35+
}
36+
37+
/// <summary>
38+
/// Create password
39+
/// </summary>
40+
/// <param name="dto"></param>
41+
/// <returns></returns>
42+
[HttpPost("")]
43+
public async Task<IActionResult> CreatePassword([FromBody] CreatePasswordDto dto)
44+
{
45+
var order = await _databaseContext.Passwords.OrderByDescending(p => p.Order).Select(p => p.Order).FirstOrDefaultAsync();
46+
var passwordId = Guid.NewGuid().ToString();
47+
var newPassword = await _databaseContext.Passwords.AddAsync(new PasswordEntity()
48+
{
49+
Id = Guid.NewGuid().ToString(),
50+
FolderId = dto.FolderId,
51+
KeyValuePairs = dto.KeyValuePairs.Select(kvp => new KeyValuePairEntity()
52+
{
53+
Id = Guid.NewGuid().ToString(),
54+
PasswordId = passwordId,
55+
Key = kvp.Key,
56+
Value = kvp.Value
57+
}).ToArray(),
58+
Icon = new IconEntity()
59+
{
60+
IconType = dto.Icon.IconType,
61+
Value = dto.Icon.Value,
62+
Id = passwordId,
63+
},
64+
Title = dto.Title,
65+
Remark = dto.Remark,
66+
Value = dto.Value,
67+
Order = order += 1,
68+
UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
69+
});
70+
await _databaseContext.SaveChangesAsync();
71+
72+
return Ok(newPassword.Entity);
73+
}
74+
75+
/// <summary>
76+
/// Update password
77+
/// </summary>
78+
/// <param name="dto"></param>
79+
/// <param name="passwordId"></param>
80+
/// <returns></returns>
81+
[HttpPut("{passwordId}")]
82+
public async Task<IActionResult> UpdatePassword([FromBody] UpdatePasswordDto dto, [FromRoute] string passwordId)
83+
{
84+
await _databaseContext.Passwords.Where(p => p.Id == passwordId).UpdateFromQueryAsync((p) => new PasswordEntity()
85+
{
86+
Title = dto.Title,
87+
Remark = dto.Remark,
88+
Value = dto.Value,
89+
Order = dto.Order,
90+
FolderId = dto.FolderId,
91+
UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
92+
});
93+
if (dto.Icon != null)
94+
{
95+
await _databaseContext.Icons.Where(icon => icon.Id == passwordId).UpdateFromQueryAsync(icon => new IconEntity()
96+
{
97+
IconType = dto.Icon.IconType,
98+
Value = dto.Icon.Value,
99+
});
100+
}
101+
if (dto.KeyValuePairs != null)
102+
{
103+
await _databaseContext.KeyValuePairs.Where(kvp => kvp.PasswordId == passwordId).DeleteFromQueryAsync();
104+
await _databaseContext.KeyValuePairs.AddRangeAsync(dto.KeyValuePairs.Select(kvp => new KeyValuePairEntity()
105+
{
106+
Id = Guid.NewGuid().ToString(),
107+
PasswordId = passwordId,
108+
Key = kvp.Key,
109+
Value = kvp.Value
110+
}).ToArray());
111+
}
112+
await _databaseContext.SaveChangesAsync();
113+
114+
var newFolder = await _databaseContext.Passwords
115+
.Where(p => p.Id == passwordId)
116+
.Include(p => p.Icon)
117+
.Include(p => p.KeyValuePairs)
118+
.FirstOrDefaultAsync();
119+
return Ok(newFolder);
120+
}
121+
122+
/// <summary>
123+
/// Delete a password
124+
/// </summary>
125+
/// <param name="passwordId"></param>
126+
/// <returns></returns>
127+
[HttpDelete("{passwordId}")]
128+
public async Task<IActionResult> DeletePassword([FromRoute] string passwordId)
129+
{
130+
await _databaseContext.KeyValuePairs
131+
.Where(kvp => kvp.PasswordId == passwordId)
132+
.DeleteFromQueryAsync();
133+
await _databaseContext.Icons
134+
.Where(kvp => kvp.Id == passwordId)
135+
.DeleteFromQueryAsync();
136+
await _databaseContext.Passwords.Where(p => p.Id == passwordId).DeleteFromQueryAsync();
137+
await _databaseContext.SaveChangesAsync();
138+
return NoContent();
139+
}
140+
}
141+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace Lavcode.Asp.Dtos
4+
{
5+
public class CreatePasswordDto
6+
{
7+
[Required]
8+
public string FolderId { get; set; } = null!;
9+
10+
public string? Title { get; set; }
11+
public string? Value { get; set; }
12+
public string? Remark { get; set; }
13+
14+
[Required]
15+
public UpsertIconDto Icon { get; set; } = null!;
16+
17+
[Required]
18+
public UpsertKeyValuePairDto[] KeyValuePairs { get; set; } = null!;
19+
}
20+
}

Lavcode.Asp/Dtos/UpdateFolderDto.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public class UpdateFolderDto
1313
/// <summary>
1414
/// 空则不修改图标
1515
/// </summary>
16-
[Required]
1716
public UpsertIconDto? Icon { get; set; }
1817
}
1918
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace Lavcode.Asp.Dtos
4+
{
5+
public class UpdatePasswordDto
6+
{
7+
[Required]
8+
public string FolderId { get; set; } = null!;
9+
10+
public string? Title { get; set; }
11+
public string? Value { get; set; }
12+
public string? Remark { get; set; }
13+
14+
[Required]
15+
public int Order { get; set; }
16+
17+
public UpsertIconDto? Icon { get; set; } = null!;
18+
public UpsertKeyValuePairDto[]? KeyValuePairs { get; set; }
19+
}
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace Lavcode.Asp.Dtos
4+
{
5+
public class UpsertKeyValuePairDto
6+
{
7+
[Required]
8+
public string Key { get; set; } = null!;
9+
[Required]
10+
public string Value { get; set; } = null!;
11+
}
12+
}

Lavcode.Asp/Entities/DatabaseContext.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Microsoft.EntityFrameworkCore;
2+
using static System.Net.Mime.MediaTypeNames;
23

34
namespace Lavcode.Asp.Entities
45
{
@@ -20,6 +21,22 @@ public DatabaseContext(DbContextOptions<DatabaseContext> options)
2021

2122
protected override void OnModelCreating(ModelBuilder modelBuilder)
2223
{
24+
modelBuilder.Entity<FolderEntity>(entity =>
25+
{
26+
entity.HasOne(d => d.Icon)
27+
.WithOne(p => p.Folder)
28+
.HasForeignKey<FolderEntity>(d => d.Id)
29+
.OnDelete(DeleteBehavior.ClientSetNull)
30+
.HasConstraintName("FK_Folder_Icon");
31+
});
32+
modelBuilder.Entity<PasswordEntity>(entity =>
33+
{
34+
entity.HasOne(d => d.Icon)
35+
.WithOne(p => p.Password)
36+
.HasForeignKey<PasswordEntity>(d => d.Id)
37+
.OnDelete(DeleteBehavior.ClientSetNull)
38+
.HasConstraintName("FK_Password_Icon");
39+
});
2340
base.OnModelCreating(modelBuilder);
2441
}
2542
}

Lavcode.Asp/Entities/IconEntity.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,8 @@ public class IconEntity
2121
/// </summary>
2222
[MaxLength(1024 * 1024 * 10)]
2323
public string Value { get; set; } = null!;
24+
25+
public virtual FolderEntity? Folder { get; set; }
26+
public virtual PasswordEntity? Password { get; set; }
2427
}
2528
}

Lavcode.Asp/Program.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Lavcode.Asp.Services;
55
using LogDashboard;
66
using Microsoft.AspNetCore.Authentication.JwtBearer;
7+
using Microsoft.AspNetCore.Mvc;
78
using Microsoft.EntityFrameworkCore;
89
using Microsoft.Extensions.DependencyInjection.Extensions;
910
using Microsoft.Extensions.Options;
@@ -33,6 +34,7 @@
3334
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
3435
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
3536
});
37+
builder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
3638

3739
// Swagger
3840
builder.Services.AddEndpointsApiExplorer();
@@ -91,7 +93,6 @@
9193
OnChallenge = async context =>
9294
{
9395
context.HandleResponse();
94-
context.Response.StatusCode = 401;
9596
await context.Response.WriteAsJsonAsync(new
9697
{
9798
message = "Çë×¢Ïú²¢ÖØÐµÇ¼"
@@ -142,6 +143,17 @@ await context.Response.WriteAsJsonAsync(new
142143
await next();
143144
});
144145

146+
// add Bearer
147+
app.Use(async (ctx, next) =>
148+
{
149+
var token = ctx.Request.Headers["Authorization"].FirstOrDefault();
150+
if (!string.IsNullOrEmpty(token) && !token.StartsWith("Bearer "))
151+
{
152+
ctx.Request.Headers["Authorization"] = new string[] { "Bearer " + token };
153+
}
154+
await next();
155+
});
156+
145157
if (app.Environment.IsDevelopment())
146158
{
147159
app.UseLogDashboard("/log");

0 commit comments

Comments
 (0)