Skip to content

Commit 084de56

Browse files
author
Daniel Medin
committed
change db
1 parent 2b3f1a8 commit 084de56

23 files changed

Lines changed: 457 additions & 226 deletions

.github/workflows/ci.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ on:
1212

1313
jobs:
1414
build:
15-
runs-on: ubuntu-latest
15+
name: Build (${{ matrix.os }})
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
os:
21+
- ubuntu-latest
22+
- windows-latest
23+
1624
steps:
1725
- name: Checkout
1826
uses: actions/checkout@v4

.github/workflows/deploy-azure-webapp.yml

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build-windows:
14+
name: Build Windows
15+
runs-on: windows-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: "20"
25+
cache: npm
26+
cache-dependency-path: BitStoreWeb/BitStoreWeb.Net9/package-lock.json
27+
28+
- name: Install frontend dependencies
29+
run: npm ci --prefix BitStoreWeb/BitStoreWeb.Net9
30+
31+
- name: Build frontend assets
32+
run: npm --prefix BitStoreWeb/BitStoreWeb.Net9 run build
33+
34+
- name: Setup .NET SDK
35+
uses: actions/setup-dotnet@v4
36+
with:
37+
dotnet-version: "9.0.x"
38+
39+
- name: Restore .NET dependencies
40+
run: dotnet restore BitStoreWeb/BitStoreWeb.Net9/BitStoreWeb.Net9.csproj
41+
42+
- name: Build .NET app
43+
run: dotnet build BitStoreWeb/BitStoreWeb.Net9/BitStoreWeb.Net9.csproj --configuration Release --no-restore
44+
45+
deploy:
46+
name: Deploy Linux
47+
runs-on: ubuntu-latest
48+
needs: build-windows
49+
env:
50+
SSH_SERVICE_NAME: ${{ secrets.SSH_SERVICE_NAME }}
51+
52+
steps:
53+
- name: Checkout code
54+
uses: actions/checkout@v4
55+
56+
- name: Setup Node.js
57+
uses: actions/setup-node@v4
58+
with:
59+
node-version: "20"
60+
cache: npm
61+
cache-dependency-path: BitStoreWeb/BitStoreWeb.Net9/package-lock.json
62+
63+
- name: Install frontend dependencies
64+
run: npm ci --prefix BitStoreWeb/BitStoreWeb.Net9
65+
66+
- name: Build frontend assets
67+
run: npm --prefix BitStoreWeb/BitStoreWeb.Net9 run build
68+
69+
- name: Setup .NET SDK
70+
uses: actions/setup-dotnet@v4
71+
with:
72+
dotnet-version: "9.0.x"
73+
74+
- name: Restore .NET dependencies
75+
run: dotnet restore BitStoreWeb/BitStoreWeb.Net9/BitStoreWeb.Net9.csproj
76+
77+
- name: Publish .NET app
78+
run: dotnet publish BitStoreWeb/BitStoreWeb.Net9/BitStoreWeb.Net9.csproj --configuration Release --no-restore --output ./publish
79+
80+
- name: Deploy via SSH
81+
uses: appleboy/scp-action@v0.1.7
82+
with:
83+
host: ${{ secrets.SSH_HOST }}
84+
username: ${{ secrets.SSH_USER }}
85+
password: ${{ secrets.SSH_PASSWORD }}
86+
port: ${{ secrets.SSH_PORT || 22 }}
87+
source: "publish/*"
88+
target: ${{ secrets.SSH_TARGET || '/httpdocs' }}
89+
strip_components: 1
90+
91+
- name: Restart app service
92+
if: ${{ env.SSH_SERVICE_NAME != '' }}
93+
uses: appleboy/ssh-action@v1.2.0
94+
with:
95+
host: ${{ secrets.SSH_HOST }}
96+
username: ${{ secrets.SSH_USER }}
97+
password: ${{ secrets.SSH_PASSWORD }}
98+
port: ${{ secrets.SSH_PORT || 22 }}
99+
script: sudo systemctl restart ${{ env.SSH_SERVICE_NAME }}

BitStoreWeb/BitStoreWeb.Net9/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ wwwroot/dist/
33
bitstore.db
44
bitstore.db-shm
55
bitstore.db-wal
6+
bitstore-local.*.log
7+
bitstore-run.*.log

BitStoreWeb/BitStoreWeb.Net9/BitStoreWeb.Net9.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
11-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
10+
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0" />
1211
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.2" />
1312
</ItemGroup>
1413

BitStoreWeb/BitStoreWeb.Net9/Controllers/BucketApiController.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ public async Task<IActionResult> AddRecord(
185185
return Unauthorized(new { message = writeAccessError });
186186
}
187187

