first commit

This commit is contained in:
2023-12-27 17:31:49 +09:00
commit ab6a57b907
69 changed files with 11271 additions and 0 deletions

72
internal/services/auth.go Normal file
View File

@ -0,0 +1,72 @@
package services
import (
"errors"
"fmt"
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
"time"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
type authService struct {
userRepository repositories.UserRepository
tokenRepository repositories.TokenRepository
}
type AuthService interface {
Register(*models.RegisterRequest) (*models.User, error)
Login(*models.LoginRequest) (*models.User, error)
}
func NewAuthService(userRepository repositories.UserRepository, tokenRepository repositories.TokenRepository) AuthService {
return &authService{
userRepository: userRepository,
tokenRepository: tokenRepository,
}
}
func (s *authService) Register(request *models.RegisterRequest) (*models.User, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(request.Password), 10)
if err != nil {
return nil, errors.New("fail to hash password")
}
// Create the user
newUser := models.User{
GUID: uuid.NewString(),
FirstName: request.FirstName,
LastName: request.LastName,
Username: request.Username,
Password: string(hash),
Gender: request.Gender,
Phone: request.Phone,
UserRole: request.UserRole,
Image: request.Image,
RegisterAt: time.Now(),
}
fmt.Println(newUser)
user, err := s.userRepository.Create(&newUser)
if err != nil {
return nil, errors.New("fail to create user")
}
return user, err
}
func (s *authService) Login(request *models.LoginRequest) (*models.User, error) {
user, err := s.userRepository.FindByUsername(request.Username)
if err != nil || user == nil {
return nil, errors.New("invalid user or password")
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(request.Password))
if err != nil {
return nil, errors.New("invalid user or password")
}
return user, nil
}

View File

@ -0,0 +1,64 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type centerService struct {
repository repositories.CenterRepository
tokenRepository repositories.TokenRepository
}
type CenterService interface {
List(string, int, int) (*[]models.Center, error)
Total(string) (int64, error)
Find(int64) (*models.Center, error)
FindByTitle(string) (*models.Center, error)
Create(*models.Center) (*models.Center, error)
Update(*models.Center) (*models.Center, error)
Delete(int64) error
}
func NewCenterService(repository repositories.CenterRepository, tokenRepository repositories.TokenRepository) CenterService {
return &centerService{
repository: repository,
tokenRepository: tokenRepository,
}
}
func (s *centerService) List(q string, page int, limit int) (*[]models.Center, error) {
return s.repository.List(q, page, limit)
}
func (s *centerService) Total(q string) (int64, error) {
return s.repository.Total(q)
}
func (s *centerService) Find(id int64) (*models.Center, error) {
return s.repository.Find(id)
}
func (s *centerService) FindByTitle(centername string) (*models.Center, error) {
return s.repository.FindByTitle(centername)
}
func (s *centerService) Create(center *models.Center) (*models.Center, error) {
result, err := s.repository.Create(center)
return result, err
}
func (s *centerService) Update(center *models.Center) (*models.Center, error) {
result, err := s.repository.Update(center)
return result, err
}
func (s *centerService) Delete(id int64) error {
err := s.repository.Delete(id)
return err
}

85
internal/services/quiz.go Normal file
View File

@ -0,0 +1,85 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
"time"
"github.com/google/uuid"
)
type quizService struct {
repository repositories.QuizRepository
}
type QuizService interface {
List(int64, int, int) (*[]models.Quiz, error)
Total(int64) (int64, error)
Find(int64) (*models.Quiz, error)
Create(*models.Quiz) (*models.Quiz, error)
Update(*models.Quiz) (*models.Quiz, error)
Delete(int64) error
}
func NewQuizService(repository repositories.QuizRepository) QuizService {
return &quizService{
repository: repository,
}
}
func (s *quizService) List(quiz_paper_id int64, page int, limit int) (*[]models.Quiz, error) {
return s.repository.List(quiz_paper_id, page, limit)
}
func (s *quizService) Total(quiz_paper_id int64) (int64, error) {
return s.repository.Total(quiz_paper_id)
}
func (s *quizService) Find(id int64) (*models.Quiz, error) {
return s.repository.Find(id)
}
func (s *quizService) Create(quiz *models.Quiz) (*models.Quiz, error) {
result, err := s.repository.Create(quiz)
return result, err
}
func (s *quizService) Update(quiz *models.Quiz) (*models.Quiz, error) {
result, err := s.repository.Update(quiz)
return result, err
}
func (s *quizService) Delete(id int64) error {
err := s.repository.Delete(id)
return err
}
func (s *quizService) Generate(quizpaper *models.QuizPaper) ([]models.Quiz, error) {
templates, err := s.repository.List(quizpaper.ID, 1, 1000)
if err != nil {
return nil, err
}
var quizzes []models.Quiz
for _, q := range *templates {
quiz := models.Quiz{
GUID: uuid.NewString(),
CenterID: quizpaper.CenterID,
QuizPaperID: quizpaper.ID,
No: q.No,
QuestionType: q.QuestionType,
Question: q.Question,
Content: q.Content,
Answer: q.Answer,
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
}
quizzes = append(quizzes, quiz)
}
return quizzes, nil
}

