github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/model/instance/tos.go (about) 1 package instance 2 3 import ( 4 "strconv" 5 "strings" 6 "time" 7 ) 8 9 // BlockingReason structs holds a reason why an instance had been blocked 10 type BlockingReason struct { 11 Code string 12 Message string 13 } 14 15 var ( 16 // BlockedLoginFailed is used when a security issue has been detected on the instance 17 BlockedLoginFailed = BlockingReason{Code: "LOGIN_FAILED", Message: "Instance Blocked Login"} 18 // BlockedPaymentFailed is used when a payment is missing for the instance 19 BlockedPaymentFailed = BlockingReason{Code: "PAYMENT_FAILED", Message: "Instance Blocked Payment"} 20 // BlockedImporting is used when importing the data from another instance 21 BlockedImporting = BlockingReason{Code: "IMPORTING", Message: "Instance Blocked Importing"} 22 // BlockedMoving is used when moving data from another instance 23 BlockedMoving = BlockingReason{Code: "MOVING", Message: "Instance Blocked Moving"} 24 // BlockedUnknown is used when an instance is blocked but the reason is unknown 25 BlockedUnknown = BlockingReason{Code: "UNKNOWN", Message: "Instance Blocked Unknown"} 26 ) 27 28 // TOSDeadline represent the state for reaching the TOS deadline. 29 type TOSDeadline int 30 31 const ( 32 // TOSNone when no deadline is reached. 33 TOSNone TOSDeadline = iota 34 // TOSWarning when the warning deadline is reached, 2 weeks before the actual 35 // activation of the CGU. 36 TOSWarning 37 // TOSBlocked when the deadline is reached and the access should be blocked. 38 TOSBlocked 39 ) 40 41 // CheckInstanceBlocked returns whether or not the instance is currently in a 42 // blocked state: meaning it should be accessible. 43 func (i *Instance) CheckInstanceBlocked() bool { 44 return i.Blocked 45 } 46 47 // CheckTOSNotSigned checks whether or not the current Term of Services have 48 // been signed by the user. 49 func (i *Instance) CheckTOSNotSigned(args ...string) (notSigned bool) { 50 notSigned, _ = i.CheckTOSNotSignedAndDeadline(args...) 51 return 52 } 53 54 // CheckTOSNotSignedAndDeadline checks whether or not the current Term of 55 // Services have been signed by the user and returns the deadline state to 56 // perform this signature. 57 func (i *Instance) CheckTOSNotSignedAndDeadline(args ...string) (notSigned bool, deadline TOSDeadline) { 58 tosLatest := i.TOSLatest 59 if len(args) > 0 { 60 tosLatest = args[0] 61 } 62 latest, latestDate, ok := ParseTOSVersion(tosLatest) 63 if !ok || latestDate.IsZero() { 64 return 65 } 66 defer func() { 67 if notSigned { 68 now := time.Now() 69 if now.After(latestDate) { 70 deadline = TOSBlocked 71 } else if now.After(latestDate.Add(-30 * 24 * time.Hour)) { 72 deadline = TOSWarning 73 } else { 74 deadline = TOSNone 75 } 76 } 77 }() 78 signed, _, ok := ParseTOSVersion(i.TOSSigned) 79 if !ok { 80 notSigned = true 81 } else { 82 notSigned = signed < latest 83 } 84 return 85 } 86 87 // ParseTOSVersion returns the "major" and the date encoded in a version string 88 // with the following format: 89 // 90 // parseTOSVersion(A.B.C-YYYYMMDD) -> (A, YYYY, true) 91 func ParseTOSVersion(v string) (major int, date time.Time, ok bool) { 92 if v == "" { 93 return 94 } 95 if len(v) == 8 { 96 var err error 97 major = 1 98 date, err = time.Parse("20060102", v) 99 ok = err == nil 100 return 101 } 102 if v[0] == 'v' { 103 v = v[1:] 104 } 105 a := strings.SplitN(v, ".", 3) 106 if len(a) != 3 { 107 return 108 } 109 major, err := strconv.Atoi(a[0]) 110 if err != nil { 111 return 112 } 113 suffix := strings.SplitN(a[2], "-", 2) 114 if len(suffix) < 2 { 115 ok = true 116 return 117 } 118 date, err = time.Parse("20060102", suffix[1]) 119 ok = err == nil 120 return 121 }