diff --git a/internal/bd/filmsrepo.go b/internal/bd/filmsrepo.go index 9b65348..dcc78f0 100644 --- a/internal/bd/filmsrepo.go +++ b/internal/bd/filmsrepo.go @@ -90,6 +90,29 @@ func (f *Filmsrepo) FindById(id string) (*model.Films, error) { return &buff, nil } +func (s *Filmsrepo) FindByIdArray(id []int) (*[]model.Siries, error) { + var buffs []model.Siries + var stringId []string + for _, i := range id { + stringId = append(stringId, strconv.Itoa(i)) + } + query := fmt.Sprint("SELECT id, Ru_title, PosterUrlPreview, Countries, Genres, Year FROM films WHERE Id = ANY($1)") + rows, err := s.db.db.Query(context.Background(), query, stringId) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + var buff model.Siries + err = rows.Scan(&buff.Id, &buff.Ru_title, &buff.PosterUrlPreview, &buff.Countries, &buff.Genres, &buff.Year) + if err != nil { + return nil, err + } + buffs = append(buffs, buff) + } + return &buffs, nil +} + func (f *Filmsrepo) FindByName(name string) (*[]model.Films, error) { var films []model.Films rows, err := f.db.db.Query(context.Background(), "SELECT id, Ru_title, year, posterurl, content_type FROM films WHERE ru_title LIKE $1;", "%"+name+"%") diff --git a/internal/bd/model/user.go b/internal/bd/model/user.go index db8231f..4160a02 100644 --- a/internal/bd/model/user.go +++ b/internal/bd/model/user.go @@ -16,3 +16,9 @@ type UserData struct { PermisionLVL int AccesToken string } + +type SaveItemUpdate struct { + Login string `json:"login"` + SaveItemFilms int `json:"SaveItemFilms"` + SaveItemSiries int `json:"SaveItemSiries"` +} diff --git a/internal/bd/siriesrepo.go b/internal/bd/siriesrepo.go index 3ac4d77..9dfc373 100644 --- a/internal/bd/siriesrepo.go +++ b/internal/bd/siriesrepo.go @@ -2,6 +2,7 @@ package bd import ( "context" + "fmt" "strconv" "git.ukamnya.ru/stulyaganov/RestApiv2/internal/bd/model" @@ -27,6 +28,29 @@ func (s *Siriesrepo) FindById(id string) (*model.Siries, error) { return &buff, nil } +func (s *Siriesrepo) FindByIdArray(id []int) (*[]model.Siries, error) { + var buffs []model.Siries + var stringId []string + for _, i := range id { + stringId = append(stringId, strconv.Itoa(i)) + } + query := fmt.Sprint("SELECT id, Ru_title, PosterUrlPreview, Countries, Genres, Year FROM siries WHERE Id = ANY($1)") + rows, err := s.db.db.Query(context.Background(), query, stringId) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + var buff model.Siries + err = rows.Scan(&buff.Id, &buff.Ru_title, &buff.PosterUrlPreview, &buff.Countries, &buff.Genres, &buff.Year) + if err != nil { + return nil, err + } + buffs = append(buffs, buff) + } + return &buffs, nil +} + func (s *Siriesrepo) Pagination(page string) (*[]model.Siries, error) { var buffs []model.Siries pages, _ := strconv.Atoi(page) diff --git a/internal/bd/userrepo.go b/internal/bd/userrepo.go index a44c183..7a9f3c6 100644 --- a/internal/bd/userrepo.go +++ b/internal/bd/userrepo.go @@ -20,6 +20,44 @@ func (u *Userrepo) Create(user *model.User) error { return nil } +func (u *Userrepo) AddSaveFilmsItem(userLogin string, films int) error { + sql := fmt.Sprint("UPDATE users SET SaveItemFilms = array_append(SaveItemFilms, $1) WHERE login = $2") + _, err := u.db.db.Exec(context.Background(), sql, films, userLogin) + if err != nil { + return err + } + return nil +} + +func (u *Userrepo) AddSaveSiriesItem(userLogin string, siries int) error { + sql := fmt.Sprint("UPDATE users SET SaveItemSiries = array_append(SaveItemSiries, $1) WHERE login = $2") + _, err := u.db.db.Exec(context.Background(), sql, siries, userLogin) + if err != nil { + return err + } + return nil +} + +func (u *Userrepo) GetSaveFilmsItem(userLogin string) ([]int, error) { + var films []int + sql := fmt.Sprint("SELECT SaveItemFilms FROM users WHERE login = $1") + err := u.db.db.QueryRow(context.Background(), sql, userLogin).Scan(&films) + if err != nil { + return nil, err + } + return films, err +} + +func (u *Userrepo) GetSaveSiriesItem(userLogin string) ([]int, error) { + var siries []int + sql := fmt.Sprint("SELECT SaveItemSiries FROM users WHERE login = $1") + err := u.db.db.QueryRow(context.Background(), sql, userLogin).Scan(&siries) + if err != nil { + return nil, err + } + return siries, err +} + func (u *Userrepo) FindById(id string) (*model.User, error) { var user model.User query := fmt.Sprintf("SELECT * FROM users WHERE Id = %s;", id) diff --git a/internal/restserver/filmhandle.go b/internal/restserver/filmhandle.go index 2946a42..86735cb 100644 --- a/internal/restserver/filmhandle.go +++ b/internal/restserver/filmhandle.go @@ -116,12 +116,24 @@ func (r *RestServer) HendleFindID() http.HandlerFunc { func (r *RestServer) HendlePagination() http.HandlerFunc { return func(w http.ResponseWriter, res *http.Request) { + var filmData resultstruct.Films id := mux.Vars(res)["page"] films, err := r.db.Films().Pagination(id) if err != nil { r.logger.Errorln(err) + w.WriteHeader(http.StatusBadRequest) + return } - jsondata, err := json.Marshal(films) + cout, err := r.db.Films().GetCountFilms() + if err != nil { + r.logger.Errorln(err) + filmData.Result = false + } else { + filmData.Result = true + filmData.Data = *films + filmData.LastPage = *cout/32 + 1 + } + jsondata, err := json.Marshal(filmData) if err != nil { r.logger.Errorln(err) } diff --git a/internal/restserver/middleware.go b/internal/restserver/middleware.go index fabe691..a436f14 100644 --- a/internal/restserver/middleware.go +++ b/internal/restserver/middleware.go @@ -1,6 +1,7 @@ package restserver import ( + "context" "io" "net/http" "os" @@ -27,8 +28,14 @@ func (r *RestServer) checkJwtAccess(next http.HandlerFunc) http.HandlerFunc { r.logger.Error(err) return } + payload, err := jwt.GetPayload(token[1], []byte(os.Getenv("JWT_SECRET_KEY_ACCESS"))) + if err != nil { + w.WriteHeader(http.StatusUnauthorized) + io.WriteString(w, `{"data":"Ошибка Авторизации"}`) + r.logger.Error(err) + } if chek { - next(w, res) + next(w, res.WithContext(context.WithValue(res.Context(), ContextKeyPayload, payload))) } else { w.WriteHeader(http.StatusUnauthorized) io.WriteString(w, `{"data":"Ошибка Авторизации"}`) diff --git a/internal/restserver/restserver.go b/internal/restserver/restserver.go index 98917d8..050d79a 100644 --- a/internal/restserver/restserver.go +++ b/internal/restserver/restserver.go @@ -10,10 +10,11 @@ import ( ) const ( - ContextKeyUser = iota - defaultPermLvl = 1 - writerPermLvl = 2 - adminPermLvl = 3 + ContextKeyUser = iota + defaultPermLvl = 1 + writerPermLvl = 2 + adminPermLvl = 3 + ContextKeyPayload = 4 ) type RestServer struct { diff --git a/internal/restserver/resultStruct/films.go b/internal/restserver/resultStruct/films.go index b71caee..6255e42 100644 --- a/internal/restserver/resultStruct/films.go +++ b/internal/restserver/resultStruct/films.go @@ -5,6 +5,5 @@ import "git.ukamnya.ru/stulyaganov/RestApiv2/internal/bd/model" type Films struct { Result bool Data []model.Films - Page int LastPage int } diff --git a/internal/restserver/resultStruct/siries.go b/internal/restserver/resultStruct/siries.go index 7c81f29..25220e8 100644 --- a/internal/restserver/resultStruct/siries.go +++ b/internal/restserver/resultStruct/siries.go @@ -5,6 +5,5 @@ import "git.ukamnya.ru/stulyaganov/RestApiv2/internal/bd/model" type Siries struct { Result bool Data []model.Siries - Page int LastPage int } diff --git a/internal/restserver/siriesheandle.go b/internal/restserver/siriesheandle.go index c1c8682..f08c2db 100644 --- a/internal/restserver/siriesheandle.go +++ b/internal/restserver/siriesheandle.go @@ -111,12 +111,24 @@ func (r *RestServer) HendleFindIDSiries() http.HandlerFunc { func (r *RestServer) HendlePaginationSiries() http.HandlerFunc { return func(w http.ResponseWriter, res *http.Request) { + var siriesData resultstruct.Siries id := mux.Vars(res)["page"] siries, err := r.db.Siries().Pagination(id) if err != nil { r.logger.Errorln(err) + w.WriteHeader(http.StatusBadRequest) + return } - jsondata, err := json.Marshal(siries) + cout, err := r.db.Siries().GetCountFilms() + if err != nil { + r.logger.Errorln(err) + siriesData.Result = false + } else { + siriesData.Result = true + siriesData.Data = *siries + siriesData.LastPage = *cout/32 + 1 + } + jsondata, err := json.Marshal(siriesData) if err != nil { r.logger.Errorln(err) } diff --git a/internal/restserver/userHendle.go b/internal/restserver/userHendle.go index 3d246df..a1e9472 100644 --- a/internal/restserver/userHendle.go +++ b/internal/restserver/userHendle.go @@ -8,6 +8,7 @@ import ( "git.ukamnya.ru/stulyaganov/RestApiv2/internal/bd/model" "git.ukamnya.ru/stulyaganov/RestApiv2/pkg/utils/password" + "github.com/golang-jwt/jwt/v5" ) func (r *RestServer) configureRouterUser() { @@ -15,6 +16,10 @@ func (r *RestServer) configureRouterUser() { r.router.HandleFunc("/api/login", r.chekUserLogin(r.HandleFuncLoginUser())).Methods("POST") r.router.HandleFunc("/api/logout", r.chekUserLogout(r.HandleFuncLogOutUser())).Methods("GET") r.router.HandleFunc("/api/refresh", r.checkUserRefresh(r.HandleFuncRefresh())).Methods("GET") + r.router.HandleFunc("/api/user/savefilm", r.checkJwtAccess(r.HandleFuncAddFilmItem())).Methods(http.MethodPost) + r.router.HandleFunc("/api/user/savesiries", r.checkJwtAccess(r.HandleFuncAddSiriesItem())).Methods(http.MethodPost) + r.router.HandleFunc("/api/user/siries", r.checkJwtAccess(r.HandleFuncGetSiriesItem())).Methods(http.MethodGet) + r.router.HandleFunc("/api/user/films", r.checkJwtAccess(r.HandleFuncGetFilmsItem())).Methods(http.MethodGet) } func (r *RestServer) HandleFuncRegUser() http.HandlerFunc { @@ -97,3 +102,87 @@ func (r *RestServer) HandleFuncRefresh() http.HandlerFunc { } } + +func (r *RestServer) HandleFuncAddFilmItem() http.HandlerFunc { + return func(w http.ResponseWriter, res *http.Request) { + payload := res.Context().Value(ContextKeyPayload).(jwt.MapClaims) + name, _ := payload["name"].(string) + data := make(map[string]int) + err := json.NewDecoder(res.Body).Decode(&data) + if err != nil { + r.logger.Error(err) + return + } + err = r.db.User().AddSaveFilmsItem(name, data["SaveItemFilms"]) + if err != nil { + r.logger.Error(err) + return + } + } +} + +func (r *RestServer) HandleFuncAddSiriesItem() http.HandlerFunc { + return func(w http.ResponseWriter, res *http.Request) { + payload := res.Context().Value(ContextKeyPayload).(jwt.MapClaims) + name, _ := payload["name"].(string) + data := make(map[string]int) + + err := json.NewDecoder(res.Body).Decode(&data) + if err != nil { + r.logger.Error(err) + return + } + err = r.db.User().AddSaveSiriesItem(name, data["SaveItemSiries"]) + if err != nil { + r.logger.Error(err) + return + } + } +} + +func (r *RestServer) HandleFuncGetSiriesItem() http.HandlerFunc { + return func(w http.ResponseWriter, res *http.Request) { + payload := res.Context().Value(ContextKeyPayload).(jwt.MapClaims) + name, _ := payload["name"].(string) + listItem, err := r.db.User().GetSaveSiriesItem(name) + if err != nil { + r.logger.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + data, err := r.db.Siries().FindByIdArray(listItem) + if err != nil { + r.logger.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + jsByte, err := json.Marshal(data) + if err != nil { + r.logger.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + io.WriteString(w, string(jsByte)) + } +} + +func (r *RestServer) HandleFuncGetFilmsItem() http.HandlerFunc { + return func(w http.ResponseWriter, res *http.Request) { + payload := res.Context().Value(ContextKeyPayload).(jwt.MapClaims) + name, _ := payload["name"].(string) + listItem, err := r.db.User().GetSaveFilmsItem(name) + if err != nil { + r.logger.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + data, err := r.db.Films().FindByIdArray(listItem) + if err != nil { + r.logger.Error(err) + w.WriteHeader(http.StatusBadRequest) + return + } + jsByte, _ := json.Marshal(data) + io.WriteString(w, string(jsByte)) + } +} diff --git a/migrates/20221213130458_films.up.sql b/migrates/20221213130458_films.up.sql index b9f65a9..503917c 100644 --- a/migrates/20221213130458_films.up.sql +++ b/migrates/20221213130458_films.up.sql @@ -32,9 +32,8 @@ CREATE TABLE users ( password TEXT NOT NULL, avatar_url TEXT, permisionLVL INTEGER NOT NULL, - SaveItem INTEGER Array, - LaterItem INTEGER Array, - WantItem INTEGER Array, + SaveItemFilms INTEGER Array, + SaveItemSiries INTEGER Array, PRIMARY KEY(id) ); diff --git a/pkg/utils/jwt/jwtCheck.go b/pkg/utils/jwt/jwtCheck.go index 7763a0b..fb42c90 100644 --- a/pkg/utils/jwt/jwtCheck.go +++ b/pkg/utils/jwt/jwtCheck.go @@ -22,3 +22,20 @@ func ValidateToken(tokenString string, secretKey []byte) (bool, error) { return false, nil } } + +func GetPayload(tokenString string, secretKey []byte) (jwt.MapClaims, error) { + token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + return secretKey, nil + }) + if err != nil { + return nil, err + } + if Claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return Claims, nil + } else { + return nil, nil + } +}