folder structure refactor volgens doc
This commit is contained in:
parent
c2f4ae10e8
commit
7e8788f7f8
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
/.env
|
||||
/api/.env
|
||||
|
||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/../portfolio-backend" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@ -4,7 +4,7 @@ FROM golang:latest
|
||||
# Set the working directory to /app
|
||||
WORKDIR .
|
||||
# Copy the current directory contents into the container at /app
|
||||
COPY . .
|
||||
COPY .. .
|
||||
|
||||
# Download and install any required dependencies
|
||||
RUN go mod download
|
||||
@ -11,4 +11,5 @@ func ApiRoutes(mux **http.ServeMux) {
|
||||
m.HandleFunc("/api/", handler.CatchAllHandler)
|
||||
m.HandleFunc("POST /api/user", handler.CreateUser)
|
||||
m.HandleFunc("GET /api/user/{id}", handler.GetUser)
|
||||
m.HandleFunc("POST /api/login", handler.Login)
|
||||
}
|
||||
51
api/api/handler/authHandler.go
Normal file
51
api/api/handler/authHandler.go
Normal file
@ -0,0 +1,51 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/ent/user"
|
||||
"portfolio/database/query"
|
||||
"portfolio/service/bcrypt"
|
||||
)
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("test")
|
||||
var u *ent.User
|
||||
|
||||
isHtmx := r.Header.Get("HX-Request")
|
||||
|
||||
if isHtmx == "true" {
|
||||
u = &ent.User{
|
||||
Name: r.PostFormValue("name"),
|
||||
Password: r.PostFormValue("password"),
|
||||
Role: user.Role(r.PostFormValue("role")),
|
||||
}
|
||||
} else {
|
||||
err := json.NewDecoder(r.Body).Decode(&u)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w)
|
||||
}
|
||||
}
|
||||
|
||||
User, err := query.GetLogin(context.Background(), u.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if bcrypt.CheckPasswordHash(u.Password, User.Password) {
|
||||
w.Header().Set("HX-Location", "/")
|
||||
return
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
err = json.NewEncoder(w).Encode(User)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
24
api/api/webHandler/loginpageHandler.go
Normal file
24
api/api/webHandler/loginpageHandler.go
Normal file
@ -0,0 +1,24 @@
|
||||
package webHandler
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func InitLoginpage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
tmpl := template.Must(template.ParseFiles(
|
||||
"./templates/login/index.html",
|
||||
"./templates/navbar/index.html",
|
||||
"./templates/themeSelector/index.html",
|
||||
))
|
||||
|
||||
err := tmpl.Execute(w, nil)
|
||||
if err != nil {
|
||||
_, err := w.Write([]byte("failed to load"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ func WebRoutes(mux **http.ServeMux) {
|
||||
m.HandleFunc("GET /{$}", webHandler.InitHomepage)
|
||||
m.HandleFunc("GET /projecten/{$}", webHandler.InitProjectpage)
|
||||
m.HandleFunc("GET /about/{$}", webHandler.InitAboutpage)
|
||||
m.HandleFunc("GET /login/{$}", webHandler.InitLoginpage)
|
||||
|
||||
m.HandleFunc("POST /theme", webHandler.UpdateTheme)
|
||||
|
||||
@ -42,7 +42,8 @@ var (
|
||||
// UsersColumns holds the columns for the "users" table.
|
||||
UsersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "name", Type: field.TypeString, Default: "John doe"},
|
||||
{Name: "name", Type: field.TypeString, Unique: true},
|
||||
{Name: "password", Type: field.TypeString},
|
||||
{Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "visitor"}},
|
||||
}
|
||||
// UsersTable holds the schema information for the "users" table.
|
||||
@ -932,6 +932,7 @@ type UserMutation struct {
|
||||
typ string
|
||||
id *int
|
||||
name *string
|
||||
password *string
|
||||
role *user.Role
|
||||
clearedFields map[string]struct{}
|
||||
teams map[int]struct{}
|
||||
@ -1076,6 +1077,42 @@ func (m *UserMutation) ResetName() {
|
||||
m.name = nil
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (m *UserMutation) SetPassword(s string) {
|
||||
m.password = &s
|
||||
}
|
||||
|
||||
// Password returns the value of the "password" field in the mutation.
|
||||
func (m *UserMutation) Password() (r string, exists bool) {
|
||||
v := m.password
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldPassword returns the old "password" field's value of the User entity.
|
||||
// If the User object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *UserMutation) OldPassword(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldPassword is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldPassword requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldPassword: %w", err)
|
||||
}
|
||||
return oldValue.Password, nil
|
||||
}
|
||||
|
||||
// ResetPassword resets all changes to the "password" field.
|
||||
func (m *UserMutation) ResetPassword() {
|
||||
m.password = nil
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (m *UserMutation) SetRole(u user.Role) {
|
||||
m.role = &u
|
||||
@ -1200,10 +1237,13 @@ func (m *UserMutation) Type() string {
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *UserMutation) Fields() []string {
|
||||
fields := make([]string, 0, 2)
|
||||
fields := make([]string, 0, 3)
|
||||
if m.name != nil {
|
||||
fields = append(fields, user.FieldName)
|
||||
}
|
||||
if m.password != nil {
|
||||
fields = append(fields, user.FieldPassword)
|
||||
}
|
||||
if m.role != nil {
|
||||
fields = append(fields, user.FieldRole)
|
||||
}
|
||||
@ -1217,6 +1257,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
case user.FieldName:
|
||||
return m.Name()
|
||||
case user.FieldPassword:
|
||||
return m.Password()
|
||||
case user.FieldRole:
|
||||
return m.Role()
|
||||
}
|
||||
@ -1230,6 +1272,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er
|
||||
switch name {
|
||||
case user.FieldName:
|
||||
return m.OldName(ctx)
|
||||
case user.FieldPassword:
|
||||
return m.OldPassword(ctx)
|
||||
case user.FieldRole:
|
||||
return m.OldRole(ctx)
|
||||
}
|
||||
@ -1248,6 +1292,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
|
||||
}
|
||||
m.SetName(v)
|
||||
return nil
|
||||
case user.FieldPassword:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetPassword(v)
|
||||
return nil
|
||||
case user.FieldRole:
|
||||
v, ok := value.(user.Role)
|
||||
if !ok {
|
||||
@ -1307,6 +1358,9 @@ func (m *UserMutation) ResetField(name string) error {
|
||||
case user.FieldName:
|
||||
m.ResetName()
|
||||
return nil
|
||||
case user.FieldPassword:
|
||||
m.ResetPassword()
|
||||
return nil
|
||||
case user.FieldRole:
|
||||
m.ResetRole()
|
||||
return nil
|
||||
9
api/database/ent/runtime.go
Normal file
9
api/database/ent/runtime.go
Normal file
@ -0,0 +1,9 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
// The init function reads all schema descriptors with runtime code
|
||||
// (default values, validators, hooks and policies) and stitches it
|
||||
// to their package variables.
|
||||
func init() {
|
||||
}
|
||||
@ -15,7 +15,8 @@ type User struct {
|
||||
func (User) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").
|
||||
Default("John doe"),
|
||||
Unique(),
|
||||
field.String("password"),
|
||||
field.Enum("role").
|
||||
Values("admin", "user", "visitor"),
|
||||
}
|
||||
@ -18,6 +18,8 @@ type User struct {
|
||||
ID int `json:"id,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Password holds the value of the "password" field.
|
||||
Password string `json:"password,omitempty"`
|
||||
// Role holds the value of the "role" field.
|
||||
Role user.Role `json:"role,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
@ -51,7 +53,7 @@ func (*User) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case user.FieldID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case user.FieldName, user.FieldRole:
|
||||
case user.FieldName, user.FieldPassword, user.FieldRole:
|
||||
values[i] = new(sql.NullString)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
@ -80,6 +82,12 @@ func (u *User) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
u.Name = value.String
|
||||
}
|
||||
case user.FieldPassword:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field password", values[i])
|
||||
} else if value.Valid {
|
||||
u.Password = value.String
|
||||
}
|
||||
case user.FieldRole:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field role", values[i])
|
||||
@ -130,6 +138,9 @@ func (u *User) String() string {
|
||||
builder.WriteString("name=")
|
||||
builder.WriteString(u.Name)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("password=")
|
||||
builder.WriteString(u.Password)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("role=")
|
||||
builder.WriteString(fmt.Sprintf("%v", u.Role))
|
||||
builder.WriteByte(')')
|
||||
@ -16,6 +16,8 @@ const (
|
||||
FieldID = "id"
|
||||
// FieldName holds the string denoting the name field in the database.
|
||||
FieldName = "name"
|
||||
// FieldPassword holds the string denoting the password field in the database.
|
||||
FieldPassword = "password"
|
||||
// FieldRole holds the string denoting the role field in the database.
|
||||
FieldRole = "role"
|
||||
// EdgeTeams holds the string denoting the teams edge name in mutations.
|
||||
@ -33,6 +35,7 @@ const (
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldName,
|
||||
FieldPassword,
|
||||
FieldRole,
|
||||
}
|
||||
|
||||
@ -52,11 +55,6 @@ func ValidColumn(column string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultName holds the default value on creation for the "name" field.
|
||||
DefaultName string
|
||||
)
|
||||
|
||||
// Role defines the type for the "role" enum field.
|
||||
type Role string
|
||||
|
||||
@ -94,6 +92,11 @@ func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPassword orders the results by the password field.
|
||||
func ByPassword(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPassword, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByRole orders the results by the role field.
|
||||
func ByRole(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRole, opts...).ToFunc()
|
||||
@ -59,6 +59,11 @@ func Name(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ.
|
||||
func Password(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldName, v))
|
||||
@ -124,6 +129,71 @@ func NameContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// PasswordEQ applies the EQ predicate on the "password" field.
|
||||
func PasswordEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordNEQ applies the NEQ predicate on the "password" field.
|
||||
func PasswordNEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldNEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordIn applies the In predicate on the "password" field.
|
||||
func PasswordIn(vs ...string) predicate.User {
|
||||
return predicate.User(sql.FieldIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordNotIn applies the NotIn predicate on the "password" field.
|
||||
func PasswordNotIn(vs ...string) predicate.User {
|
||||
return predicate.User(sql.FieldNotIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordGT applies the GT predicate on the "password" field.
|
||||
func PasswordGT(v string) predicate.User {
|
||||
return predicate.User(sql.FieldGT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordGTE applies the GTE predicate on the "password" field.
|
||||
func PasswordGTE(v string) predicate.User {
|
||||
return predicate.User(sql.FieldGTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLT applies the LT predicate on the "password" field.
|
||||
func PasswordLT(v string) predicate.User {
|
||||
return predicate.User(sql.FieldLT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLTE applies the LTE predicate on the "password" field.
|
||||
func PasswordLTE(v string) predicate.User {
|
||||
return predicate.User(sql.FieldLTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContains applies the Contains predicate on the "password" field.
|
||||
func PasswordContains(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContains(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasPrefix applies the HasPrefix predicate on the "password" field.
|
||||
func PasswordHasPrefix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasPrefix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasSuffix applies the HasSuffix predicate on the "password" field.
|
||||
func PasswordHasSuffix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasSuffix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordEqualFold applies the EqualFold predicate on the "password" field.
|
||||
func PasswordEqualFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEqualFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContainsFold applies the ContainsFold predicate on the "password" field.
|
||||
func PasswordContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// RoleEQ applies the EQ predicate on the "role" field.
|
||||
func RoleEQ(v Role) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldRole, v))
|
||||
@ -26,11 +26,9 @@ func (uc *UserCreate) SetName(s string) *UserCreate {
|
||||
return uc
|
||||
}
|
||||
|
||||
// SetNillableName sets the "name" field if the given value is not nil.
|
||||
func (uc *UserCreate) SetNillableName(s *string) *UserCreate {
|
||||
if s != nil {
|
||||
uc.SetName(*s)
|
||||
}
|
||||
// SetPassword sets the "password" field.
|
||||
func (uc *UserCreate) SetPassword(s string) *UserCreate {
|
||||
uc.mutation.SetPassword(s)
|
||||
return uc
|
||||
}
|
||||
|
||||
@ -62,7 +60,6 @@ func (uc *UserCreate) Mutation() *UserMutation {
|
||||
|
||||
// Save creates the User in the database.
|
||||
func (uc *UserCreate) Save(ctx context.Context) (*User, error) {
|
||||
uc.defaults()
|
||||
return withHooks(ctx, uc.sqlSave, uc.mutation, uc.hooks)
|
||||
}
|
||||
|
||||
@ -88,19 +85,14 @@ func (uc *UserCreate) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (uc *UserCreate) defaults() {
|
||||
if _, ok := uc.mutation.Name(); !ok {
|
||||
v := user.DefaultName
|
||||
uc.mutation.SetName(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (uc *UserCreate) check() error {
|
||||
if _, ok := uc.mutation.Name(); !ok {
|
||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)}
|
||||
}
|
||||
if _, ok := uc.mutation.Password(); !ok {
|
||||
return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "User.password"`)}
|
||||
}
|
||||
if _, ok := uc.mutation.Role(); !ok {
|
||||
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "User.role"`)}
|
||||
}
|
||||
@ -139,6 +131,10 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||
_node.Name = value
|
||||
}
|
||||
if value, ok := uc.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
_node.Password = value
|
||||
}
|
||||
if value, ok := uc.mutation.Role(); ok {
|
||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||
_node.Role = value
|
||||
@ -180,7 +176,6 @@ func (ucb *UserCreateBulk) Save(ctx context.Context) ([]*User, error) {
|
||||
for i := range ucb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := ucb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*UserMutation)
|
||||
if !ok {
|
||||
@ -42,6 +42,20 @@ func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate {
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (uu *UserUpdate) SetPassword(s string) *UserUpdate {
|
||||
uu.mutation.SetPassword(s)
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||
func (uu *UserUpdate) SetNillablePassword(s *string) *UserUpdate {
|
||||
if s != nil {
|
||||
uu.SetPassword(*s)
|
||||
}
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate {
|
||||
uu.mutation.SetRole(u)
|
||||
@ -149,6 +163,9 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := uu.mutation.Name(); ok {
|
||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uu.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uu.mutation.Role(); ok {
|
||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
@ -231,6 +248,20 @@ func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne {
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne {
|
||||
uuo.mutation.SetPassword(s)
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||
func (uuo *UserUpdateOne) SetNillablePassword(s *string) *UserUpdateOne {
|
||||
if s != nil {
|
||||
uuo.SetPassword(*s)
|
||||
}
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne {
|
||||
uuo.mutation.SetRole(u)
|
||||
@ -368,6 +399,9 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
|
||||
if value, ok := uuo.mutation.Name(); ok {
|
||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uuo.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uuo.mutation.Role(); ok {
|
||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
23
api/database/query/authQuery.go
Normal file
23
api/database/query/authQuery.go
Normal file
@ -0,0 +1,23 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"portfolio/database"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/ent/user"
|
||||
)
|
||||
|
||||
func GetLogin(ctx context.Context, name string) (*ent.User, error) {
|
||||
|
||||
u, err := database.Client.User.
|
||||
Query().
|
||||
Where(user.Name(name)).
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed querying user: %w", err)
|
||||
}
|
||||
log.Println("user returned: ", u)
|
||||
return u, nil
|
||||
}
|
||||
@ -19,6 +19,7 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/zclconf/go-cty v1.14.2 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
@ -58,6 +58,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/zclconf/go-cty v1.14.2 h1:kTG7lqmBou0Zkx35r6HJHUQTvaRPr5bIAf3AoHS0izI=
|
||||
github.com/zclconf/go-cty v1.14.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
@ -15,7 +15,7 @@ func main() {
|
||||
log.Fatalf(".env not found: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
print("test")
|
||||
// Create a new request multiplexer
|
||||
// Take incoming requests and dispatch them to the matching webHandler
|
||||
mux := http.NewServeMux()
|
||||
15
api/service/bcrypt/password.go
Normal file
15
api/service/bcrypt/password.go
Normal file
@ -0,0 +1,15 @@
|
||||
package bcrypt
|
||||
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
|
||||
func HashPassword(password string) (string, error) {
|
||||
//generate hash from password
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func CheckPasswordHash(password, hash string) bool {
|
||||
//check password with hash
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1007 B After Width: | Height: | Size: 1007 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
157
api/templates/login/index.html
Normal file
157
api/templates/login/index.html
Normal file
@ -0,0 +1,157 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-bs-theme="auto">
|
||||
<head><script src="../assets/js/color-modes.js"></script>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
||||
<meta name="generator" content="Hugo 0.122.0">
|
||||
<title>Signin Template · Bootstrap v5.3</title>
|
||||
|
||||
<link rel="canonical" href="https://getbootstrap.com/docs/5.3/examples/sign-in/">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
|
||||
|
||||
<link href="../assets/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
.bd-placeholder-img {
|
||||
font-size: 1.125rem;
|
||||
text-anchor: middle;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.bd-placeholder-img-lg {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.b-example-divider {
|
||||
width: 100%;
|
||||
height: 3rem;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
border: solid rgba(0, 0, 0, .15);
|
||||
border-width: 1px 0;
|
||||
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.b-example-vr {
|
||||
flex-shrink: 0;
|
||||
width: 1.5rem;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.bi {
|
||||
vertical-align: -.125em;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.nav-scroller {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
height: 2.75rem;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.nav-scroller .nav {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding-bottom: 1rem;
|
||||
margin-top: -1px;
|
||||
overflow-x: auto;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.btn-bd-primary {
|
||||
--bd-violet-bg: #712cf9;
|
||||
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
|
||||
|
||||
--bs-btn-font-weight: 600;
|
||||
--bs-btn-color: var(--bs-white);
|
||||
--bs-btn-bg: var(--bd-violet-bg);
|
||||
--bs-btn-border-color: var(--bd-violet-bg);
|
||||
--bs-btn-hover-color: var(--bs-white);
|
||||
--bs-btn-hover-bg: #6528e0;
|
||||
--bs-btn-hover-border-color: #6528e0;
|
||||
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
|
||||
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||
--bs-btn-active-bg: #5a23c8;
|
||||
--bs-btn-active-border-color: #5a23c8;
|
||||
}
|
||||
|
||||
.bd-mode-toggle {
|
||||
z-index: 1500;
|
||||
}
|
||||
|
||||
.bd-mode-toggle .dropdown-menu .active .bi {
|
||||
display: block !important;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
max-width: 330px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||
|
||||
{{template "themeSelector"}}
|
||||
|
||||
<main class="form-signin w-100 m-auto">
|
||||
<form hx-post="/api/login" hx-target="body">
|
||||
<img class="mb-4" src="../assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
|
||||
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
|
||||
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" name="name" id="floatingInput" placeholder="name@example.com">
|
||||
<label for="floatingInput">Naam</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" name="password" id="floatingPassword" placeholder="Password">
|
||||
<label for="floatingPassword">Password</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check text-start my-3">
|
||||
<input class="form-check-input" type="checkbox" value="remember-me" id="flexCheckDefault">
|
||||
<label class="form-check-label" for="flexCheckDefault">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
|
||||
<p class="mt-5 mb-3 text-body-secondary">© 2017–2024</p>
|
||||
</form>
|
||||
</main>
|
||||
<script src="../assets/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -20,10 +20,7 @@
|
||||
<a class="nav-link disabled" aria-disabled="true">Servers</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="d-flex" role="search">
|
||||
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||
</form>
|
||||
<a class="btn btn-primary" href="/login">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@ -1,20 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"portfolio/database/ent/schema"
|
||||
"portfolio/database/ent/user"
|
||||
)
|
||||
|
||||
// The init function reads all schema descriptors with runtime code
|
||||
// (default values, validators, hooks and policies) and stitches it
|
||||
// to their package variables.
|
||||
func init() {
|
||||
userFields := schema.User{}.Fields()
|
||||
_ = userFields
|
||||
// userDescName is the schema descriptor for name field.
|
||||
userDescName := userFields[0].Descriptor()
|
||||
// user.DefaultName holds the default value on creation for the name field.
|
||||
user.DefaultName = userDescName.Default.(string)
|
||||
}
|
||||
@ -2,7 +2,7 @@ version: '3.8'
|
||||
|
||||
services:
|
||||
api:
|
||||
build: .
|
||||
build: ./api
|
||||
ports:
|
||||
- "4002:4002"
|
||||
restart: unless-stopped
|
||||
Loading…
x
Reference in New Issue
Block a user