diff --git a/.env b/.env index ec0c687..e0189b4 100644 --- a/.env +++ b/.env @@ -1,18 +1,18 @@ -# POSTGRES_DSN="postgres://sa:password@localhost:5432/postgres?sslmode=disable" -DB_HOST=localhost -DB_USERNAME=sa -DB_PASSWORD=password -DB_NAME=postgres -DB_PORT=5432 - -SATUDATA_HOST=10.10.123.165 -SATUDATA_USERNAME=stim -SATUDATA_PASSWORD=stim*RS54 -SATUDATA_NAME=satu_db -SATUDATA_PORT=5000 - -BASEURL_BPJS=https://apijkn-dev.bpjs-kesehatan.go.id/ -ANTREAN_RS=antreanrs_dev -CONS_ID=16041 -USER_KEY=04a742fc834e0d3dc5b18913c8d46b90 -SECRET_KEY=8pP3D5431E \ No newline at end of file +# POSTGRES_DSN="postgres://sa:password@localhost:5432/postgres?sslmode=disable" +DB_HOST=localhost +DB_USERNAME=sa +DB_PASSWORD=password +DB_NAME=postgres +DB_PORT=5432 + +SATUDATA_HOST=10.10.123.165 +SATUDATA_USERNAME=stim +SATUDATA_PASSWORD=stim*RS54 +SATUDATA_NAME=satu_db +SATUDATA_PORT=5000 + +BASEURL_BPJS=https://apijkn.bpjs-kesehatan.go.id/ +ANTREAN_RS=antreanrs +CONS_ID=5257 +USER_KEY=4cf1cbef8c008440bbe9ef9ba789e482 +SECRET_KEY=1bV363512D \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0c326ed..10f02a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,23 @@ -# ---> Go -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work - +# ---> Go +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + diff --git a/Dockerfile b/Dockerfile index 364802d..cf4a464 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,22 @@ -FROM golang:1.23-alpine AS builder - -WORKDIR /app - -COPY go.mod go.sum ./ - -RUN go mod tidy - -COPY . . - -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . -# RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . - -FROM alpine:latest -RUN apk --no-cache add ca-certificates - -WORKDIR /root/ - -COPY --from=builder /app/main . -COPY --from=builder /app/.env . -EXPOSE 8080 +FROM golang:1.23-alpine AS builder + +WORKDIR /app + +COPY go.mod go.sum ./ + +RUN go mod tidy + +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . +# RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . + +FROM alpine:latest +RUN apk --no-cache add ca-certificates + +WORKDIR /root/ + +COPY --from=builder /app/main . +COPY --from=builder /app/.env . +EXPOSE 8080 CMD ["./main"] \ No newline at end of file diff --git a/README.md b/README.md index ea2983e..7c876f7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# bridging-rssa - +# bridging-rssa + diff --git a/config/config.go b/config/config.go index 24c074f..b5e1e50 100644 --- a/config/config.go +++ b/config/config.go @@ -1,67 +1,76 @@ -package config - -import ( - "bridging-rssa/models/config" - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "fmt" - "log" - "os" - "time" - - "gorm.io/driver/postgres" - "gorm.io/gorm" -) - -var DB *gorm.DB -var SatuDataDB *gorm.DB -var err error - -func ConnectDB() { - hostSatuData := os.Getenv("SATUDATA_HOST") - userNameSatuData := os.Getenv("SATUDATA_USERNAME") - passwordSatuData := os.Getenv("SATUDATA_PASSWORD") - dbNameSatuData := os.Getenv("SATUDATA_NAME") - portSatuData := os.Getenv("SATUDATA_PORT") - - satuData := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", hostSatuData, userNameSatuData, passwordSatuData, dbNameSatuData, portSatuData) - - SatuDataDB, err = gorm.Open(postgres.Open(satuData), &gorm.Config{}) - if err != nil { - log.Fatal("Failed to connect to Satu Data database: ", err) - } else { - log.Println("Successfully connected to the database") - } -} - -func SetHeader(cfg config.ConfigBpjs) (string, string, string, string, string) { - - timenow := time.Now().UTC() - time := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC) - tstamp := timenow.Unix() - time.Unix() - - log.Println("TIMENOW: ", timenow) - log.Println("TIME UNIX", timenow.Unix()) - log.Println("T: ", time) - log.Println("T UNIX: ", time.Unix()) - - cfg.Cons_id = os.Getenv("CONS_ID") - cfg.User_key = os.Getenv("USER_KEY") - cfg.Secret_key = os.Getenv("SECRET_KEY") - - log.Println("TIMESTAMP:", tstamp) - - secret := []byte(cfg.Secret_key) - message := []byte(cfg.Cons_id + "&" + fmt.Sprint(tstamp)) - hash := hmac.New(sha256.New, secret) - hash.Write(message) - // to lowercase hexits - hex.EncodeToString(hash.Sum(nil)) - // to base64 - X_signature := base64.StdEncoding.EncodeToString(hash.Sum(nil)) - - return cfg.Cons_id, cfg.Secret_key, cfg.User_key, fmt.Sprint(tstamp), X_signature - -} +package config + +import ( + "bridging-rssa/models/config" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "log" + "os" + "time" + + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +var DB *gorm.DB +var localDB *gorm.DB +var SatuDataDB *gorm.DB +var err error + +func ConnectDB() { + hostDB := os.Getenv("DB_HOST") + usernameDB := os.Getenv("DB_USERNAME") + passwordDB := os.Getenv("DB_PASSWORD") + dbName := os.Getenv("DB_NAME") + portDB := os.Getenv("DB_PORT") + + hostSatuData := os.Getenv("SATUDATA_HOST") + userNameSatuData := os.Getenv("SATUDATA_USERNAME") + passwordSatuData := os.Getenv("SATUDATA_PASSWORD") + dbNameSatuData := os.Getenv("SATUDATA_NAME") + portSatuData := os.Getenv("SATUDATA_PORT") + + local := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", hostDB, usernameDB, passwordDB, dbName, portDB) + + satuData := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", hostSatuData, userNameSatuData, passwordSatuData, dbNameSatuData, portSatuData) + + localDB, err = gorm.Open(postgres.Open(local), &gorm.Config{}) + if err != nil { + log.Fatal("Failed to connect to Satu Data database: ", err) + } else { + log.Println("Successfully connected to the database") + } + + SatuDataDB, err = gorm.Open(postgres.Open(satuData), &gorm.Config{}) + if err != nil { + log.Fatal("Failed to connect to Satu Data database: ", err) + } else { + log.Println("Successfully connected to the database") + } +} + +func SetHeader(cfg config.ConfigBpjs) (string, string, string, string, string) { + + timenow := time.Now().UTC() + time := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC) + tstamp := timenow.Unix() - time.Unix() + + cfg.Cons_id = os.Getenv("CONS_ID") + cfg.User_key = os.Getenv("USER_KEY") + cfg.Secret_key = os.Getenv("SECRET_KEY") + + secret := []byte(cfg.Secret_key) + message := []byte(cfg.Cons_id + "&" + fmt.Sprint(tstamp)) + hash := hmac.New(sha256.New, secret) + hash.Write(message) + // to lowercase hexits + hex.EncodeToString(hash.Sum(nil)) + // to base64 + X_signature := base64.StdEncoding.EncodeToString(hash.Sum(nil)) + + return cfg.Cons_id, cfg.Secret_key, cfg.User_key, fmt.Sprint(tstamp), X_signature + +} diff --git a/database/database.go b/database/database.go deleted file mode 100644 index 20dd91a..0000000 --- a/database/database.go +++ /dev/null @@ -1,49 +0,0 @@ -package database - -import ( - "fmt" - "log" - "os" - - "gorm.io/driver/postgres" - "gorm.io/gorm" -) - -var DB *gorm.DB -var SatuDataDB *gorm.DB -var err error - -func ConnectDB() { - // host := os.Getenv("DB_HOST") - // userName := os.Getenv("DB_USERNAME") - // password := os.Getenv("DB_PASSWORD") - // dbName := os.Getenv("DB_NAME") - // port := os.Getenv("DB_PORT") - - hostSatuData := os.Getenv("SATUDATA_HOST") - userNameSatuData := os.Getenv("SATUDATA_USERNAME") - passwordSatuData := os.Getenv("SATUDATA_PASSWORD") - dbNameSatuData := os.Getenv("SATUDATA_NAME") - portSatuData := os.Getenv("SATUDATA_PORT") - - // dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", host, userName, password, dbName, port) - // if dsn == "" { - // log.Fatal("POSTGRES_DSN environment variable not set") - // } - - satuData := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", hostSatuData, userNameSatuData, passwordSatuData, dbNameSatuData, portSatuData) - - // DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) - // if err != nil { - // log.Fatal("Failed to connect to database: ", err) - // } else { - // log.Println("Successfully connected to the database") - // } - - SatuDataDB, err = gorm.Open(postgres.Open(satuData), &gorm.Config{}) - if err != nil { - log.Fatal("Failed to connect to Satu Data database: ", err) - } else { - log.Println("Successfully connected to the database") - } -} diff --git a/database/satu_data/dokter/jadwal_dokter.go b/database/satu_data/dokter/jadwal_dokter.go new file mode 100644 index 0000000..4d51d1c --- /dev/null +++ b/database/satu_data/dokter/jadwal_dokter.go @@ -0,0 +1,13 @@ +package dokter + +import "bridging-rssa/models/bpjs/jadwal_dokter" + +func InsertJadwalDokter(reqInsert *jadwal_dokter.JadwalDokterSatuData) (error) { + + return nil +} + +func UpdateJadwalDokter(reqInsert *jadwal_dokter.JadwalDokterSatuData) (error) { + + return nil +} \ No newline at end of file diff --git a/database/satu_data/dokter/spesialis.go b/database/satu_data/dokter/spesialis.go new file mode 100644 index 0000000..ba03896 --- /dev/null +++ b/database/satu_data/dokter/spesialis.go @@ -0,0 +1,27 @@ +package dokter + +import ( + "bridging-rssa/config" + "bridging-rssa/models/dokter" + "errors" + "log" + + "gorm.io/gorm" +) + +func GetSpesialis() (*[]dokter.DaftarSpesialis, error) { + var daftarSpesialis *[]dokter.DaftarSpesialis + + result := config.SatuDataDB.Debug().Raw(`select * from "daftar_spesialis"`).Find(&daftarSpesialis) + if result.Error != nil { + if !errors.Is(result.Error, gorm.ErrRecordNotFound) { + log.Fatalf("Error get data : %v", result.Error) + return nil, result.Error + } + log.Fatalf("Data kosong: %v", result.Error) + return daftarSpesialis, nil + } + + log.Print(&daftarSpesialis) + return daftarSpesialis, nil +} diff --git a/database/satu_data/dokter/subspesialis.go b/database/satu_data/dokter/subspesialis.go new file mode 100644 index 0000000..dec9751 --- /dev/null +++ b/database/satu_data/dokter/subspesialis.go @@ -0,0 +1,27 @@ +package dokter + +import ( + "bridging-rssa/config" + "bridging-rssa/models/dokter" + "errors" + "log" + + "gorm.io/gorm" +) + +func GetSubspesialis() (*[]dokter.DaftarSubspesialis, error) { + var daftarSubspesialis *[]dokter.DaftarSubspesialis + + result := config.SatuDataDB.Debug().Raw(`select * from "daftar_spesialis"`).Find(&daftarSubspesialis) + if result.Error != nil { + if !errors.Is(result.Error, gorm.ErrRecordNotFound) { + log.Fatalf("Error get data : %v", result.Error) + return nil, result.Error + } + log.Fatalf("Data kosong: %v", result.Error) + return daftarSubspesialis, nil + } + + log.Print(&daftarSubspesialis) + return daftarSubspesialis, nil +} diff --git a/docker-compose.yml b/docker-compose.yml index 43c3f7d..1f06cd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,25 +1,25 @@ -version: '3.8' -services: - app: - build: - context: . - dockerfile: Dockerfile - container_name: api-rssa - restart: always - ports: - - 8080:8080 - volumes: - - .:/app - environment: - # DATABASE SIMRS V3.0 - - DB_HOST=localhost - - DB_USERNAME=sa - - DB_PASSWORD=password - - DB_NAME=postgres - - DB_PORT=5432 - # DATABASE SATU DATA - - SATUDATA_HOST=10.10.123.165 - - SATUDATA_USERNAME=stim - - SATUDATA_PASSWORD=stim*RS54 - - SATUDATA_NAME=satu_db +version: '3.8' +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: api-rssa + restart: always + ports: + - 8080:8080 + volumes: + - .:/app + environment: + # DATABASE SIMRS V3.0 + - DB_HOST=localhost + - DB_USERNAME=sa + - DB_PASSWORD=password + - DB_NAME=postgres + - DB_PORT=5432 + # DATABASE SATU DATA + - SATUDATA_HOST=10.10.123.165 + - SATUDATA_USERNAME=stim + - SATUDATA_PASSWORD=stim*RS54 + - SATUDATA_NAME=satu_db - SATUDATA_PORT=5000 \ No newline at end of file diff --git a/docs/docs.go b/docs/docs.go index 91a293e..5220cf7 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,141 +1,141 @@ -// Package docs Code generated by swaggo/swag. DO NOT EDIT -package docs - -import "github.com/swaggo/swag" - -const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "contact": {}, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", - "paths": { - "/api/user": { - "get": { - "description": "returs list of all users from the database", - "tags": [ - "Users" - ], - "summary": "return list of all", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.User" - } - } - } - } - }, - "/api/user/create": { - "post": { - "description": "Insert Data User", - "tags": [ - "Users" - ], - "summary": "Insert Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, - "/api/user/delete/:id": { - "delete": { - "description": "Delete Data User", - "tags": [ - "Users" - ], - "summary": "Delete Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, - "/api/user/update/:id": { - "put": { - "description": "Update Data User", - "tags": [ - "Users" - ], - "summary": "Update Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - } - }, - "definitions": { - "models.Response": { - "type": "object", - "properties": { - "response_code": { - "type": "string" - }, - "response_message": { - "type": "string" - } - } - }, - "models.User": { - "type": "object", - "properties": { - "agama": { - "type": "string" - }, - "alamat": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jenis_kelamin": { - "type": "string" - }, - "nama": { - "type": "string" - }, - "umur": { - "type": "integer" - } - } - } - } -}` - -// SwaggerInfo holds exported Swagger Info so clients can modify it -var SwaggerInfo = &swag.Spec{ - Version: "1", - Host: "localhost:8080", - BasePath: "", - Schemes: []string{}, - Title: "Crud User", - Description: "Rest API CRUD User", - InfoInstanceName: "swagger", - SwaggerTemplate: docTemplate, - LeftDelim: "{{", - RightDelim: "}}", -} - -func init() { - swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) -} +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/api/user": { + "get": { + "description": "returs list of all users from the database", + "tags": [ + "Users" + ], + "summary": "return list of all", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/api/user/create": { + "post": { + "description": "Insert Data User", + "tags": [ + "Users" + ], + "summary": "Insert Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/user/delete/:id": { + "delete": { + "description": "Delete Data User", + "tags": [ + "Users" + ], + "summary": "Delete Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/user/update/:id": { + "put": { + "description": "Update Data User", + "tags": [ + "Users" + ], + "summary": "Update Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + } + }, + "definitions": { + "models.Response": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "response_message": { + "type": "string" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "agama": { + "type": "string" + }, + "alamat": { + "type": "string" + }, + "id": { + "type": "string" + }, + "jenis_kelamin": { + "type": "string" + }, + "nama": { + "type": "string" + }, + "umur": { + "type": "integer" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1", + Host: "localhost:8080", + BasePath: "", + Schemes: []string{}, + Title: "Crud User", + Description: "Rest API CRUD User", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/lz-string.go b/docs/lz-string.go index dc7ebf7..214f4bd 100644 --- a/docs/lz-string.go +++ b/docs/lz-string.go @@ -1,183 +1,46 @@ -package docs - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/sha256" - "encoding/base64" - "errors" - "math" - "unicode/utf8" -) - -// -// Decompress uri encoded lz-string -// http://pieroxy.net/blog/pages/lz-string/index.html -// https://github.com/pieroxy/lz-string/ -// - -// map of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$" -var keyStrUriSafe map[byte]int = map[byte]int{74: 9, 78: 13, 83: 18, 36: 64, 109: 38, 114: 43, 116: 45, 101: 30, 45: 63, 73: 8, 81: 16, 113: 42, 49: 53, 50: 54, 54: 58, 76: 11, 100: 29, 107: 36, 121: 50, 77: 12, 89: 24, 105: 34, 66: 1, 69: 4, 85: 20, 48: 52, 119: 48, 117: 46, 120: 49, 52: 56, 56: 60, 110: 39, 112: 41, 70: 5, 71: 6, 79: 14, 88: 23, 97: 26, 102: 31, 103: 32, 67: 2, 118: 47, 65: 0, 68: 3, 72: 7, 108: 37, 51: 55, 57: 61, 82: 17, 90: 25, 98: 27, 115: 44, 122: 51, 53: 57, 86: 21, 106: 35, 111: 40, 55: 59, 43: 62, 75: 10, 80: 15, 84: 19, 87: 22, 99: 28, 104: 33} - -type dataStruct struct { - input string - val int - position int - index int - dictionary []string - enlargeIn float64 - numBits int -} - -func getBaseValue(char byte) int { - return keyStrUriSafe[char] -} - -// Input is composed of ASCII characters, so accessing it by array has no UTF-8 pb. -func readBits(nb int, data *dataStruct) int { - result := 0 - power := 1 - for i := 0; i < nb; i++ { - respB := data.val & data.position - data.position = data.position / 2 - if data.position == 0 { - data.position = 32 - data.val = getBaseValue(data.input[data.index]) - data.index += 1 - } - if respB > 0 { - result |= power - } - power *= 2 - } - return result -} - -func appendValue(data *dataStruct, str string) { - data.dictionary = append(data.dictionary, str) - data.enlargeIn -= 1 - if data.enlargeIn == 0 { - data.enlargeIn = math.Pow(2, float64(data.numBits)) - data.numBits += 1 - } -} - -func getString(last string, data *dataStruct) (string, bool, error) { - c := readBits(data.numBits, data) - switch c { - case 0: - str := string(readBits(8, data)) - appendValue(data, str) - return str, false, nil - case 1: - str := string(readBits(16, data)) - appendValue(data, str) - return str, false, nil - case 2: - return "", true, nil - } - if c < len(data.dictionary) { - return data.dictionary[c], false, nil - } - if c == len(data.dictionary) { - return concatWithFirstRune(last, last), false, nil - } - return "", false, errors.New("Bad character encoding.") -} - -// Need to handle UTF-8, so we need to use rune to concatenate -func concatWithFirstRune(str string, getFirstRune string) string { - r, _ := utf8.DecodeRuneInString(getFirstRune) - return str + string(r) -} - -func DecompressFromEncodedUriComponent(input string) (string, error) { - data := dataStruct{input, getBaseValue(input[0]), 32, 1, []string{"0", "1", "2"}, 5, 2} - - result, isEnd, err := getString("", &data) - if err != nil || isEnd { - return result, err - } - last := result - data.numBits += 1 - for { - str, isEnd, err := getString(last, &data) - if err != nil || isEnd { - return result, err - } - - result = result + str - appendValue(&data, concatWithFirstRune(last, str)) - last = str - } - - return "", errors.New("Unexpected end of buffer reached.") -} - -func StringDecrypt(key string, str string) string { - // hash - keyHash := sha256.Sum256([]byte(key)) - - // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning - iv := keyHash[:16] - - // create a new aes cipher using the key and iv - block, err := aes.NewCipher(keyHash[:32]) - if err != nil { - panic(err) - } - - // decode the base64 string to a []byte - ciphertext, _ := base64.StdEncoding.DecodeString(str) - - // create the decrypter - decrypter := cipher.NewCBCDecrypter(block, iv) - - // decrypt - decrypted := make([]byte, len(ciphertext)) - decrypter.CryptBlocks(decrypted, ciphertext) - - // remove padding - padLen := int(decrypted[len(decrypted)-1]) - decrypted = decrypted[:len(decrypted)-padLen] - - return string(decrypted) -} - -func ResponseVclaim(encrypted string, key string) (string, error) { - - cipherText, err := base64.StdEncoding.DecodeString(encrypted) - if err != nil { - return "", err - } - - hash := sha256.Sum256([]byte(key)) - - block, err := aes.NewCipher(hash[:]) - if err != nil { - return "", err - } - - if len(cipherText) < aes.BlockSize { - return "", errors.New("cipherText too short") - } - - iv := hash[:aes.BlockSize] - - if len(cipherText)%aes.BlockSize != 0 { - return "", errors.New("cipherText is not a multiple of the block size") - } - - mode := cipher.NewCBCDecrypter(block, iv) - mode.CryptBlocks(cipherText, cipherText) - - // cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize) - cipherText, _ = Unpad(cipherText, aes.BlockSize) - // data, err := lzstring.DecompressFromEncodedURIComponent(string(cipherText)) - data, err := DecompressFromEncodedUriComponent(string(cipherText)) - if err != nil { - return "", err - } - - return data, nil -} +package docs + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + "encoding/base64" + "log" + + lzstring "github.com/daku10/go-lz-string" +) + +func StringDecrypt(key string, encryptedString string) (string, error) { + keyHash := sha256.Sum256([]byte(key)) + keyHashBytes := keyHash[:] + + iv := keyHashBytes[:16] + + encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedString) + if err != nil { + return "", err + } + + block, err := aes.NewCipher(keyHashBytes) + if err != nil { + return "", err + } + + mode := cipher.NewCBCDecrypter(block, iv) + + decrypted := make([]byte, len(encryptedBytes)) + mode.CryptBlocks(decrypted, encryptedBytes) + + decrypted = RemovePKCS7Padding(decrypted) + + dataResp, err := lzstring.DecompressFromEncodedURIComponent(string(decrypted)) + if err != nil { + log.Fatalf("Error decompress: %v", err) + } + return dataResp, nil +} + +func RemovePKCS7Padding(data []byte) []byte { + paddingLength := int(data[len(data)-1]) + return data[:len(data)-paddingLength] +} diff --git a/docs/pkcs7.go b/docs/pkcs7.go deleted file mode 100644 index 8277678..0000000 --- a/docs/pkcs7.go +++ /dev/null @@ -1,25 +0,0 @@ -package docs - -import "errors" - -func Pad(buf []byte, size int) ([]byte, error) { - bufLen := len(buf) - padLen := size - bufLen%size - padded := make([]byte, bufLen+padLen) - copy(padded, buf) - for i := 0; i < padLen; i++ { - padded[bufLen+i] = byte(padLen) - } - return padded, nil -} - -func Unpad(padded []byte, size int) ([]byte, error) { - if len(padded)%size != 0 { - return nil, errors.New("pkcs7: Padded value wasn't in correct size.") - } - - bufLen := len(padded) - int(padded[len(padded)-1]) - buf := make([]byte, bufLen) - copy(buf, padded[:bufLen]) - return buf, nil -} diff --git a/docs/swagger.json b/docs/swagger.json index cf25c11..0637ad1 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1,116 +1,116 @@ -{ - "swagger": "2.0", - "info": { - "description": "Rest API CRUD User", - "title": "Crud User", - "contact": {}, - "version": "1" - }, - "host": "localhost:8080", - "paths": { - "/api/user": { - "get": { - "description": "returs list of all users from the database", - "tags": [ - "Users" - ], - "summary": "return list of all", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.User" - } - } - } - } - }, - "/api/user/create": { - "post": { - "description": "Insert Data User", - "tags": [ - "Users" - ], - "summary": "Insert Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, - "/api/user/delete/:id": { - "delete": { - "description": "Delete Data User", - "tags": [ - "Users" - ], - "summary": "Delete Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, - "/api/user/update/:id": { - "put": { - "description": "Update Data User", - "tags": [ - "Users" - ], - "summary": "Update Data User", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - } - }, - "definitions": { - "models.Response": { - "type": "object", - "properties": { - "response_code": { - "type": "string" - }, - "response_message": { - "type": "string" - } - } - }, - "models.User": { - "type": "object", - "properties": { - "agama": { - "type": "string" - }, - "alamat": { - "type": "string" - }, - "id": { - "type": "string" - }, - "jenis_kelamin": { - "type": "string" - }, - "nama": { - "type": "string" - }, - "umur": { - "type": "integer" - } - } - } - } +{ + "swagger": "2.0", + "info": { + "description": "Rest API CRUD User", + "title": "Crud User", + "contact": {}, + "version": "1" + }, + "host": "localhost:8080", + "paths": { + "/api/user": { + "get": { + "description": "returs list of all users from the database", + "tags": [ + "Users" + ], + "summary": "return list of all", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/api/user/create": { + "post": { + "description": "Insert Data User", + "tags": [ + "Users" + ], + "summary": "Insert Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/user/delete/:id": { + "delete": { + "description": "Delete Data User", + "tags": [ + "Users" + ], + "summary": "Delete Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/api/user/update/:id": { + "put": { + "description": "Update Data User", + "tags": [ + "Users" + ], + "summary": "Update Data User", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + } + }, + "definitions": { + "models.Response": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "response_message": { + "type": "string" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "agama": { + "type": "string" + }, + "alamat": { + "type": "string" + }, + "id": { + "type": "string" + }, + "jenis_kelamin": { + "type": "string" + }, + "nama": { + "type": "string" + }, + "umur": { + "type": "integer" + } + } + } + } } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e736080..ef4b129 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,75 +1,75 @@ -definitions: - models.Response: - properties: - response_code: - type: string - response_message: - type: string - type: object - models.User: - properties: - agama: - type: string - alamat: - type: string - id: - type: string - jenis_kelamin: - type: string - nama: - type: string - umur: - type: integer - type: object -host: localhost:8080 -info: - contact: {} - description: Rest API CRUD User - title: Crud User - version: "1" -paths: - /api/user: - get: - description: returs list of all users from the database - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.User' - summary: return list of all - tags: - - Users - /api/user/create: - post: - description: Insert Data User - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Response' - summary: Insert Data User - tags: - - Users - /api/user/delete/:id: - delete: - description: Delete Data User - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Response' - summary: Delete Data User - tags: - - Users - /api/user/update/:id: - put: - description: Update Data User - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Response' - summary: Update Data User - tags: - - Users -swagger: "2.0" +definitions: + models.Response: + properties: + response_code: + type: string + response_message: + type: string + type: object + models.User: + properties: + agama: + type: string + alamat: + type: string + id: + type: string + jenis_kelamin: + type: string + nama: + type: string + umur: + type: integer + type: object +host: localhost:8080 +info: + contact: {} + description: Rest API CRUD User + title: Crud User + version: "1" +paths: + /api/user: + get: + description: returs list of all users from the database + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + summary: return list of all + tags: + - Users + /api/user/create: + post: + description: Insert Data User + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Response' + summary: Insert Data User + tags: + - Users + /api/user/delete/:id: + delete: + description: Delete Data User + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Response' + summary: Delete Data User + tags: + - Users + /api/user/update/:id: + put: + description: Update Data User + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Response' + summary: Update Data User + tags: + - Users +swagger: "2.0" diff --git a/go.mod b/go.mod index 357ade5..7e33643 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect diff --git a/go.sum b/go.sum index 34db0a0..4858eb9 100644 --- a/go.sum +++ b/go.sum @@ -80,6 +80,8 @@ github.com/mashingan/smapping v0.1.19 h1:SsEtuPn2UcM1croIupPtGLgWgpYRuS0rSQMvKD9 github.com/mashingan/smapping v0.1.19/go.mod h1:FjfiwFxGOuNxL/OT1WcrNAwTPx0YJeg5JiXwBB1nyig= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/handlers/bpjs/bpjs.go b/handlers/bpjs/bpjs.go deleted file mode 100644 index 1b94d6e..0000000 --- a/handlers/bpjs/bpjs.go +++ /dev/null @@ -1,55 +0,0 @@ -package bpjs - -import ( - "bridging-rssa/docs" - "bridging-rssa/models/jadwal_dokter" - "encoding/json" - "fmt" - "io" - "log" - "net/http" - - lzstring "github.com/daku10/go-lz-string" -) - -func BPJSGetResponse(url string, secretKey string, cons_id string, User_keys string, tstamp string, X_signature string, kdPoly string, tanggal string, headers map[string]string) (string, error) { - param := "/jadwaldokter/kodepoli/" + kdPoly + "/tanggal/" + tanggal - url += param - log.Println("URL", url) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - log.Fatalf("Error creating request: %v", err) - } - - for key, value := range headers { - req.Header.Set(key, value) - } - - log.Println("REQ", req.Header) - client := http.Client{} - response, err := client.Do(req) - if err != nil { - log.Fatalf("Error making external API request: %v", err) - } - log.Println("RESPONSE: ", response) - - key := cons_id + secretKey + tstamp - res, err := io.ReadAll(response.Body) - if err != nil { - fmt.Println(err) - } - - var jadwalDokter jadwal_dokter.JadwalDokter - err = json.Unmarshal([]byte(res), &jadwalDokter) - if err != nil { - log.Fatalf("Error Unmarshaling: %v", err) - } - log.Println("RESPONSE DATA", jadwalDokter.Response) - dataResp, err := lzstring.DecompressFromEncodedURIComponent((docs.StringDecrypt(key, jadwalDokter.Response))) - if err != nil { - log.Fatalf("Error Decrypt: %v", err) - } - log.Println("res: ", dataResp) - - return string(res), nil -} diff --git a/handlers/bpjs/jadwal_dokter/jadwal_dokter.go b/handlers/bpjs/jadwal_dokter/jadwal_dokter.go new file mode 100644 index 0000000..0ddf636 --- /dev/null +++ b/handlers/bpjs/jadwal_dokter/jadwal_dokter.go @@ -0,0 +1,64 @@ +package jadwal_dokter + +import ( + cfg "bridging-rssa/config" + "bridging-rssa/database/satu_data/dokter" + "bridging-rssa/models/bpjs/jadwal_dokter" + "bridging-rssa/models/config" + "log" + "net/http" + "os" + "time" + + "github.com/gin-gonic/gin" +) + +func GetJadwalDokter(c *gin.Context) { + baseUrl := os.Getenv("BASEURL_BPJS") + endpoint := os.Getenv("ANTREAN_RS") + url := baseUrl + endpoint + + // Select from daftar spesialis + spesialis, err := dokter.GetSpesialis() + if err != nil { + c.JSON(http.StatusInternalServerError, err) + } + + + + conf := config.ConfigBpjs{} + + cons_id, secretKey, User_key, tstamp, X_signature := cfg.SetHeader(conf) + + headers := map[string]string{ + "X-cons-id": cons_id, + "X-timestamp": tstamp, + "X-signature": X_signature, + "user_key": User_key, + } + var res *[]jadwal_dokter.ListDokter + log.Println("Headers : ", headers) + tanggal := time.Now().Format("2006-01-02") + for _, value := range *spesialis { + for i := 0; i < 7; i++ { + kdPoly := value.Kode + res, err = JadwalDokterGetResponse(url, secretKey, cons_id, User_key, tstamp, X_signature, kdPoly, tanggal, headers) + if err != nil { + log.Fatalf("Error making external API request: %v", err) + c.JSON(http.StatusInternalServerError, err) + } + + for _, key := range *res { + key.KodeDokter + } + + date, errParse := time.Parse("2006-01-02", tanggal) + if errParse != nil { + c.JSON(http.StatusInternalServerError, errParse) + } + tanggal = date.AddDate(0, 0, 1).Format("2006-01-02") + } + } + + c.JSON(http.StatusOK, res) +} diff --git a/handlers/bpjs/jadwal_dokter/response.go b/handlers/bpjs/jadwal_dokter/response.go new file mode 100644 index 0000000..66d029c --- /dev/null +++ b/handlers/bpjs/jadwal_dokter/response.go @@ -0,0 +1,66 @@ +package jadwal_dokter + +import ( + "bridging-rssa/docs" + "bridging-rssa/models/bpjs/jadwal_dokter" + "encoding/json" + "fmt" + "io" + "log" + "net/http" +) + +func JadwalDokterGetResponse(url string, secretKey string, cons_id string, User_keys string, tstamp string, X_signature string, kdPoly string, tanggal string, headers map[string]string) (*[]jadwal_dokter.ListDokter, error) { + param := "/jadwaldokter/kodepoli/" + kdPoly + "/tanggal/" + tanggal + url += param + log.Println("URL", url) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + log.Fatalf("Error creating request: %v", err) + } + + for key, value := range headers { + req.Header.Set(key, value) + } + + log.Println("REQ", req.Header) + client := http.Client{} + response, err := client.Do(req) + if err != nil { + log.Fatalf("Error making external API request: %v", err) + } + log.Println("RESPONSE: ", response) + + key := cons_id + secretKey + tstamp + res, err := io.ReadAll(response.Body) + if err != nil { + fmt.Println(err) + } + + var jadwalDokterRaw jadwal_dokter.JadwalDokterRaw + err = json.Unmarshal([]byte(res), &jadwalDokterRaw) + if err != nil { + log.Fatalf("Error Unmarshaling: %v", err) + } + + dataResp, err := docs.StringDecrypt(key, jadwalDokterRaw.Response) + if err != nil { + log.Fatalf("Error Decrypt: %v", err) + log.Println("res: ", dataResp) + + } + + var listDokter []jadwal_dokter.ListDokter + + log.Println("dataresp: ", dataResp) + + // err = mapstructure.Decode(dataResp, &listDokter) + err = json.Unmarshal([]byte(dataResp), &listDokter) + if err != nil { + log.Fatalf("Error Decode: %v", err) + } + + log.Println("res: ", &listDokter) + + return &listDokter, nil +} diff --git a/handlers/bpjs/subspesialis.go b/handlers/bpjs/subspesialis.go index 82dc877..f6454b5 100644 --- a/handlers/bpjs/subspesialis.go +++ b/handlers/bpjs/subspesialis.go @@ -1,24 +1,24 @@ -package bpjs - -import ( - "bridging-rssa/database" - "bridging-rssa/models/dokter" - "net/http" - - "github.com/gin-gonic/gin" - "gorm.io/gorm" -) - -func GetAllSubspesialis(c *gin.Context) { - var subspesialis []dokter.DaftarSubspesialis - result := database.SatuDataDB.Debug().Raw(`SELECT * FROM "daftar_subspesialis"`).Find(&subspesialis) - if result.Error != nil { - if result.Error == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, result.Error) - } else { - c.JSON(http.StatusInternalServerError, result.Error) - } - return - } - c.JSON(http.StatusOK, subspesialis) -} +package bpjs + +import ( + "bridging-rssa/config" + "bridging-rssa/models/dokter" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +func GetAllSubspesialis(c *gin.Context) { + var subspesialis []dokter.DaftarSubspesialis + result := config.SatuDataDB.Debug().Raw(`SELECT * FROM "daftar_subspesialis"`).Find(&subspesialis) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + c.JSON(http.StatusNotFound, result.Error) + } else { + c.JSON(http.StatusInternalServerError, result.Error) + } + return + } + c.JSON(http.StatusOK, subspesialis) +} diff --git a/handlers/handlers.go b/handlers/handlers.go deleted file mode 100644 index 4ffe7b4..0000000 --- a/handlers/handlers.go +++ /dev/null @@ -1,152 +0,0 @@ -package ginHandlers - -import ( - "bridging-rssa/database" - "bridging-rssa/models" - "encoding/json" - "net/http" - - "github.com/gin-gonic/gin" - "gorm.io/gorm" -) - -// GetAllUser returs list of all users from the database -// @Summary return list of all -// @Description returs list of all users from the database -// @Tags Users -// @Success 200 {object} models.User -// @Router /api/user [get] -func GetAllUser(c *gin.Context) { - var users []models.User - result := database.DB.Debug().Raw(`SELECT * FROM "user"`).Find(&users) - if result.Error != nil { - if result.Error == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, result.Error) - } else { - c.JSON(http.StatusInternalServerError, result.Error) - } - return - } - c.JSON(http.StatusOK, users) -} - -func GetUserId(c *gin.Context) { - id := c.Param("id") - - var user models.User - query := `select * from "user" where id = ?` - result := database.DB.Debug().Raw(query, id).Find(&user) - if result.Error != nil { - if result.Error == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, result.Error) - } else { - c.JSON(http.StatusInternalServerError, result.Error) - } - return - } - - c.JSON(http.StatusOK, user) -} - -// CreateUser Insert Data User -// @Summary Insert Data User -// @Description Insert Data User -// @Tags Users -// @Success 200 {object} models.Response -// @Router /api/user/create [post] -func CreateUser(c *gin.Context) { - var u models.InsertUser - err := json.NewDecoder(c.Request.Body).Decode(&u) - if err != nil { - c.JSON(http.StatusBadRequest, "Invalid request payload") - return - } - - insertData := &models.InsertUser{ - Nama: u.Nama, - Umur: u.Umur, - Alamat: u.Alamat, - Agama: u.Agama, - JenisKelamin: u.JenisKelamin, - } - queryInsert := `INSERT INTO "user" (nama, umur, alamat, agama, jenis_kelamin) VALUES (?, ?, ?, ?, ?)` - result := database.DB.Debug().Exec(queryInsert, insertData.Nama, insertData.Umur, insertData.Alamat, insertData.Agama, insertData.JenisKelamin) - if result.Error != nil { - c.JSON(http.StatusInternalServerError, result.Error) - return - } - - res := &models.Response{ - ResponseCode: "00", - ResponseMessage: "Berhasil Insert Data", - } - c.JSON(http.StatusOK, res) -} - -// CreateUser Update Data User -// @Summary Update Data User -// @Description Update Data User -// @Tags Users -// @Success 200 {object} models.Response -// @Router /api/user/update/:id [put] -func UpdateUser(c *gin.Context) { - id := c.Param("id") - - var u models.UpdateUser - err := json.NewDecoder(c.Request.Body).Decode(&u) - if err != nil { - c.JSON(http.StatusBadRequest, "Invalid request payload") - return - } - - update := &models.UpdateUser{ - Nama: u.Nama, - Umur: u.Umur, - Alamat: u.Alamat, - Agama: u.Agama, - JenisKelamin: u.JenisKelamin, - } - res := &models.Response{ - ResponseCode: "00", - ResponseMessage: "Berhasil Update Data", - } - result := database.DB.Debug().Exec(`UPDATE "user" SET nama = ?, umur = ?, alamat = ?, agama = ?, jenis_kelamin = ? WHERE ID = ?`, update.Nama, update.Umur, update.Alamat, update.Agama, update.JenisKelamin, id) - if result.RowsAffected == 0 { - res = &models.Response{ - ResponseCode: "99", - ResponseMessage: "Gagal update data", - } - } else if result.Error != nil { - c.JSON(http.StatusInternalServerError, result.Error) - return - } - - c.JSON(http.StatusOK, res) -} - -// CreateUser Delete Data User -// @Summary Delete Data User -// @Description Delete Data User -// @Tags Users -// @Success 200 {object} models.Response -// @Router /api/user/delete/:id [delete] -func DeleteUser(c *gin.Context) { - id := c.Param("id") - - res := &models.Response{ - ResponseCode: "00", - ResponseMessage: "Berhasil Delete Data", - } - result := database.DB.Debug().Exec(`DELETE from "user" where id = ?`, id) - if result.RowsAffected == 0 { - res = &models.Response{ - ResponseCode: "99", - ResponseMessage: "Gagal delete data", - } - } else if result.Error != nil { - c.JSON(http.StatusInternalServerError, result.Error) - return - } - - c.JSON(http.StatusOK, res) -} diff --git a/handlers/jadwal_dokter/jadwal_dokter.go b/handlers/jadwal_dokter/jadwal_dokter.go deleted file mode 100644 index 0d5d321..0000000 --- a/handlers/jadwal_dokter/jadwal_dokter.go +++ /dev/null @@ -1,40 +0,0 @@ -package jadwal_dokter - -import ( - cfg "bridging-rssa/config" - "bridging-rssa/handlers/bpjs" - "bridging-rssa/models/config" - "fmt" - "log" - "net/http" - "os" - - "github.com/gin-gonic/gin" -) - -func GetJadwalDokter(c *gin.Context) { - fmt.Println("MASUK SINI KAH?") - baseUrl := os.Getenv("BASEURL_BPJS") - endpoint := os.Getenv("ANTREAN_RS") - url := baseUrl + endpoint - kdPoly := c.Param("kdpoly") - tanggal := c.Param("tanggal") - - conf := config.ConfigBpjs{} - - cons_id, _, User_key, tstamp, X_signature := cfg.SetHeader(conf) - - headers := map[string]string{ - "X-cons-id": cons_id, - "X-timestamp": tstamp, - "X-signature": X_signature, - "user_key": User_key, - } - log.Println("Headers : ", headers) - - res, err := bpjs.BPJSGetResponse(url, conf.Secret_key, cons_id, User_key, tstamp, X_signature, kdPoly, tanggal, headers) - if err != nil { - log.Fatalf("Error making external API request: %v", err) - } - c.JSON(http.StatusOK, res) -} diff --git a/handlers/vClaim/Config.go b/handlers/vClaim/Config.go index 3ae356a..8958651 100644 --- a/handlers/vClaim/Config.go +++ b/handlers/vClaim/Config.go @@ -1,39 +1,39 @@ -package Vclaim - -import ( - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "fmt" - "log" - "time" -) - -type ConfigBpjs struct { - Cons_id string - Secret_key string - User_key string -} - -func SetHeader(cfg ConfigBpjs) (string, string, string, string, string) { - - timenow := time.Now().UTC() - t, err := time.Parse(time.RFC3339, "1970-01-01T00:00:00Z") - if err != nil { - log.Fatal(err) - } - - tstamp := timenow.Unix() - t.Unix() - secret := []byte(cfg.Secret_key) - message := []byte(cfg.Cons_id + "&" + fmt.Sprint(tstamp)) - hash := hmac.New(sha256.New, secret) - hash.Write(message) - // to lowercase hexits - hex.EncodeToString(hash.Sum(nil)) - // to base64 - X_signature := base64.StdEncoding.EncodeToString(hash.Sum(nil)) - - return cfg.Cons_id, cfg.Secret_key, cfg.User_key, fmt.Sprint(tstamp), X_signature - -} +package Vclaim + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "log" + "time" +) + +type ConfigBpjs struct { + Cons_id string + Secret_key string + User_key string +} + +func SetHeader(cfg ConfigBpjs) (string, string, string, string, string) { + + timenow := time.Now().UTC() + t, err := time.Parse(time.RFC3339, "1970-01-01T00:00:00Z") + if err != nil { + log.Fatal(err) + } + + tstamp := timenow.Unix() - t.Unix() + secret := []byte(cfg.Secret_key) + message := []byte(cfg.Cons_id + "&" + fmt.Sprint(tstamp)) + hash := hmac.New(sha256.New, secret) + hash.Write(message) + // to lowercase hexits + hex.EncodeToString(hash.Sum(nil)) + // to base64 + X_signature := base64.StdEncoding.EncodeToString(hash.Sum(nil)) + + return cfg.Cons_id, cfg.Secret_key, cfg.User_key, fmt.Sprint(tstamp), X_signature + +} diff --git a/handlers/vClaim/Response.go b/handlers/vClaim/Response.go index 3c215b6..9737ad3 100644 --- a/handlers/vClaim/Response.go +++ b/handlers/vClaim/Response.go @@ -1,50 +1,50 @@ -package Vclaim - -import ( - "bridging-rssa/docs" - "crypto/aes" - "crypto/cipher" - "crypto/sha256" - "encoding/base64" - "errors" - - lzstring "github.com/daku10/go-lz-string" -) - -func ResponseVclaim(encrypted string, key string) (string, error) { - - cipherText, err := base64.StdEncoding.DecodeString(encrypted) - if err != nil { - return "", err - } - - hash := sha256.Sum256([]byte(key)) - - block, err := aes.NewCipher(hash[:]) - if err != nil { - return "", err - } - - if len(cipherText) < aes.BlockSize { - return "", errors.New("cipherText too short") - } - - iv := hash[:aes.BlockSize] - - if len(cipherText)%aes.BlockSize != 0 { - return "", errors.New("cipherText is not a multiple of the block size") - } - - mode := cipher.NewCBCDecrypter(block, iv) - mode.CryptBlocks(cipherText, cipherText) - - // cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize) - cipherText, _ = docs.Unpad(cipherText, aes.BlockSize) - data, err := lzstring.DecompressFromEncodedURIComponent(string(cipherText)) - // data, err := helper.DecompressFromEncodedUriComponent(string(cipherText)) - if err != nil { - return "", err - } - - return data, nil -} +package Vclaim + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + "encoding/base64" + "errors" + "bridging-rssa/docs" + + lzstring "github.com/daku10/go-lz-string" +) + +func ResponseVclaim(encrypted string, key string) (string, error) { + + cipherText, err := base64.StdEncoding.DecodeString(encrypted) + if err != nil { + return "", err + } + + hash := sha256.Sum256([]byte(key)) + + block, err := aes.NewCipher(hash[:]) + if err != nil { + return "", err + } + + if len(cipherText) < aes.BlockSize { + return "", errors.New("cipherText too short") + } + + iv := hash[:aes.BlockSize] + + if len(cipherText)%aes.BlockSize != 0 { + return "", errors.New("cipherText is not a multiple of the block size") + } + + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(cipherText, cipherText) + + // cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize) + cipherText = docs.RemovePKCS7Padding(cipherText) + data, err := lzstring.DecompressFromEncodedURIComponent(string(cipherText)) + // data, err := helper.DecompressFromEncodedUriComponent(string(cipherText)) + if err != nil { + return "", err + } + + return data, nil +} diff --git a/handlers/vClaim/VclaimBridge.go b/handlers/vClaim/VclaimBridge.go index 45592fe..a3441c4 100644 --- a/handlers/vClaim/VclaimBridge.go +++ b/handlers/vClaim/VclaimBridge.go @@ -1,122 +1,122 @@ -package Vclaim - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - - "github.com/mashingan/smapping" -) - -type Respon_MentahDTO struct { - MetaData struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"metaData"` - Response string `json:"response"` -} - -type Respon_DTO struct { - MetaData struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"metaData"` - Response interface{} `json:"response"` -} - -func GetRequest(endpoint string, cfg interface{}) interface{} { - - conf := ConfigBpjs{} - - err := smapping.FillStruct(&conf, smapping.MapFields(&cfg)) - if err != nil { - log.Fatalf("Failed map %v: ", err) - } - - cons_id, Secret_key, User_key, tstamp, X_signature := SetHeader(conf) - - req, _ := http.NewRequest("GET", endpoint, nil) - - req.Header.Add("Content-Type", "Application/x-www-form-urlencoded") - req.Header.Add("X-cons-id", cons_id) - req.Header.Add("X-timestamp", tstamp) - req.Header.Add("X-signature", X_signature) - req.Header.Add("user_key", User_key) - - res, err := http.DefaultClient.Do(req) - - if err != nil { - fmt.Println(err) - } - - body, err := io.ReadAll(res.Body) - - if err != nil { - fmt.Println(err) - } - - var resp_mentah Respon_MentahDTO - var resp Respon_DTO - json.Unmarshal([]byte(body), &resp_mentah) - - resp_decrypt, _ := ResponseVclaim(string(resp_mentah.Response), string(cons_id+Secret_key+tstamp)) - resp.MetaData = resp_mentah.MetaData - json.Unmarshal([]byte(resp_decrypt), &resp.Response) - - return &resp -} - -func PostRequest(endpoint string, cfg interface{}, data interface{}) interface{} { - - conf := ConfigBpjs{} - - err := smapping.FillStruct(&conf, smapping.MapFields(&cfg)) - if err != nil { - log.Fatalf("Failed map %v: ", err) - } - - cons_id, Secret_key, User_key, tstamp, X_signature := SetHeader(conf) - - var buf bytes.Buffer - - err = json.NewEncoder(&buf).Encode(data) - - if err != nil { - log.Fatal(err) - } - - req, _ := http.NewRequest("POST", endpoint, &buf) - - req.Header.Add("Content-Type", "Application/x-www-form-urlencoded") - req.Header.Add("X-cons-id", cons_id) - req.Header.Add("X-timestamp", tstamp) - req.Header.Add("X-signature", X_signature) - req.Header.Add("user_key", User_key) - - res, err := http.DefaultClient.Do(req) - - if err != nil { - fmt.Println(err) - } - - body, err := ioutil.ReadAll(res.Body) - - if err != nil { - fmt.Println(err) - } - fmt.Println(string(body)) - var resp_mentah Respon_MentahDTO - var resp Respon_DTO - json.Unmarshal([]byte(body), &resp_mentah) - - resp_decrypt, _ := ResponseVclaim(string(resp_mentah.Response), string(cons_id+Secret_key+tstamp)) - resp.MetaData = resp_mentah.MetaData - json.Unmarshal([]byte(resp_decrypt), &resp.Response) - - return &resp - -} +package Vclaim + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + + "github.com/mashingan/smapping" +) + +type Respon_MentahDTO struct { + MetaData struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"metaData"` + Response string `json:"response"` +} + +type Respon_DTO struct { + MetaData struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"metaData"` + Response interface{} `json:"response"` +} + +func GetRequest(endpoint string, cfg interface{}) interface{} { + + conf := ConfigBpjs{} + + err := smapping.FillStruct(&conf, smapping.MapFields(&cfg)) + if err != nil { + log.Fatalf("Failed map %v: ", err) + } + + cons_id, Secret_key, User_key, tstamp, X_signature := SetHeader(conf) + + req, _ := http.NewRequest("GET", endpoint, nil) + + req.Header.Add("Content-Type", "Application/x-www-form-urlencoded") + req.Header.Add("X-cons-id", cons_id) + req.Header.Add("X-timestamp", tstamp) + req.Header.Add("X-signature", X_signature) + req.Header.Add("user_key", User_key) + + res, err := http.DefaultClient.Do(req) + + if err != nil { + fmt.Println(err) + } + + body, err := io.ReadAll(res.Body) + + if err != nil { + fmt.Println(err) + } + + var resp_mentah Respon_MentahDTO + var resp Respon_DTO + json.Unmarshal([]byte(body), &resp_mentah) + + resp_decrypt, _ := ResponseVclaim(string(resp_mentah.Response), string(cons_id+Secret_key+tstamp)) + resp.MetaData = resp_mentah.MetaData + json.Unmarshal([]byte(resp_decrypt), &resp.Response) + + return &resp +} + +func PostRequest(endpoint string, cfg interface{}, data interface{}) interface{} { + + conf := ConfigBpjs{} + + err := smapping.FillStruct(&conf, smapping.MapFields(&cfg)) + if err != nil { + log.Fatalf("Failed map %v: ", err) + } + + cons_id, Secret_key, User_key, tstamp, X_signature := SetHeader(conf) + + var buf bytes.Buffer + + err = json.NewEncoder(&buf).Encode(data) + + if err != nil { + log.Fatal(err) + } + + req, _ := http.NewRequest("POST", endpoint, &buf) + + req.Header.Add("Content-Type", "Application/x-www-form-urlencoded") + req.Header.Add("X-cons-id", cons_id) + req.Header.Add("X-timestamp", tstamp) + req.Header.Add("X-signature", X_signature) + req.Header.Add("user_key", User_key) + + res, err := http.DefaultClient.Do(req) + + if err != nil { + fmt.Println(err) + } + + body, err := ioutil.ReadAll(res.Body) + + if err != nil { + fmt.Println(err) + } + fmt.Println(string(body)) + var resp_mentah Respon_MentahDTO + var resp Respon_DTO + json.Unmarshal([]byte(body), &resp_mentah) + + resp_decrypt, _ := ResponseVclaim(string(resp_mentah.Response), string(cons_id+Secret_key+tstamp)) + resp.MetaData = resp_mentah.MetaData + json.Unmarshal([]byte(resp_decrypt), &resp.Response) + + return &resp + +} diff --git a/main.go b/main.go index 50279eb..856a9dd 100644 --- a/main.go +++ b/main.go @@ -1,64 +1,54 @@ -package main - -import ( - "bridging-rssa/config" - ginHandlers "bridging-rssa/handlers" - "bridging-rssa/handlers/bpjs" - "bridging-rssa/handlers/jadwal_dokter" - "log" - - _ "bridging-rssa/docs" - - "github.com/gin-gonic/gin" - "github.com/joho/godotenv" - swaggerFiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" -) - -// @title Crud User -// @version 1 -// @Description Rest API CRUD User - -// @host localhost:8080 - -func main() { - err := godotenv.Load() - if err != nil { - log.Fatal("Error loading .env file") - } - - config.ConnectDB() - - r := gin.Default() - - v1 := r.Group("/api") - - user := v1.Group("/user") - { - user.GET("/", ginHandlers.GetAllUser) - user.GET("/:id", ginHandlers.GetUserId) - user.POST("/create", ginHandlers.CreateUser) - user.PUT("/update/:id", ginHandlers.UpdateUser) - user.DELETE("/delete/:id", ginHandlers.DeleteUser) - } - - subspesialis := v1.Group("/subspesialis") - { - subspesialis.GET("/", bpjs.GetAllSubspesialis) - } - - jadwalDokter := v1.Group("/jadwaldokter") - { - jadwalDokter.GET("/kdpoly/:kdpoly/tanggal/:tanggal", jadwal_dokter.GetJadwalDokter) - } - - r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - r.POST("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - r.PUT("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - r.DELETE("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) - log.Println("JALAN DI PORT : 8081") - err = r.Run(":8081") - if err != nil { - log.Fatal(err) - } -} +package main + +import ( + "bridging-rssa/config" + "bridging-rssa/handlers/bpjs" + "bridging-rssa/handlers/bpjs/jadwal_dokter" + "log" + + _ "bridging-rssa/docs" + + "github.com/gin-gonic/gin" + "github.com/joho/godotenv" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" +) + +// @title Crud User +// @version 1 +// @Description Rest API CRUD User + +// @host localhost:8080 + +func main() { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + + config.ConnectDB() + + r := gin.Default() + + v1 := r.Group("/api") + + subspesialis := v1.Group("/subspesialis") + { + subspesialis.GET("/", bpjs.GetAllSubspesialis) + } + + jadwalDokter := v1.Group("/jadwaldokter") + { + jadwalDokter.GET("/kdpoly/:kdpoly/tanggal/:tanggal", jadwal_dokter.GetJadwalDokter) + } + + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + r.POST("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + r.PUT("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + r.DELETE("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + log.Println("JALAN DI PORT : 8081") + err = r.Run(":8080") + if err != nil { + log.Fatal(err) + } +} diff --git a/models/jadwal_dokter/jadwal_dokter.go b/models/bpjs/jadwal_dokter/jadwal_dokter.go similarity index 58% rename from models/jadwal_dokter/jadwal_dokter.go rename to models/bpjs/jadwal_dokter/jadwal_dokter.go index 709e737..e6a16bb 100644 --- a/models/jadwal_dokter/jadwal_dokter.go +++ b/models/bpjs/jadwal_dokter/jadwal_dokter.go @@ -1,25 +1,41 @@ -package jadwal_dokter - -type JadwalDokter struct { - Response string `json:"response"` - MetaData Metadata `json:"metadata"` -} - -type Metadata struct { - Code int `json:"code"` - Message string `json:"message"` -} - -type ListDokter struct { - KodeSubspesialis string `json:"kodesubspesialis"` - Hari int `json:"hari"` - KapasitasPasien int `json:"kapasitaspasien"` - Libur int `json:"libur"` - NamaHari string `json:"namahari"` - Jadwal string `json:"jadwal"` - NamaSubspesialis string `json:"namasubspesialis"` - NamaDokter string `json:"namadokter"` - KodePoli string `json:"kodepoli"` - NamaPoli string `json:"namapoli"` - KodeDokter int `json:"kodedokter"` -} +package jadwal_dokter + +type JadwalDokterRaw struct { + Response string `json:"response"` + MetaData Metadata `json:"metadata"` +} + +type Metadata struct { + Code int `json:"code"` + Message string `json:"message"` +} + +type ListDokter struct { + KodeSubspesialis string `json:"kodesubspesialis"` + Hari int `json:"hari"` + KapasitasPasien int `json:"kapasitaspasien"` + Libur int `json:"libur"` + NamaHari string `json:"namahari"` + Jadwal string `json:"jadwal"` + NamaSubspesialis string `json:"namasubspesialis"` + NamaDokter string `json:"namadokter"` + KodePoli string `json:"kodepoli"` + NamaPoli string `json:"namapoli"` + KodeDokter int `json:"kodedokter"` +} + +type DaftarSpesialis struct { + ID int `json:"id"` + Kode string `json:"Kode"` + Spesialis string `json:"Spesialis"` +} + +type JadwalDokterSatuData struct { + ID int `json:"id"` + Hari int `json:"Hari"` + NamaHari string `json:"Nama_hari"` + Waktu string `json:"Waktu"` + Spesialis int `json:"Spesialis"` + SubSpesialis int `json:"Sub_spesialis"` + Status int `json:"Status"` +} \ No newline at end of file diff --git a/models/config/config.go b/models/config/config.go index ec19f66..c6e2f86 100644 --- a/models/config/config.go +++ b/models/config/config.go @@ -1,7 +1,7 @@ -package config - -type ConfigBpjs struct { - Cons_id string - Secret_key string - User_key string -} +package config + +type ConfigBpjs struct { + Cons_id string + Secret_key string + User_key string +} diff --git a/models/dokter/spesialis.go b/models/dokter/spesialis.go new file mode 100644 index 0000000..9ceaa3f --- /dev/null +++ b/models/dokter/spesialis.go @@ -0,0 +1,7 @@ +package dokter + +type DaftarSpesialis struct { + ID int `json:"id"` + Kode string `json:"Kode"` + Spesialis string `json:"Spesialis"` +} diff --git a/models/dokter/subspesialis.go b/models/dokter/subspesialis.go index b969250..1707bd8 100644 --- a/models/dokter/subspesialis.go +++ b/models/dokter/subspesialis.go @@ -1,8 +1,9 @@ -package dokter - -type DaftarSubspesialis struct { - ID int `json:"id"` - Kode string `json:"Kode"` - Subspesialis string `json:"Subspesialis"` - FKDaftarSpesialisID int `json:"FK_daftar_spesialis_ID" gorm:"column:FK_daftar_spesialis_ID"` -} +package dokter + +type DaftarSubspesialis struct { + ID int `json:"id"` + Kode string `json:"Kode"` + Subspesialis string `json:"Subspesialis"` + FKDaftarSpesialisID int `json:"FK_daftar_spesialis_ID" gorm:"column:FK_daftar_spesialis_ID"` +} + diff --git a/models/user.go b/models/user.go index 9e94231..f43d9b5 100644 --- a/models/user.go +++ b/models/user.go @@ -1,32 +1,32 @@ -package models - -type User struct { - ID string `json:"id"` - Nama string `json:"nama"` - Umur int `json:"umur"` - Alamat string `json:"alamat"` - Agama string `json:"agama"` - JenisKelamin string `json:"jenis_kelamin"` -} - -type UpdateUser struct { - ID string `json:"id"` - Nama string `json:"nama"` - Umur int `json:"umur"` - Alamat string `json:"alamat"` - Agama string `json:"agama"` - JenisKelamin string `json:"jenis_kelamin"` -} - -type InsertUser struct { - Nama string `json:"nama"` - Umur int `json:"umur"` - Alamat string `json:"alamat"` - Agama string `json:"agama"` - JenisKelamin string `json:"jenis_kelamin"` -} - -type Response struct { - ResponseCode string `json:"response_code"` - ResponseMessage string `json:"response_message"` -} +package models + +type User struct { + ID string `json:"id"` + Nama string `json:"nama"` + Umur int `json:"umur"` + Alamat string `json:"alamat"` + Agama string `json:"agama"` + JenisKelamin string `json:"jenis_kelamin"` +} + +type UpdateUser struct { + ID string `json:"id"` + Nama string `json:"nama"` + Umur int `json:"umur"` + Alamat string `json:"alamat"` + Agama string `json:"agama"` + JenisKelamin string `json:"jenis_kelamin"` +} + +type InsertUser struct { + Nama string `json:"nama"` + Umur int `json:"umur"` + Alamat string `json:"alamat"` + Agama string `json:"agama"` + JenisKelamin string `json:"jenis_kelamin"` +} + +type Response struct { + ResponseCode string `json:"response_code"` + ResponseMessage string `json:"response_message"` +}