1313 ApiMethod ,
1414 ApiParams ,
1515 ApiSchema ,
16+ Parameter ,
17+ ParamType ,
18+ Schema ,
1619)
1720import pbench .server .auth .auth as Auth
1821from pbench .server .database .models .api_keys import APIKey , DuplicateApiKey
@@ -26,20 +29,75 @@ def __init__(self, config: PbenchServerConfig):
2629 ApiSchema (
2730 ApiMethod .POST ,
2831 OperationCode .CREATE ,
32+ query_schema = Schema (
33+ Parameter ("label" , ParamType .STRING , required = False ),
34+ ),
35+ audit_type = AuditType .API_KEY ,
36+ audit_name = "apikey" ,
37+ authorization = ApiAuthorizationType .NONE ,
38+ ),
39+ ApiSchema (
40+ ApiMethod .GET ,
41+ OperationCode .READ ,
42+ uri_schema = Schema (
43+ Parameter ("key" , ParamType .STRING , required = False ),
44+ ),
45+ authorization = ApiAuthorizationType .NONE ,
46+ ),
47+ ApiSchema (
48+ ApiMethod .DELETE ,
49+ OperationCode .DELETE ,
50+ uri_schema = Schema (
51+ Parameter ("key" , ParamType .STRING , required = True ),
52+ ),
2953 audit_type = AuditType .API_KEY ,
3054 audit_name = "apikey" ,
3155 authorization = ApiAuthorizationType .NONE ,
3256 ),
3357 )
3458
59+ def _get (
60+ self , params : ApiParams , request : Request , context : ApiContext
61+ ) -> Response :
62+ """Get a list of API keys associated with the user.
63+
64+ GET /api/v1/key
65+
66+ Returns:
67+ Success: 200 with response containing the requested api_key
68+ or list of api_key
69+
70+ Raises:
71+ APIAbort, reporting "UNAUTHORIZED" or "NOT_FOUND"
72+ """
73+ user = Auth .token_auth .current_user ()
74+
75+ if not user :
76+ raise APIAbort (
77+ HTTPStatus .UNAUTHORIZED ,
78+ "User provided access_token is invalid or expired" ,
79+ )
80+
81+ key_id = params .uri .get ("key" )
82+ if not key_id :
83+ keys = APIKey .query (user = user )
84+ return [key .as_json () for key in keys ]
85+
86+ else :
87+ key = APIKey .query (id = key_id , user = user )
88+ if not key :
89+ raise APIAbort (HTTPStatus .NOT_FOUND , "Requested key not found" )
90+ return key [0 ].as_json ()
91+
3592 def _post (
3693 self , params : ApiParams , request : Request , context : ApiContext
3794 ) -> Response :
3895 """
3996 Post request for generating a new persistent API key.
4097
41- Required headers include
98+ POST /api/v1/key?label=label
4299
100+ Required headers include
43101 Content-Type: application/json
44102 Accept: application/json
45103
@@ -51,6 +109,12 @@ def _post(
51109 APIInternalError, reporting the failure message
52110 """
53111 user = Auth .token_auth .current_user ()
112+ label = params .query .get ("label" )
113+
114+ if context ["raw_params" ].uri :
115+ raise APIAbort (
116+ HTTPStatus .BAD_REQUEST , "Key cannot be specified by the user"
117+ )
54118
55119 if not user :
56120 raise APIAbort (
@@ -61,17 +125,51 @@ def _post(
61125 new_key = APIKey .generate_api_key (user )
62126 except Exception as e :
63127 raise APIInternalError (str (e )) from e
64-
65128 try :
66- key = APIKey (api_key = new_key , user = user )
129+ key = APIKey (key = new_key , user = user , label = label )
67130 key .add ()
68131 status = HTTPStatus .CREATED
69132 except DuplicateApiKey :
70133 status = HTTPStatus .OK
71134 except Exception as e :
72135 raise APIInternalError (str (e )) from e
73-
74- context ["auditing" ]["attributes" ] = {"key" : new_key }
75- response = jsonify ({"api_key" : new_key })
136+ context ["auditing" ]["attributes" ] = key .as_json ()
137+ response = jsonify (key .as_json ())
76138 response .status_code = status
77139 return response
140+
141+ def _delete (
142+ self , params : ApiParams , request : Request , context : ApiContext
143+ ) -> Response :
144+ """Delete the requested key.
145+
146+ DELETE /api/v1/key/{key}
147+
148+ Returns:
149+ Success: 200
150+
151+ Raises:
152+ APIAbort, reporting "UNAUTHORIZED" or "NOT_FOUND"
153+ APIInternalError, reporting the failure message
154+ """
155+ key_id = params .uri ["key" ]
156+ user = Auth .token_auth .current_user ()
157+
158+ if not user :
159+ raise APIAbort (
160+ HTTPStatus .UNAUTHORIZED ,
161+ "User provided access_token is invalid or expired" ,
162+ )
163+ term = {"id" : key_id }
164+ if not user .is_admin ():
165+ term ["user" ] = user
166+ keys = APIKey .query (** term )
167+ if not keys :
168+ raise APIAbort (HTTPStatus .NOT_FOUND , "Requested key not found" )
169+ key = keys [0 ]
170+ try :
171+ context ["auditing" ]["attributes" ] = key .as_json ()
172+ key .delete ()
173+ return "deleted" , HTTPStatus .OK
174+ except Exception as e :
175+ raise APIInternalError (str (e )) from e
0 commit comments