188+
if (await FreeRecordLimitReachedAsync(bucket.Id, bucket.OwnerUserId, cancellationToken))
189+
{
190+
return StatusCode(
191+
StatusCodes.Status403Forbidden,
192+
new { message = $"Free accounts can store up to {AccountLimits.FreeRecordLimit} records per bucket." });
193+
}
194+
188195
var record = new BucketRecord
189196
{
190197
BucketId = bucket.Id,
@@ -407,6 +414,23 @@ private bool HasWriteAccess(Bucket bucket, string? apiKeyHeader, string? apiKey,
407414
return false;
408415
}
409416

417+
private async Task<bool> FreeRecordLimitReachedAsync(int bucketId, int ownerUserId, CancellationToken cancellationToken)
418+
{
419+
var userRole = await _db.Users
420+
.AsNoTracking()
421+
.Where(x => x.Id == ownerUserId)
422+
.Select(x => x.Role)
423+
.SingleOrDefaultAsync(cancellationToken);
424+
if (!AccountLimits.IsFreeAccount(userRole))
425+
{
426+
return false;
427+
}
428+
429+
var recordCount = await _db.BucketRecords
430+
.CountAsync(x => x.BucketId == bucketId, cancellationToken);
431+
return recordCount >= AccountLimits.FreeRecordLimit;
432+
}
433+
410434
private static BucketRecordResponse MapRecord(BucketRecord record)
411435
=> new(record.Id, record.Value, record.CreatedUtc, record.UpdatedUtc);
412436

BitStoreWeb/BitStoreWeb.Net9/Controllers/BucketController.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ public async Task<IActionResult> AddRecord(int id, string value, CancellationTok
6868
return RedirectToAction(nameof(Index), new { id });
6969
}
7070

71+
if (await FreeRecordLimitReachedAsync(bucket.Id, userId.Value, cancellationToken))
72+
{
73+
TempData["ErrorMessage"] = $"Free accounts can store up to {AccountLimits.FreeRecordLimit} records per bucket.";
74+
return RedirectToAction(nameof(Index), new { id });
75+
}
76+
7177
_db.BucketRecords.Add(new BucketRecord
7278
{
7379
BucketId = bucket.Id,
@@ -256,6 +262,23 @@ public async Task<IActionResult> DeleteBucket(int id, CancellationToken cancella
256262
.SingleOrDefaultAsync(x => x.Id == bucketId && x.OwnerUserId == userId, cancellationToken);
257263
}
258264

265+
private async Task<bool> FreeRecordLimitReachedAsync(int bucketId, int userId, CancellationToken cancellationToken)
266+
{
267+
var userRole = await _db.Users
268+
.AsNoTracking()
269+
.Where(x => x.Id == userId)
270+
.Select(x => x.Role)
271+
.SingleOrDefaultAsync(cancellationToken);
272+
if (!AccountLimits.IsFreeAccount(userRole))
273+
{
274+
return false;
275+
}
276+
277+
var recordCount = await _db.BucketRecords
278+
.CountAsync(x => x.BucketId == bucketId, cancellationToken);
279+
return recordCount >= AccountLimits.FreeRecordLimit;
280+
}
281+
259282
private async Task<BucketDetailsViewModel> BuildViewModelAsync(Bucket bucket, CancellationToken cancellationToken)
260283
{
261284
var records = await _db.BucketRecords

BitStoreWeb/BitStoreWeb.Net9/Controllers/BucketsController.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@ public async Task<IActionResult> Create(BucketsViewModel model, CancellationToke
7676
return View("Index", model);
7777
}
7878

79+
var userRole = await _db.Users
80+
.AsNoTracking()
81+
.Where(x => x.Id == userId.Value)
82+
.Select(x => x.Role)
83+
.SingleOrDefaultAsync(cancellationToken);
84+
if (AccountLimits.IsFreeAccount(userRole))
85+
{
86+
var bucketCount = await _db.Buckets
87+
.CountAsync(x => x.OwnerUserId == userId.Value, cancellationToken);
88+
if (bucketCount >= AccountLimits.FreeBucketLimit)
89+
{
90+
ModelState.AddModelError(
91+
nameof(model.NewBucketName),
92+
$"Free accounts can create {AccountLimits.FreeBucketLimit} bucket.");
93+
model.Buckets = await LoadBucketSummariesAsync(userId.Value, cancellationToken);
94+
return View("Index", model);
95+
}
96+
}
97+
7998
var normalizedBucketName = model.NewBucketName.ToUpperInvariant();
8099
var nameExists = await _db.Buckets.AnyAsync(
81100
x => x.OwnerUserId == userId.Value && x.Name.ToUpper() == normalizedBucketName,

0 commit comments

Comments
 (0)