View File

@ -0,0 +1,56 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type quizPaperService struct {
repository repositories.QuizPaperRepository
}
type QuizPaperService interface {
List(string, string, int, int) (*[]models.QuizPaper, error)
Total(string, string) (int64, error)
Find(int64) (*models.QuizPaper, error)
Create(*models.QuizPaper) (*models.QuizPaper, error)
Update(*models.QuizPaper) (*models.QuizPaper, error)
Delete(string) error
}
func NewQuizPaperService(repository repositories.QuizPaperRepository) QuizPaperService {
return &quizPaperService{
repository: repository,
}
}
func (s *quizPaperService) List(q string, tag string, page int, limit int) (*[]models.QuizPaper, error) {
return s.repository.List(q, tag, page, limit)
}
func (s *quizPaperService) Total(q string, tag string) (int64, error) {
return s.repository.Total(q, tag)
}
func (s *quizPaperService) Find(id int64) (*models.QuizPaper, error) {
return s.repository.Find(id)
}
func (s *quizPaperService) Create(quizPaper *models.QuizPaper) (*models.QuizPaper, error) {
result, err := s.repository.Create(quizPaper)
return result, err
}
func (s *quizPaperService) Update(quizPaper *models.QuizPaper) (*models.QuizPaper, error) {
result, err := s.repository.Update(quizPaper)
return result, err
}
func (s *quizPaperService) Delete(id string) error {
err := s.repository.Delete(id)
return err
}

200
internal/services/token.go Normal file
View File

