github.com/nats-io/jwt/v2@v2.5.6/revocation_list.go (about)

     1  /*
     2   * Copyright 2020 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package jwt
    17  
    18  import (
    19  	"time"
    20  )
    21  
    22  const All = "*"
    23  
    24  // RevocationList is used to store a mapping of public keys to unix timestamps
    25  type RevocationList map[string]int64
    26  type RevocationEntry struct {
    27  	PublicKey string
    28  	TimeStamp int64
    29  }
    30  
    31  // Revoke enters a revocation by publickey and timestamp into this export
    32  // If there is already a revocation for this public key that is newer, it is kept.
    33  func (r RevocationList) Revoke(pubKey string, timestamp time.Time) {
    34  	newTS := timestamp.Unix()
    35  	// cannot move a revocation into the future - only into the past
    36  	if ts, ok := r[pubKey]; ok && ts > newTS {
    37  		return
    38  	}
    39  	r[pubKey] = newTS
    40  }
    41  
    42  // MaybeCompact will compact the revocation list if jwt.All is found. Any
    43  // revocation that is covered by a jwt.All revocation will be deleted, thus
    44  // reducing the size of the JWT. Returns a slice of entries that were removed
    45  // during the process.
    46  func (r RevocationList) MaybeCompact() []RevocationEntry {
    47  	var deleted []RevocationEntry
    48  	ats, ok := r[All]
    49  	if ok {
    50  		for k, ts := range r {
    51  			if k != All && ats >= ts {
    52  				deleted = append(deleted, RevocationEntry{
    53  					PublicKey: k,
    54  					TimeStamp: ts,
    55  				})
    56  				delete(r, k)
    57  			}
    58  		}
    59  	}
    60  	return deleted
    61  }
    62  
    63  // ClearRevocation removes any revocation for the public key
    64  func (r RevocationList) ClearRevocation(pubKey string) {
    65  	delete(r, pubKey)
    66  }
    67  
    68  // IsRevoked checks if the public key is in the revoked list with a timestamp later than
    69  // the one passed in. Generally this method is called with an issue time but other time's can
    70  // be used for testing.
    71  func (r RevocationList) IsRevoked(pubKey string, timestamp time.Time) bool {
    72  	if r.allRevoked(timestamp) {
    73  		return true
    74  	}
    75  	ts, ok := r[pubKey]
    76  	return ok && ts >= timestamp.Unix()
    77  }
    78  
    79  // allRevoked returns true if All is set and the timestamp is later or same as the
    80  // one passed. This is called by IsRevoked.
    81  func (r RevocationList) allRevoked(timestamp time.Time) bool {
    82  	ts, ok := r[All]
    83  	return ok && ts >= timestamp.Unix()
    84  }