6
6
7
7
import { TeamDB } from "@gitpod/gitpod-db/lib" ;
8
8
import {
9
- BillingTier ,
10
- Team ,
11
- User ,
12
9
WorkspaceInstance ,
13
10
WorkspaceTimeoutDuration ,
14
11
WORKSPACE_TIMEOUT_DEFAULT_LONG ,
15
12
WORKSPACE_TIMEOUT_DEFAULT_SHORT ,
16
13
WORKSPACE_LIFETIME_LONG ,
17
14
WORKSPACE_LIFETIME_SHORT ,
15
+ User ,
16
+ BillingTier ,
17
+ Team ,
18
18
} from "@gitpod/gitpod-protocol" ;
19
19
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution" ;
20
20
import { inject , injectable } from "inversify" ;
@@ -38,11 +38,10 @@ export class EntitlementServiceUBP implements EntitlementService {
38
38
async mayStartWorkspace (
39
39
user : User ,
40
40
organizationId : string ,
41
- date : Date ,
42
41
runningInstances : Promise < WorkspaceInstance [ ] > ,
43
42
) : Promise < MayStartWorkspaceResult > {
44
43
const hasHitParallelWorkspaceLimit = async ( ) : Promise < HitParallelWorkspaceLimit | undefined > => {
45
- const max = await this . getMaxParallelWorkspaces ( user , date ) ;
44
+ const max = await this . getMaxParallelWorkspaces ( user . id , organizationId ) ;
46
45
const current = ( await runningInstances ) . filter ( ( i ) => i . status . phase !== "preparing" ) . length ;
47
46
if ( current >= max ) {
48
47
return {
@@ -54,7 +53,7 @@ export class EntitlementServiceUBP implements EntitlementService {
54
53
}
55
54
} ;
56
55
const [ usageLimitReachedOnCostCenter , hitParallelWorkspaceLimit ] = await Promise . all ( [
57
- this . checkUsageLimitReached ( user , organizationId , date ) ,
56
+ this . checkUsageLimitReached ( user . id , organizationId ) ,
58
57
hasHitParallelWorkspaceLimit ( ) ,
59
58
] ) ;
60
59
return {
@@ -63,69 +62,63 @@ export class EntitlementServiceUBP implements EntitlementService {
63
62
} ;
64
63
}
65
64
66
- private async checkUsageLimitReached (
67
- user : User ,
68
- organizationId : string ,
69
- date : Date ,
70
- ) : Promise < AttributionId | undefined > {
71
- const result = await this . usageService . checkUsageLimitReached ( user . id , organizationId ) ;
65
+ private async checkUsageLimitReached ( userId : string , organizationId : string ) : Promise < AttributionId | undefined > {
66
+ const result = await this . usageService . checkUsageLimitReached ( userId , organizationId ) ;
72
67
if ( result . reached ) {
73
68
return result . attributionId ;
74
69
}
75
70
return undefined ;
76
71
}
77
72
78
- private async getMaxParallelWorkspaces ( user : User , date : Date ) : Promise < number > {
79
- if ( await this . hasPaidSubscription ( user , date ) ) {
73
+ private async getMaxParallelWorkspaces ( userId : string , organizationId : string ) : Promise < number > {
74
+ if ( await this . hasPaidSubscription ( userId , organizationId ) ) {
80
75
return MAX_PARALLEL_WORKSPACES_PAID ;
81
76
} else {
82
77
return MAX_PARALLEL_WORKSPACES_FREE ;
83
78
}
84
79
}
85
80
86
- async maySetTimeout ( user : User , date : Date ) : Promise < boolean > {
87
- return this . hasPaidSubscription ( user , date ) ;
81
+ async maySetTimeout ( userId : string , organizationId ?: string ) : Promise < boolean > {
82
+ return this . hasPaidSubscription ( userId , organizationId ) ;
88
83
}
89
84
90
- async getDefaultWorkspaceTimeout ( user : User , date : Date ) : Promise < WorkspaceTimeoutDuration > {
91
- if ( await this . hasPaidSubscription ( user , date ) ) {
85
+ async getDefaultWorkspaceTimeout ( userId : string , organizationId : string ) : Promise < WorkspaceTimeoutDuration > {
86
+ if ( await this . hasPaidSubscription ( userId , organizationId ) ) {
92
87
return WORKSPACE_TIMEOUT_DEFAULT_LONG ;
93
88
} else {
94
89
return WORKSPACE_TIMEOUT_DEFAULT_SHORT ;
95
90
}
96
91
}
97
92
98
- async getDefaultWorkspaceLifetime ( user : User , date : Date ) : Promise < WorkspaceTimeoutDuration > {
99
- if ( await this . hasPaidSubscription ( user , date ) ) {
93
+ async getDefaultWorkspaceLifetime ( userId : string , organizationId : string ) : Promise < WorkspaceTimeoutDuration > {
94
+ if ( await this . hasPaidSubscription ( userId , organizationId ) ) {
100
95
return WORKSPACE_LIFETIME_LONG ;
101
96
} else {
102
97
return WORKSPACE_LIFETIME_SHORT ;
103
98
}
104
99
}
105
100
106
- /**
107
- * DEPRECATED: With usage-based billing, users can choose exactly how many resources they want to get.
108
- * Thus, we no longer need to "force" extra resources via the `userGetsMoreResources` mechanism.
109
- */
110
- async userGetsMoreResources ( user : User , date : Date = new Date ( ) ) : Promise < boolean > {
111
- return false ;
112
- }
113
-
114
101
/**
115
102
* Returns true if network connections should be limited
116
103
* @param user
117
104
*/
118
- async limitNetworkConnections ( user : User , date : Date ) : Promise < boolean > {
105
+ async limitNetworkConnections ( userId : string , organizationId : string ) : Promise < boolean > {
119
106
// gpl: Because with the current payment handling (pay-after-use) having a "paid" plan is not a good enough classifier for trushworthyness atm.
120
107
// We're looking into improving this, but for the meantime we limit network connections for everybody to reduce the impact of abuse.
121
108
return true ;
122
109
}
123
110
124
- private async hasPaidSubscription ( user : User , date : Date ) : Promise < boolean > {
111
+ private async hasPaidSubscription ( userId : string , organizationId ?: string ) : Promise < boolean > {
112
+ if ( organizationId ) {
113
+ // This is the "stricter", more correct version: We only allow privileges on the Organization that is paying for it
114
+ const { billingStrategy } = await this . usageService . getCostCenter ( userId , organizationId ) ;
115
+ return billingStrategy === CostCenter_BillingStrategy . BILLING_STRATEGY_STRIPE ;
116
+ }
117
+ // This is the old behavior, stemming from our transition to PAYF, where our API did-/doesn't pass organizationId, yet
125
118
// Member of paid team?
126
- const teams = await this . teamDB . findTeamsByUser ( user . id ) ;
119
+ const teams = await this . teamDB . findTeamsByUser ( userId ) ;
127
120
const isTeamSubscribedPromises = teams . map ( async ( team : Team ) => {
128
- const { billingStrategy } = await this . usageService . getCostCenter ( user . id , team . id ) ;
121
+ const { billingStrategy } = await this . usageService . getCostCenter ( userId , team . id ) ;
129
122
return billingStrategy === CostCenter_BillingStrategy . BILLING_STRATEGY_STRIPE ;
130
123
} ) ;
131
124
// Return the first truthy promise, or false if all the promises were falsy.
@@ -147,8 +140,8 @@ export class EntitlementServiceUBP implements EntitlementService {
147
140
} ) ;
148
141
}
149
142
150
- async getBillingTier ( user : User ) : Promise < BillingTier > {
151
- const hasPaidPlan = await this . hasPaidSubscription ( user , new Date ( ) ) ;
143
+ async getBillingTier ( userId : string , organizationId : string ) : Promise < BillingTier > {
144
+ const hasPaidPlan = await this . hasPaidSubscription ( userId , organizationId ) ;
152
145
return hasPaidPlan ? "paid" : "free" ;
153
146
}
154
147
}
0 commit comments