| /*- |
| * Copyright 2016 Zbigniew Mandziejewicz |
| * Copyright 2016 Square, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package jwt |
| |
| import ( |
| "encoding/json" |
| "strconv" |
| "time" |
| ) |
| |
| // Claims represents public claim values (as specified in RFC 7519). |
| type Claims struct { |
| Issuer string `json:"iss,omitempty"` |
| Subject string `json:"sub,omitempty"` |
| Audience Audience `json:"aud,omitempty"` |
| Expiry NumericDate `json:"exp,omitempty"` |
| NotBefore NumericDate `json:"nbf,omitempty"` |
| IssuedAt NumericDate `json:"iat,omitempty"` |
| ID string `json:"jti,omitempty"` |
| } |
| |
| // NumericDate represents date and time as the number of seconds since the |
| // epoch, including leap seconds. Non-integer values can be represented |
| // in the serialized format, but we round to the nearest second. |
| type NumericDate int64 |
| |
| // NewNumericDate constructs NumericDate from time.Time value. |
| func NewNumericDate(t time.Time) NumericDate { |
| if t.IsZero() { |
| return NumericDate(0) |
| } |
| |
| // While RFC 7519 technically states that NumericDate values may be |
| // non-integer values, we don't bother serializing timestamps in |
| // claims with sub-second accurancy and just round to the nearest |
| // second instead. Not convined sub-second accuracy is useful here. |
| return NumericDate(t.Unix()) |
| } |
| |
| // MarshalJSON serializes the given NumericDate into its JSON representation. |
| func (n NumericDate) MarshalJSON() ([]byte, error) { |
| return []byte(strconv.FormatInt(int64(n), 10)), nil |
| } |
| |
| // UnmarshalJSON reads a date from its JSON representation. |
| func (n *NumericDate) UnmarshalJSON(b []byte) error { |
| s := string(b) |
| |
| f, err := strconv.ParseFloat(s, 64) |
| if err != nil { |
| return ErrUnmarshalNumericDate |
| } |
| |
| *n = NumericDate(f) |
| return nil |
| } |
| |
| // Time returns time.Time representation of NumericDate. |
| func (n NumericDate) Time() time.Time { |
| return time.Unix(int64(n), 0) |
| } |
| |
| // Audience represents the recipents that the token is intended for. |
| type Audience []string |
| |
| // UnmarshalJSON reads an audience from its JSON representation. |
| func (s *Audience) UnmarshalJSON(b []byte) error { |
| var v interface{} |
| if err := json.Unmarshal(b, &v); err != nil { |
| return err |
| } |
| |
| switch v := v.(type) { |
| case string: |
| *s = []string{v} |
| case []interface{}: |
| a := make([]string, len(v)) |
| for i, e := range v { |
| s, ok := e.(string) |
| if !ok { |
| return ErrUnmarshalAudience |
| } |
| a[i] = s |
| } |
| *s = a |
| default: |
| return ErrUnmarshalAudience |
| } |
| |
| return nil |
| } |
| |
| func (s Audience) Contains(v string) bool { |
| for _, a := range s { |
| if a == v { |
| return true |
| } |
| } |
| return false |
| } |