@ -0,0 +1,200 @@
package services
import (
"errors"
"fmt"
"strings"
"time"
config "learnsteam/cslms-api/configs"
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
"github.com/golang-jwt/jwt/v5"
)
type tokenService struct {
repository repositories.TokenRepository
}
type TokenService interface {
Find(int64) (*models.Token, error)
Create(int64, string) (*models.Token, error)
Update(*models.Token) (*models.Token, error)
Delete(string) error
Refresh(string) (*models.Token, error)
Generate(string, int64, string) (string, error)
Verify(tokenString string) (*jwt.Token, error)
GetJwtToken(string) (*jwt.Token, error)
ExtractTokenString(string) string
VerifyTokenString(string) (*jwt.Token, error)
ValidToken(*jwt.Token) (bool, error)
}
func NewTokenService(repository repositories.TokenRepository) TokenService {
return &tokenService{
repository: repository,
}
}
func (s *tokenService) Find(id int64) (*models.Token, error) {
return s.repository.Find(id)
}
func (s *tokenService) Create(user_id int64, role string) (*models.Token, error) {
expiredAt := time.Now().Add(time.Hour * 24 * 30)
accessToken, err := s.repository.Generate(user_id, expiredAt.Unix(), role)
if err != nil {
return nil, err
}
refreshExpiredAt := time.Now().Add(time.Hour * 24 * 90)
refreshToken, err := s.repository.Generate(user_id, refreshExpiredAt.Unix(), role)
if err != nil {
return nil, err
}
newToken := &models.Token{
UserID: user_id,
Token: accessToken,
RefreshToken: refreshToken,
Status: "on",
EndingAt: expiredAt,
RegisterAt: time.Now(),
}
token, err := s.repository.Create(newToken)
return token, err
}
func (s *tokenService) Update(token *models.Token) (*models.Token, error) {
return s.repository.Update(token)
}
func (s *tokenService) Delete(id string) error {
return s.repository.Delete(id)
}
func (s *tokenService) Verify(tokenString string) (*jwt.Token, error) {
jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
return []byte(config.SECRET_KEY), nil
})
return jwtToken, err
}
func (s *tokenService) Generate(user_id string, expire_at int64, role string) (string, error) {
claims := jwt.MapClaims{}
claims["authorized"] = true
claims["sub"] = user_id
claims["exp"] = expire_at
claims["role"] = role
at := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err := at.SignedString([]byte(config.SECRET_KEY))
return token, err
}
func (s *tokenService) GetJwtToken(tokenString string) (*jwt.Token, error) {
jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
return []byte(config.SECRET_KEY), nil
})
return jwtToken, err
}
func (s *tokenService) ExtractTokenString(authorization string) string {
strArr := strings.Split(authorization, " ")
if len(strArr) == 2 {
return strArr[1]
}
return ""
}
func (s *tokenService) VerifyTokenString(tokenString string) (*jwt.Token, error) {
jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
return []byte(config.SECRET_KEY), nil
})
if err != nil {
return nil, err
}
return jwtToken, nil
}
func (s *tokenService) ValidToken(jwtToken *jwt.Token) (bool, error) {
if jwtToken == nil {
return false, fmt.Errorf("no token")
}
return jwtToken.Valid, nil
}
func (s *tokenService) Refresh(refreshToken string) (*models.Token, error) {
fmt.Println("refresh_token", refreshToken)
jwtToken, err := jwt.Parse(refreshToken, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
return []byte(config.SECRET_KEY), nil
})
if err != nil {
fmt.Println("refresh token is not valid")
} else {
fmt.Println("refresh token is valid")
}
if err != nil {
fmt.Println("error", err.Error())
return nil, err
}
claims, ok := jwtToken.Claims.(jwt.MapClaims)
if !ok || !jwtToken.Valid {
return nil, errors.New("refresh token is invalid")
}
sub := claims["sub"].(int64)
if err != nil {
return nil, errors.New("wrong user")
}
role := claims["role"].(string)
token, err := s.repository.FindByRefreshToken(sub, refreshToken)
if err != nil {
return nil, errors.New("wrong token")
}
expiredAt := time.Now().Add(time.Hour * 24 * 30)
accessToken, err := s.repository.Generate(sub, expiredAt.Unix(), role)
if err != nil {
return nil, err
}
refreshExpiredAt := time.Now().Add(time.Hour * 24 * 90)
refreshToken, err = s.repository.Generate(sub, refreshExpiredAt.Unix(), role)
if err != nil {
return nil, err
}
token.Token = accessToken
token.EndingAt = expiredAt
token.RefreshToken = refreshToken
return s.repository.Update(token)
}

48
internal/services/user.go Normal file
View File

@ -0,0 +1,48 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type userService struct {
repository repositories.UserRepository
tokenRepository repositories.TokenRepository
}
type UserService interface {
List(string, int, int) (*[]models.User, error)
Total(string) (int64, error)
Find(int64) (*models.User, error)
FindByUsername(string) (*models.User, error)
Create(*models.User) (*models.User, error)
}
func NewUserService(repository repositories.UserRepository, tokenRepository repositories.TokenRepository) UserService {
return &userService{
repository: repository,
tokenRepository: tokenRepository,
}
}
func (s *userService) List(q string, page int, limit int) (*[]models.User, error) {
return s.repository.List(q, page, limit)
}
func (s *userService) Total(q string) (int64, error) {
return s.repository.Total(q)
}
func (s *userService) Find(id int64) (*models.User, error) {
return s.repository.Find(id)
}
func (s *userService) FindByUsername(username string) (*models.User, error) {
return s.repository.FindByUsername(username)
}
func (s *userService) Create(user *models.User) (*models.User, error) {
result, err := s.repository.Create(user)
return result, err
}

View File

