From f0e1f8a19a26fe0d5c3b24c9e3144aecba9b8398 Mon Sep 17 00:00:00 2001 From: andig Date: Wed, 22 Feb 2023 13:58:59 +0100 Subject: [PATCH] Sponsors: warn when token is about to expire (#6319) --- api/proto/auth.proto | 3 ++ api/proto/pb/auth.pb.go | 65 +++++++++++++++++++++++------------- api/proto/pb/auth_grpc.pb.go | 4 +++ cmd/root.go | 3 ++ util/sponsor/auth.go | 6 +++- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/api/proto/auth.proto b/api/proto/auth.proto index 105a3b1a6..a0917dd26 100644 --- a/api/proto/auth.proto +++ b/api/proto/auth.proto @@ -2,6 +2,8 @@ syntax = "proto3"; // protoc proto/auth.proto --go_out=. --go-grpc_out=. +import "google/protobuf/timestamp.proto"; + option go_package = "proto/pb"; service Auth { @@ -15,4 +17,5 @@ message AuthRequest { message AuthReply { bool authorized = 1; string subject = 2; + google.protobuf.Timestamp expires_at = 3; } diff --git a/api/proto/pb/auth.pb.go b/api/proto/pb/auth.pb.go index da3fffb6f..d42e94008 100644 --- a/api/proto/pb/auth.pb.go +++ b/api/proto/pb/auth.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.15.8 +// protoc v3.21.12 // source: proto/auth.proto package pb @@ -9,6 +9,7 @@ package pb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -72,8 +73,9 @@ type AuthReply struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"` - Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"` + Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` } func (x *AuthReply) Reset() { @@ -122,22 +124,35 @@ func (x *AuthReply) GetSubject() string { return "" } +func (x *AuthReply) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + var File_proto_auth_proto protoreflect.FileDescriptor var file_proto_auth_proto_rawDesc = []byte{ 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x45, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x32, 0x32, - 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x0c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x80, 0x01, 0x0a, 0x09, 0x41, 0x75, 0x74, + 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x32, 0x32, 0x0a, 0x04, 0x41, + 0x75, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x12, 0x0c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, + 0x0a, 0x5a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -154,17 +169,19 @@ func file_proto_auth_proto_rawDescGZIP() []byte { var file_proto_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_proto_auth_proto_goTypes = []interface{}{ - (*AuthRequest)(nil), // 0: AuthRequest - (*AuthReply)(nil), // 1: AuthReply + (*AuthRequest)(nil), // 0: AuthRequest + (*AuthReply)(nil), // 1: AuthReply + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp } var file_proto_auth_proto_depIdxs = []int32{ - 0, // 0: Auth.IsAuthorized:input_type -> AuthRequest - 1, // 1: Auth.IsAuthorized:output_type -> AuthReply - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 2, // 0: AuthReply.expires_at:type_name -> google.protobuf.Timestamp + 0, // 1: Auth.IsAuthorized:input_type -> AuthRequest + 1, // 2: Auth.IsAuthorized:output_type -> AuthReply + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_proto_auth_proto_init() } diff --git a/api/proto/pb/auth_grpc.pb.go b/api/proto/pb/auth_grpc.pb.go index 92e6dabbe..9e6d264d1 100644 --- a/api/proto/pb/auth_grpc.pb.go +++ b/api/proto/pb/auth_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: proto/auth.proto package pb diff --git a/cmd/root.go b/cmd/root.go index 8daae4aab..191063d8f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -263,6 +263,9 @@ func runRoot(cmd *cobra.Command, args []string) { // expose sponsor to UI if sponsor.Subject != "" { valueChan <- util.Param{Key: "sponsor", Val: sponsor.Subject} + if validDuration := time.Until(sponsor.ExpiresAt); validDuration < 30*24*time.Hour { + valueChan <- util.Param{Key: "sponsorValid", Val: validDuration} + } } // allow web access for vehicles diff --git a/util/sponsor/auth.go b/util/sponsor/auth.go index 927360533..e7e9a08ef 100644 --- a/util/sponsor/auth.go +++ b/util/sponsor/auth.go @@ -12,7 +12,10 @@ import ( "google.golang.org/grpc/status" ) -var Subject, Token string +var ( + Subject, Token string + ExpiresAt time.Time +) func IsAuthorized() bool { return len(Subject) > 0 @@ -34,6 +37,7 @@ func ConfigureSponsorship(token string) error { res, err := client.IsAuthorized(ctx, &pb.AuthRequest{Token: token}) if err == nil && res.Authorized { Subject = res.Subject + ExpiresAt = res.ExpiresAt.AsTime() Token = token }