Initial project import

This commit is contained in:
Agila Forge Importer committed 2026-07-13 15:20:32 +00:00
commit 23f2d29e32
11957 files changed
+1754577

No files matched your search

@@ -0,0 +1,8 @@
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.v]
indent_style = tab
@@ -0,0 +1,4 @@
*.v linguist-language=V text=auto eol=lf
*.vv linguist-language=V text=auto eol=lf
*.vsh linguist-language=V text=auto eol=lf
**/v.mod linguist-language=V text=auto eol=lf
+11
View File
@@ -0,0 +1,11 @@
# Binaries for programs and plugins
main
v
*.exe
*.exe~
*.so
*.dylib
*.dll
vls.log
.env
*.db
@@ -0,0 +1,19 @@
module main
import veb
import json
@['/auth/login'; post]
pub fn (mut app App) controller_auth(mut ctx Context) veb.Result {
body := json.decode(AuthRequestDto, ctx.req.data) or {
ctx.res.set_status(.bad_request)
return ctx.text('Failed to decode json, error: ${err}')
}
response := app.service_auth(body.username, body.password) or {
ctx.res.set_status(.bad_request)
return ctx.text('error: ${err}')
}
return ctx.json(response)
}
+8
View File
@@ -0,0 +1,8 @@
module main
struct AuthRequestDto {
// Adding a @[required] attribute will make decoding fail, if that field is not present in the input.
// If a field is not [required], but is missing, it will be assumed to have its default value, like 0 for numbers, or '' for strings, and decoding will not fail.
username string @[required]
password string @[required]
}
@@ -0,0 +1,91 @@
module main
import crypto.hmac
import crypto.sha256
import crypto.bcrypt
import encoding.base64
import json
import databases
import time
import os
struct JwtHeader {
alg string
typ string
}
struct JwtPayload {
sub string // (subject) = Entity to whom the token belongs, usually the user ID;
iss string // (issuer) = Token issuer;
exp string // (expiration) = Timestamp of when the token will expire;
iat time.Time // (issued at) = Timestamp of when the token was created;
aud string // (audience) = Token recipient, represents the application that will use it.
name string
roles string
permissions string
}
fn (mut app App) service_auth(username string, password string) !string {
mut db := databases.create_db_connection() or {
eprintln(err)
panic(err)
}
users := sql db {
select from User where username == username
}!
if users.len == 0 {
return error('user not found')
}
user := users.first()
if !user.active {
return error('user is not active')
}
db.close()!
bcrypt.compare_hash_and_password(password.bytes(), user.password.bytes()) or {
return error('Failed to auth user, ${err}')
}
token := make_token(user)
return token
}
fn make_token(user User) string {
secret := os.getenv('SECRET_KEY')
jwt_header := JwtHeader{'HS256', 'JWT'}
jwt_payload := JwtPayload{
sub: '${user.id}'
name: '${user.username}'
iat: time.now()
}
header := base64.url_encode(json.encode(jwt_header).bytes())
payload := base64.url_encode(json.encode(jwt_payload).bytes())
signature := base64.url_encode(hmac.new(secret.bytes(), '${header}.${payload}'.bytes(),
sha256.sum, sha256.block_size).bytestr().bytes())
jwt := '${header}.${payload}.${signature}'
return jwt
}
fn auth_verify(token string) bool {
if token == '' {
return false
}
secret := os.getenv('SECRET_KEY')
token_split := token.split('.')
signature_mirror := hmac.new(secret.bytes(), '${token_split[0]}.${token_split[1]}'.bytes(),
sha256.sum, sha256.block_size).bytestr().bytes()
signature_from_token := base64.url_decode(token_split[2])
return hmac.equal(signature_from_token, signature_mirror)
}
@@ -0,0 +1,8 @@
module databases
import db.sqlite
pub fn create_db_connection() !sqlite.DB {
mut db := sqlite.connect('database.db')!
return db
}
+36
View File
@@ -0,0 +1,36 @@
module main
import veb
import databases
const http_port = 8081
pub struct Context {
veb.Context
}
struct App {
veb.StaticHandler
}
pub fn (app &App) before_request(mut ctx Context) {
println('[veb] ${ctx.req.method} ${ctx.req.url}')
}
fn main() {
mut db := databases.create_db_connection() or { panic(err) }
sql db {
create table User
} or { panic('error on create table: ${err}') }
db.close() or { panic(err) }
mut app := &App{}
veb.run[App, Context](mut app, http_port)
}
@['/'; get]
pub fn (mut app App) ping(mut ctx Context) veb.Result {
return ctx.text('ping')
}
@@ -0,0 +1,72 @@
module main
import veb
import json
import databases
@['/user/:id/get'; get]
pub fn (mut app App) controller_get_user_by_id(mut ctx Context, id string) veb.Result {
response := app.service_get_user_by_id(id.int()) or {
ctx.res.set_status(.bad_request)
return ctx.text('${err}')
}
return ctx.json(response)
}
@['/user/create'; post]
pub fn (mut app App) controller_create_user(mut ctx Context) veb.Result {
body := json.decode(User, ctx.req.data) or {
ctx.res.set_status(.bad_request)
return ctx.text('Failed to decode json, error: ${err}')
}
response := app.service_add_user(body.username, body.password) or {
ctx.res.set_status(.bad_request)
return ctx.text('error: ${err}')
}
return ctx.json(response)
}
@['/user/get_all'; get]
pub fn (mut app App) controller_get_all_user(mut ctx Context) veb.Result {
token := ctx.req.header.get_custom('token') or { '' }
if !auth_verify(token) {
ctx.res.set_status(.unauthorized)
return ctx.text('Not valid token')
}
response := app.service_get_all_user() or {
ctx.res.set_status(.bad_request)
return ctx.text('${err}')
}
return ctx.json(response)
}
@['/user/get_by_username/:username'; get]
pub fn (mut app App) controller_get_by_username(mut ctx Context, username string) veb.Result {
response := app.service_get_by_username(username) or {
ctx.res.set_status(.bad_request)
return ctx.text('${err}')
}
return ctx.json(response)
}
@['/user/drop'; delete]
pub fn (mut app App) delete(mut ctx Context) veb.Result {
mut db := databases.create_db_connection() or {
ctx.res.set_status(.bad_request)
return ctx.text('${err}')
}
defer {
db.close() or { panic(err) }
}
sql db {
drop table User
} or { panic(err) }
return ctx.text('Successfully deleted table')
}
@@ -0,0 +1,13 @@
module main
@[table: 'users']
struct User {
mut:
id int @[primary; sql: serial]
username string @[required; sql_type: 'TEXT']
password string @[required; sql_type: 'TEXT']
created_at string @[default: 'CURRENT_TIMESTAMP']
updated_at string @[default: 'CURRENT_TIMESTAMP']
deleted_at string @[default: 'CURRENT_TIMESTAMP']
active bool
}
@@ -0,0 +1,94 @@
module main
import crypto.bcrypt
import databases
fn (mut app App) service_add_user(username string, password string) !User {
mut db := databases.create_db_connection() or {
eprintln(err)
return err
}
defer {
db.close() or { panic(err) }
}
hashed_password := bcrypt.generate_from_password(password.bytes(), bcrypt.min_cost) or {
eprintln(err)
return err
}
user_model := User{
username: username
password: hashed_password
active: true
}
sql db {
insert user_model into User
} or {
eprintln(err)
return err
}
users := sql db {
select from User where username == username limit 1
}!
return users.first()
}
fn (mut app App) service_get_user_by_id(user_id int) !User {
mut db := databases.create_db_connection() or {
println(err)
return err
}
defer {
db.close() or { panic(err) }
}
users := sql db {
select from User where id == user_id
}!
return users.first()
}
fn (mut app App) service_get_all_user() ![]User {
mut db := databases.create_db_connection() or {
println(err)
return err
}
defer {
db.close() or { panic(err) }
}
results := sql db {
select from User
}!
return results
}
fn (mut app App) service_get_by_username(username string) !User {
mut db := databases.create_db_connection() or {
println(err)
return err
}
defer {
db.close() or { panic(err) }
}
results := sql db {
select from User where username == username
}!
if results.len == 0 {
return error('User not found')
}
return results[0]
}
+7
View File
@@ -0,0 +1,7 @@
Module {
name: 'veb_orm_jwt'
description: ''
version: ''
license: ''
dependencies: []
}