token.go raw

   1  package internal
   2  
   3  import (
   4  	"crypto/sha1"
   5  	"encoding/hex"
   6  	"fmt"
   7  	"io"
   8  	"time"
   9  )
  10  
  11  func authToken(userName, wapiPass string) string {
  12  	return sha1string(userName + sha1string(wapiPass) + czechHourString())
  13  }
  14  
  15  func sha1string(txt string) string {
  16  	h := sha1.New()
  17  	_, _ = io.WriteString(h, txt)
  18  
  19  	return hex.EncodeToString(h.Sum(nil))
  20  }
  21  
  22  func czechHourString() string {
  23  	return formatHour(czechHour())
  24  }
  25  
  26  func czechHour() int {
  27  	tryZones := []string{"Europe/Prague", "Europe/Paris", "CET"}
  28  
  29  	for _, zoneName := range tryZones {
  30  		loc, err := time.LoadLocation(zoneName)
  31  		if err == nil {
  32  			return time.Now().In(loc).Hour()
  33  		}
  34  	}
  35  
  36  	// hopefully this will never be used
  37  	// this is fallback for containers without tzdata installed
  38  	return utcToCet(time.Now().UTC()).Hour()
  39  }
  40  
  41  func utcToCet(utc time.Time) time.Time {
  42  	// https://en.wikipedia.org/wiki/Central_European_Time
  43  	// As of 2011, all member states of the European Union observe Summer Time (daylight saving time),
  44  	// from the last Sunday in March to the last Sunday in October.
  45  	// States within the CET area switch to Central European Summer Time (CEST -- UTC+02:00) for the summer.[1]
  46  	utcMonth := utc.Month()
  47  	if utcMonth < time.March || utcMonth > time.October {
  48  		return utc.Add(time.Hour)
  49  	}
  50  
  51  	if utcMonth > time.March && utcMonth < time.October {
  52  		return utc.Add(time.Hour * 2)
  53  	}
  54  
  55  	dayOff := 0
  56  
  57  	breaking := time.Date(utc.Year(), utcMonth+1, dayOff, 1, 0, 0, 0, time.UTC)
  58  	for breaking.Weekday() != time.Sunday {
  59  		dayOff--
  60  
  61  		breaking = time.Date(utc.Year(), utcMonth+1, dayOff, 1, 0, 0, 0, time.UTC)
  62  
  63  		if dayOff < -7 {
  64  			panic("safety exit to avoid infinite loop")
  65  		}
  66  	}
  67  
  68  	if (utcMonth == time.March && utc.Before(breaking)) || (utcMonth == time.October && utc.After(breaking)) {
  69  		return utc.Add(time.Hour)
  70  	}
  71  
  72  	return utc.Add(time.Hour * 2)
  73  }
  74  
  75  func formatHour(hour int) string {
  76  	return fmt.Sprintf("%02d", hour)
  77  }
  78