@ -0,0 +1,94 @@
package services
import (
"fmt"
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type userQuizService struct {
repository repositories.UserQuizRepository
quizRepository repositories.QuizRepository
}
type UserQuizService interface {
List(int64, int, int) (*[]models.UserQuiz, error)
Total(int64) (int64, error)
Find(int64) (*models.UserQuiz, error)
Create(*models.UserQuiz) (*models.UserQuiz, error)
Insert([]models.UserQuiz) ([]models.UserQuiz, error)
Update(*models.UserQuiz) (*models.UserQuiz, error)
Delete(int64) error
Generate(int64, *models.UserQuizPaper) ([]models.UserQuiz, error)
}
func NewUserQuizService(repository repositories.UserQuizRepository, quizRepository repositories.QuizRepository) UserQuizService {
return &userQuizService{
repository: repository,
quizRepository: quizRepository,
}
}
func (s *userQuizService) List(user_quiz_paper_id int64, page int, limit int) (*[]models.UserQuiz, error) {
return s.repository.List(user_quiz_paper_id, page, limit)
}
func (s *userQuizService) Total(user_quiz_paper_id int64) (int64, error) {
return s.repository.Total(user_quiz_paper_id)
}
func (s *userQuizService) Find(id int64) (*models.UserQuiz, error) {
return s.repository.Find(id)
}
func (s *userQuizService) Create(quiz *models.UserQuiz) (*models.UserQuiz, error) {
result, err := s.repository.Create(quiz)
return result, err
}
func (s *userQuizService) Insert(items []models.UserQuiz) ([]models.UserQuiz, error) {
result, err := s.repository.Insert(items)
return result, err
}
func (s *userQuizService) Update(quiz *models.UserQuiz) (*models.UserQuiz, error) {
result, err := s.repository.Update(quiz)
return result, err
}
func (s *userQuizService) Delete(id int64) error {
err := s.repository.Delete(id)
return err
}
func (s *userQuizService) Generate(quiz_paper_id int64, userQuizPaper *models.UserQuizPaper) ([]models.UserQuiz, error) {
var userQuizzes []models.UserQuiz
quizzes, err := s.quizRepository.List(quiz_paper_id, 1, 1000)
if err != nil {
return nil, err
}
for _, quiz := range *quizzes {
userQuiz := models.UserQuiz{
GUID: quiz.GUID,
CenterID: quiz.CenterID,
UserQuizPaperID: userQuizPaper.ID,
UserID: userQuizPaper.UserID,
No: quiz.No,
QuestionType: quiz.QuestionType,
Question: quiz.Question,
Content: quiz.Content,
}
fmt.Println(userQuiz.Content)
// fmt.Println(userQuiz.Answer)
userQuizzes = append(userQuizzes, userQuiz)
}
return userQuizzes, nil
}

View File

@ -0,0 +1,83 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
"github.com/google/uuid"
)
type userQuizPaperService struct {
repository repositories.UserQuizPaperRepository
}
type UserQuizPaperService interface {
List(string, int, int) (*[]models.UserQuizPaper, error)
Total(string) (int64, error)
Find(int64) (*models.UserQuizPaper, error)
Create(*models.UserQuizPaper) (*models.UserQuizPaper, error)
Insert([]models.UserQuizPaper) ([]models.UserQuizPaper, error)
Update(*models.UserQuizPaper) (*models.UserQuizPaper, error)
Delete(string) error
Generate([]int64, *models.QuizPaper) []models.UserQuizPaper
}
func NewUserQuizPaperService(repository repositories.UserQuizPaperRepository) UserQuizPaperService {
return &userQuizPaperService{
repository: repository,
}
}
func (s *userQuizPaperService) List(q string, page int, limit int) (*[]models.UserQuizPaper, error) {
return s.repository.List(q, page, limit)
}
func (s *userQuizPaperService) Total(q string) (int64, error) {
return s.repository.Total(q)
}
func (s *userQuizPaperService) Find(id int64) (*models.UserQuizPaper, error) {
return s.repository.Find(id)
}
func (s *userQuizPaperService) Create(userQuizPaper *models.UserQuizPaper) (*models.UserQuizPaper, error) {
result, err := s.repository.Create(userQuizPaper)
return result, err
}
func (s *userQuizPaperService) Insert(items []models.UserQuizPaper) ([]models.UserQuizPaper, error) {
result, err := s.repository.Insert(items)
return result, err
}
func (s *userQuizPaperService) Update(userQuizPaper *models.UserQuizPaper) (*models.UserQuizPaper, error) {
result, err := s.repository.Update(userQuizPaper)
return result, err
}
func (s *userQuizPaperService) Delete(id string) error {
err := s.repository.Delete(id)
return err
}
func (s *userQuizPaperService) Generate(users []int64, quizPaper *models.QuizPaper) []models.UserQuizPaper {
var userQuizPapers []models.UserQuizPaper
for _, user_id := range users {
userQuizPaper := models.UserQuizPaper{
GUID: uuid.NewString(),
CenterID: quizPaper.CenterID,
UserID: user_id,
QuizPaperID: quizPaper.ID,
}
userQuizPapers = append(userQuizPapers, userQuizPaper)
}
return userQuizPapers
}