helpers.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright (c) 2016, 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  2. // This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
  3. package common
  4. import (
  5. "crypto/rand"
  6. "crypto/rsa"
  7. "crypto/x509"
  8. "encoding/pem"
  9. "fmt"
  10. "reflect"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. // String returns a pointer to the provided string
  16. func String(value string) *string {
  17. return &value
  18. }
  19. // Int returns a pointer to the provided int
  20. func Int(value int) *int {
  21. return &value
  22. }
  23. // Int64 returns a pointer to the provided int64
  24. func Int64(value int64) *int64 {
  25. return &value
  26. }
  27. // Uint returns a pointer to the provided uint
  28. func Uint(value uint) *uint {
  29. return &value
  30. }
  31. //Float32 returns a pointer to the provided float32
  32. func Float32(value float32) *float32 {
  33. return &value
  34. }
  35. //Float64 returns a pointer to the provided float64
  36. func Float64(value float64) *float64 {
  37. return &value
  38. }
  39. //Bool returns a pointer to the provided bool
  40. func Bool(value bool) *bool {
  41. return &value
  42. }
  43. //PointerString prints the values of pointers in a struct
  44. //Producing a human friendly string for an struct with pointers.
  45. //useful when debugging the values of a struct
  46. func PointerString(datastruct interface{}) (representation string) {
  47. val := reflect.ValueOf(datastruct)
  48. typ := reflect.TypeOf(datastruct)
  49. all := make([]string, 2)
  50. all = append(all, "{")
  51. for i := 0; i < typ.NumField(); i++ {
  52. sf := typ.Field(i)
  53. //unexported
  54. if sf.PkgPath != "" && !sf.Anonymous {
  55. continue
  56. }
  57. sv := val.Field(i)
  58. stringValue := ""
  59. if isNil(sv) {
  60. stringValue = fmt.Sprintf("%s=<nil>", sf.Name)
  61. } else {
  62. if sv.Type().Kind() == reflect.Ptr {
  63. sv = sv.Elem()
  64. }
  65. stringValue = fmt.Sprintf("%s=%v", sf.Name, sv)
  66. }
  67. all = append(all, stringValue)
  68. }
  69. all = append(all, "}")
  70. representation = strings.TrimSpace(strings.Join(all, " "))
  71. return
  72. }
  73. // SDKTime a struct that parses/renders to/from json using RFC339 date-time information
  74. type SDKTime struct {
  75. time.Time
  76. }
  77. // SDKDate a struct that parses/renders to/from json using only date information
  78. type SDKDate struct {
  79. //Date date information
  80. Date time.Time
  81. }
  82. func sdkTimeFromTime(t time.Time) SDKTime {
  83. return SDKTime{t}
  84. }
  85. func sdkDateFromTime(t time.Time) SDKDate {
  86. return SDKDate{Date: t}
  87. }
  88. func formatTime(t SDKTime) string {
  89. return t.Format(sdkTimeFormat)
  90. }
  91. func formatDate(t SDKDate) string {
  92. return t.Date.Format(sdkDateFormat)
  93. }
  94. func now() *SDKTime {
  95. t := SDKTime{time.Now()}
  96. return &t
  97. }
  98. var timeType = reflect.TypeOf(SDKTime{})
  99. var timeTypePtr = reflect.TypeOf(&SDKTime{})
  100. var sdkDateType = reflect.TypeOf(SDKDate{})
  101. var sdkDateTypePtr = reflect.TypeOf(&SDKDate{})
  102. //Formats for sdk supported time representations
  103. const sdkTimeFormat = time.RFC3339Nano
  104. const rfc1123OptionalLeadingDigitsInDay = "Mon, _2 Jan 2006 15:04:05 MST"
  105. const sdkDateFormat = "2006-01-02"
  106. func tryParsingTimeWithValidFormatsForHeaders(data []byte, headerName string) (t time.Time, err error) {
  107. header := strings.ToLower(headerName)
  108. switch header {
  109. case "lastmodified", "date":
  110. t, err = tryParsing(data, time.RFC3339Nano, time.RFC3339, time.RFC1123, rfc1123OptionalLeadingDigitsInDay, time.RFC850, time.ANSIC)
  111. return
  112. default: //By default we parse with RFC3339
  113. t, err = time.Parse(sdkTimeFormat, string(data))
  114. return
  115. }
  116. }
  117. func tryParsing(data []byte, layouts ...string) (tm time.Time, err error) {
  118. datestring := string(data)
  119. for _, l := range layouts {
  120. tm, err = time.Parse(l, datestring)
  121. if err == nil {
  122. return
  123. }
  124. }
  125. err = fmt.Errorf("Could not parse time: %s with formats: %s", datestring, layouts[:])
  126. return
  127. }
  128. // String returns string representation of SDKDate
  129. func (t *SDKDate) String() string {
  130. return t.Date.Format(sdkDateFormat)
  131. }
  132. // NewSDKDateFromString parses the dateString into SDKDate
  133. func NewSDKDateFromString(dateString string) (*SDKDate, error) {
  134. parsedTime, err := time.Parse(sdkDateFormat, dateString)
  135. if err != nil {
  136. return nil, err
  137. }
  138. return &SDKDate{Date: parsedTime}, nil
  139. }
  140. // UnmarshalJSON unmarshals from json
  141. func (t *SDKTime) UnmarshalJSON(data []byte) (e error) {
  142. s := string(data)
  143. if s == "null" {
  144. t.Time = time.Time{}
  145. } else {
  146. //Try parsing with RFC3339
  147. t.Time, e = time.Parse(`"`+sdkTimeFormat+`"`, string(data))
  148. }
  149. return
  150. }
  151. // MarshalJSON marshals to JSON
  152. func (t *SDKTime) MarshalJSON() (buff []byte, e error) {
  153. s := t.Format(sdkTimeFormat)
  154. buff = []byte(`"` + s + `"`)
  155. return
  156. }
  157. // UnmarshalJSON unmarshals from json
  158. func (t *SDKDate) UnmarshalJSON(data []byte) (e error) {
  159. if string(data) == `"null"` {
  160. t.Date = time.Time{}
  161. return
  162. }
  163. t.Date, e = tryParsing(data,
  164. strconv.Quote(sdkDateFormat),
  165. )
  166. return
  167. }
  168. // MarshalJSON marshals to JSON
  169. func (t *SDKDate) MarshalJSON() (buff []byte, e error) {
  170. s := t.Date.Format(sdkDateFormat)
  171. buff = []byte(strconv.Quote(s))
  172. return
  173. }
  174. // PrivateKeyFromBytes is a helper function that will produce a RSA private
  175. // key from bytes. This function is deprecated in favour of PrivateKeyFromBytesWithPassword
  176. // Deprecated
  177. func PrivateKeyFromBytes(pemData []byte, password *string) (key *rsa.PrivateKey, e error) {
  178. if password == nil {
  179. return PrivateKeyFromBytesWithPassword(pemData, nil)
  180. }
  181. return PrivateKeyFromBytesWithPassword(pemData, []byte(*password))
  182. }
  183. // PrivateKeyFromBytesWithPassword is a helper function that will produce a RSA private
  184. // key from bytes and a password.
  185. func PrivateKeyFromBytesWithPassword(pemData, password []byte) (key *rsa.PrivateKey, e error) {
  186. if pemBlock, _ := pem.Decode(pemData); pemBlock != nil {
  187. decrypted := pemBlock.Bytes
  188. if x509.IsEncryptedPEMBlock(pemBlock) {
  189. if password == nil {
  190. e = fmt.Errorf("private key password is required for encrypted private keys")
  191. return
  192. }
  193. if decrypted, e = x509.DecryptPEMBlock(pemBlock, password); e != nil {
  194. return
  195. }
  196. }
  197. key, e = parsePKCSPrivateKey(decrypted)
  198. } else {
  199. e = fmt.Errorf("PEM data was not found in buffer")
  200. return
  201. }
  202. return
  203. }
  204. // ParsePrivateKey using PKCS1 or PKCS8
  205. func parsePKCSPrivateKey(decryptedKey []byte) (*rsa.PrivateKey, error) {
  206. if key, err := x509.ParsePKCS1PrivateKey(decryptedKey); err == nil {
  207. return key, nil
  208. }
  209. if key, err := x509.ParsePKCS8PrivateKey(decryptedKey); err == nil {
  210. switch key := key.(type) {
  211. case *rsa.PrivateKey:
  212. return key, nil
  213. default:
  214. return nil, fmt.Errorf("unsupportesd private key type in PKCS8 wrapping")
  215. }
  216. }
  217. return nil, fmt.Errorf("failed to parse private key")
  218. }
  219. func generateRandUUID() (string, error) {
  220. b := make([]byte, 16)
  221. _, err := rand.Read(b)
  222. if err != nil {
  223. return "", err
  224. }
  225. uuid := fmt.Sprintf("%x%x%x%x%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
  226. return uuid, nil
  227. }
  228. func makeACopy(original []string) []string {
  229. tmp := make([]string, len(original))
  230. copy(tmp, original)
  231. return tmp
  232. }