Skip to content

Commit a8d4d6b

Browse files
committed
Apply naming standards + changenote
1 parent 5cfa6e8 commit a8d4d6b

File tree

4 files changed

+29
-25
lines changed

4 files changed

+29
-25
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* Initial modeling for the Ruby Grape framework in `Grape.qll` have been added to detect API endpoints, parameters, and headers within Grape API classes.

ruby/ql/lib/codeql/ruby/frameworks/Grape.qll

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ module Grape {
2323
* A Grape API class which sits at the top of the class hierarchy.
2424
* In other words, it does not subclass any other Grape API class in source code.
2525
*/
26-
class RootAPI extends GrapeAPIClass {
27-
RootAPI() {
28-
not exists(GrapeAPIClass parent | this != parent and this = parent.getADescendent())
26+
class RootApi extends GrapeApiClass {
27+
RootApi() {
28+
not exists(GrapeApiClass parent | this != parent and this = parent.getADescendent())
2929
}
3030
}
3131
}
@@ -43,17 +43,17 @@ module Grape {
4343
* end
4444
* ```
4545
*/
46-
class GrapeAPIClass extends DataFlow::ClassNode {
47-
GrapeAPIClass() {
48-
this = grapeAPIBaseClass().getADescendentModule() and
49-
not exists(DataFlow::ModuleNode m | m = grapeAPIBaseClass().asModule() | this = m)
46+
class GrapeApiClass extends DataFlow::ClassNode {
47+
GrapeApiClass() {
48+
this = grapeApiBaseClass().getADescendentModule() and
49+
not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m)
5050
}
5151

5252
/**
5353
* Gets a `GrapeEndpoint` defined in this class.
5454
*/
5555
GrapeEndpoint getAnEndpoint() {
56-
result.getAPIClass() = this
56+
result.getApiClass() = this
5757
}
5858

5959
/**
@@ -68,19 +68,19 @@ class GrapeAPIClass extends DataFlow::ClassNode {
6868
}
6969
}
7070

71-
private DataFlow::ConstRef grapeAPIBaseClass() {
71+
private DataFlow::ConstRef grapeApiBaseClass() {
7272
result = DataFlow::getConstant("Grape").getConstant("API")
7373
}
7474

75-
private API::Node grapeAPIInstance() {
76-
result = any(GrapeAPIClass cls).getSelf().track()
75+
private API::Node grapeApiInstance() {
76+
result = any(GrapeApiClass cls).getSelf().track()
7777
}
7878

7979
/**
8080
* A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class.
8181
*/
8282
class GrapeEndpoint extends DataFlow::CallNode {
83-
private GrapeAPIClass apiClass;
83+
private GrapeApiClass apiClass;
8484

8585
GrapeEndpoint() {
8686
this = apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"])
@@ -96,7 +96,7 @@ class GrapeEndpoint extends DataFlow::CallNode {
9696
/**
9797
* Gets the API class containing this endpoint.
9898
*/
99-
GrapeAPIClass getAPIClass() { result = apiClass }
99+
GrapeApiClass getApiClass() { result = apiClass }
100100

101101
/**
102102
* Gets the block containing the endpoint logic.
@@ -131,7 +131,7 @@ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range {
131131
private class GrapeParamsCall extends ParamsCallImpl {
132132
GrapeParamsCall() {
133133
// Simplified approach: find params calls that are descendants of Grape API class methods
134-
exists(GrapeAPIClass api |
134+
exists(GrapeApiClass api |
135135
this.getMethodName() = "params" and
136136
this.getParent+() = api.getADeclaration()
137137
)
@@ -163,7 +163,7 @@ private class GrapeHeadersCall extends MethodCall {
163163
)
164164
or
165165
// Also handle cases where headers is called on an instance of a Grape API class
166-
this = grapeAPIInstance().getAMethodCall("headers").asExpr().getExpr()
166+
this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr()
167167
}
168168
}
169169

@@ -206,7 +206,7 @@ private class GrapeRequestCall extends MethodCall {
206206
)
207207
or
208208
// Also handle cases where request is called on an instance of a Grape API class
209-
this = grapeAPIInstance().getAMethodCall("request").asExpr().getExpr()
209+
this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr()
210210
}
211211
}
212212

@@ -221,7 +221,7 @@ private class GrapeRouteParamCall extends MethodCall {
221221
)
222222
or
223223
// Also handle cases where route_param is called on an instance of a Grape API class
224-
this = grapeAPIInstance().getAMethodCall("route_param").asExpr().getExpr()
224+
this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr()
225225
}
226226
}
227227

@@ -231,7 +231,7 @@ private class GrapeRouteParamCall extends MethodCall {
231231
*/
232232
private class GrapeHeadersBlockCall extends MethodCall {
233233
GrapeHeadersBlockCall() {
234-
exists(GrapeAPIClass api |
234+
exists(GrapeApiClass api |
235235
this.getParent+() = api.getADeclaration() and
236236
this.getMethodName() = "headers" and
237237
exists(this.getBlock())
@@ -245,7 +245,7 @@ private class GrapeHeadersBlockCall extends MethodCall {
245245
*/
246246
private class GrapeCookiesBlockCall extends MethodCall {
247247
GrapeCookiesBlockCall() {
248-
exists(GrapeAPIClass api |
248+
exists(GrapeApiClass api |
249249
this.getParent+() = api.getADeclaration() and
250250
this.getMethodName() = "cookies" and
251251
exists(this.getBlock())
@@ -280,7 +280,7 @@ private class GrapeCookiesCall extends MethodCall {
280280
)
281281
or
282282
// Also handle cases where cookies is called on an instance of a Grape API class
283-
this = grapeAPIInstance().getAMethodCall("cookies").asExpr().getExpr()
283+
this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr()
284284
}
285285
}
286286

@@ -289,7 +289,7 @@ private class GrapeCookiesCall extends MethodCall {
289289
* These methods become available in endpoint contexts through Grape's DSL.
290290
*/
291291
private class GrapeHelperMethod extends Method {
292-
private GrapeAPIClass apiClass;
292+
private GrapeApiClass apiClass;
293293

294294
GrapeHelperMethod() {
295295
exists(DataFlow::CallNode helpersCall |
@@ -301,7 +301,7 @@ private class GrapeHelperMethod extends Method {
301301
/**
302302
* Gets the API class that contains this helper method.
303303
*/
304-
GrapeAPIClass getAPIClass() { result = apiClass }
304+
GrapeApiClass getAPIClass() { result = apiClass }
305305
}
306306

307307
/**

ruby/ql/test/library-tests/frameworks/grape/Grape.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
grapeAPIClasses
1+
grapeApiClasses
22
| app.rb:1:1:90:3 | MyAPI |
33
| app.rb:92:1:96:3 | AdminAPI |
44
grapeEndpoints

ruby/ql/test/library-tests/frameworks/grape/Grape.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import codeql.ruby.frameworks.Grape
33
import codeql.ruby.Concepts
44
import codeql.ruby.AST
55

6-
query predicate grapeAPIClasses(GrapeAPIClass api) { any() }
6+
query predicate grapeApiClasses(GrapeApiClass api) { any() }
77

8-
query predicate grapeEndpoints(GrapeAPIClass api, GrapeEndpoint endpoint, string method, string path) {
8+
query predicate grapeEndpoints(GrapeApiClass api, GrapeEndpoint endpoint, string method, string path) {
99
endpoint = api.getAnEndpoint() and
1010
method = endpoint.getHttpMethod() and
1111
path = endpoint.getPath()

0 commit comments

Comments
 (0)