package client import ( "bytes" "compress/gzip" "context" "encoding/base64" "errors" "fmt" "io" "net/http" "strings" "time" "netisjwt/internal/jws" ) // PridobiInPreveriStatus poklice GET endpoint, preveri JWS in vrne status. func PridobiInPreveriStatus(ctx context.Context, targetURL string) (bool, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil) if err != nil { return false, err } resp, err := http.DefaultClient.Do(req) if err != nil { return false, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } rawToken, err := io.ReadAll(resp.Body) if err != nil { return false, err } token := strings.TrimSpace(string(rawToken)) claims, err := jws.PreveriZeton(token) if err != nil { return false, err } if err := jws.PreveriTrditve(claims, izdajateljIzURL(targetURL), time.Now()); err != nil { return false, err } values, err := dekodirajKodiranSeznam(claims.Status.EncodedList) if err != nil { return false, err } return preberiBit(values, claims.Status.Index) } // izdajateljIzURL vrne url brez zadnjega segmenta index. func izdajateljIzURL(url string) string { parts := strings.Split(url, "/") if len(parts) < 5 { return "" } return strings.Join(parts[:len(parts)-1], "/") } // dekodirajKodiranSeznam pretvori base64+gzip seznam v surove bajte. func dekodirajKodiranSeznam(encoded string) ([]byte, error) { compressed, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, err } reader, err := newGzipBralnik(compressed) if err != nil { return nil, err } defer reader.Close() return io.ReadAll(reader) } // preberiBit prebere en bit iz podanega bajtnega zaporedja. func preberiBit(data []byte, index int) (bool, error) { if index < 0 { return false, errors.New("index must be >= 0") } byteIdx := index / 8 if byteIdx >= len(data) { return false, errors.New("index is out of encoded list range") } mask := byte(1 << (index % 8)) return data[byteIdx]&mask != 0, nil } type gzipReader interface { io.Reader Close() error } // newGzipBralnik ustvari gzip reader iz podanih bajtov. func newGzipBralnik(input []byte) (gzipReader, error) { return gzip.NewReader(bytes.NewReader(input)) }