def post(self, revision_id): """ .. http:post:: /api/1/revisions/<int:revision_id>/comments Create a new Revision Comment. **Example Request**: .. sourcecode:: http POST /api/1/revisions/1141/comments HTTP/1.1 Host: example.com Accept: application/json { "text": "This is a Revision Comment." } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { 'id': 22, 'revision_id': 1141, "date_created": "2013-10-04 22:01:47", 'text': 'This is a Revision Comment.' } :statuscode 201: Revision Comment Created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('text', required=False, type=unicode, help='Must provide comment', location='json') args = self.reqparse.parse_args() irc = ItemRevisionComment() irc.user_id = current_user.id irc.revision_id = revision_id irc.text = args['text'] irc.date_created = datetime.datetime.utcnow() db.session.add(irc) db.session.commit() irc_committed = ItemRevisionComment.query.filter(ItemRevisionComment.id == irc.id).first() revision_marshaled = marshal(irc_committed.__dict__, REVISION_COMMENT_FIELDS) revision_marshaled = dict( revision_marshaled.items() + {'user': irc_committed.user.email}.items() ) return revision_marshaled, 200
def get(self, audit_id): """ .. http:get:: /api/1/issue/1234 Get a specific issue **Example Request**: .. sourcecode:: http GET /api/1/issue/1234 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { justification: null, name: "example_name", issue: "Example Audit Issue", notes: "Example Notes on Audit Issue", auth: { authenticated: true, user: "******" }, score: 0, item_id: 704, region: "us-east-1", justified: false, justified_date: null, id: 704 } :statuscode 200: no error :statuscode 401: Authentication Error. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemAudit.query.join("item").filter(ItemAudit.id == audit_id) result = query.first() issue_marshaled = marshal(result, AUDIT_FIELDS) item_marshaled = marshal(result.item, ITEM_FIELDS) issue_marshaled = dict( issue_marshaled.items() + item_marshaled.items() + {'auth': self.auth_dict}.items() ) return issue_marshaled, 200
def get(self, audit_id): """ .. http:get:: /api/1/issue/1234 Get a specific issue **Example Request**: .. sourcecode:: http GET /api/1/issue/1234 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { justification: null, name: "example_name", issue: "Example Audit Issue", notes: "Example Notes on Audit Issue", auth: { authenticated: true, user: "******" }, score: 0, item_id: 704, region: "us-east-1", justified: false, justified_date: null, id: 704 } :statuscode 200: no error :statuscode 401: Authentication Error. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemAudit.query.join("item").filter(ItemAudit.id == audit_id) result = query.first() issue_marshaled = marshal(result, AUDIT_FIELDS) item_marshaled = marshal(result.item, ITEM_FIELDS) issue_marshaled = dict(issue_marshaled.items() + item_marshaled.items() + {'auth': self.auth_dict}.items()) return issue_marshaled, 200
def get(self, item_id): """ .. http:get:: /api/1/ignorelistentries/<int:id> Get the ignorelist entry with the given ID. **Example Request**: .. sourcecode:: http GET /api/1/ignorelistentries/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval result = IgnoreListEntry.query.filter( IgnoreListEntry.id == item_id).first() if not result: return { "status": "Ignorelist entry with the given ID not found." }, 404 ignorelistentry_marshaled = marshal(result.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled['technology'] = result.technology.name ignorelistentry_marshaled['auth'] = self.auth_dict return ignorelistentry_marshaled, 200
def get(self, item_id): """ .. http:get:: /api/1/whitelistcidrs/<int:id> Get the whitelist entry with the given ID. **Example Request**: .. sourcecode:: http GET /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval result = NetworkWhitelistEntry.query.filter( NetworkWhitelistEntry.id == item_id).first() if not result: return { "status": "Whitelist entry with the given ID not found." }, 404 whitelistentry_marshaled = marshal(result.__dict__, WHITELIST_FIELDS) whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def get(self, revision_id, comment_id): """ .. http:get:: /api/1/revisions/<int:revision_id>/comments/<int:comment_id> Get a specific Revision Comment **Example Request**: .. sourcecode:: http GET /api/1/revisions/1141/comments/22 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'id': 22, 'revision_id': 1141, "date_created": "2013-10-04 22:01:47", 'text': 'This is a Revision Comment.' } :statuscode 200: no error :statuscode 404: Revision Comment with given ID not found. :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevisionComment.query.filter(ItemRevisionComment.id == comment_id) query = query.filter(ItemRevisionComment.revision_id == revision_id) irc = query.first() if irc is None: return {"status": "Revision Comment Not Found"}, 404 revision_marshaled = marshal(irc.__dict__, REVISION_COMMENT_FIELDS) revision_marshaled = dict( revision_marshaled.items() + {'user': irc.user.email}.items() ) return revision_marshaled, 200
def get(self, item_id, comment_id): """ .. http:get:: /api/1/items/<int:item_id>/comment/<int:comment_id> Retrieves an item comment. **Example Request**: .. sourcecode:: http GET /api/1/items/1234/comment/7718 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'id': 7719, 'date_created': "2013-10-04 22:01:47", 'text': 'This is an Item Comment.', 'item_id': 1111 } :statuscode 200: Success :statuscode 404: Comment with given ID not found. :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemComment.query.filter(ItemComment.id == comment_id) query = query.filter(ItemComment.item_id == item_id) ic = query.first() if ic is None: return {"status": "Item Comment Not Found"}, 404 comment_marshaled = marshal(ic.__dict__, ITEM_COMMENT_FIELDS) comment_marshaled = dict( comment_marshaled.items() + {'user': ic.user.email}.items() ) return comment_marshaled, 200
def get(self, revision_id, comment_id): """ .. http:get:: /api/1/revisions/<int:revision_id>/comments/<int:comment_id> Get a specific Revision Comment **Example Request**: .. sourcecode:: http GET /api/1/revisions/1141/comments/22 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'id': 22, 'revision_id': 1141, "date_created": "2013-10-04 22:01:47", 'text': 'This is a Revision Comment.' } :statuscode 200: no error :statuscode 404: Revision Comment with given ID not found. :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevisionComment.query.filter( ItemRevisionComment.id == comment_id) query = query.filter(ItemRevisionComment.revision_id == revision_id) irc = query.first() if irc is None: return {"status": "Revision Comment Not Found"}, 404 revision_marshaled = marshal(irc.__dict__, REVISION_COMMENT_FIELDS) revision_marshaled = dict(revision_marshaled.items() + {'user': irc.user.email}.items()) return revision_marshaled, 200
def delete(self, audit_id): """ .. http:delete:: /api/1/issues/1234/justification Remove a justification on an audit issue on a specific item. **Example Request**: .. sourcecode:: http DELETE /api/1/issues/1234/justification HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 OK Vary: Accept Content-Type: application/json { "status": "deleted" } :statuscode 202: Accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval if not __check_admin__(): return {"Error": "You must be an admin to delete justifications"}, 403 item = ItemAudit.query.filter(ItemAudit.id == audit_id).first() if not item: return {"Error": "Item with audit_id {} not found".format(audit_id)}, 404 item.justified_user_id = None item.justified = False item.justified_date = None item.justification = None db.session.add(item) db.session.commit() return {"status": "deleted"}, 202
def get(self, item_id): """ .. http:get:: /api/1/ignorelistentries/<int:id> Get the ignorelist entry with the given ID. **Example Request**: .. sourcecode:: http GET /api/1/ignorelistentries/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval result = IgnoreListEntry.query.filter(IgnoreListEntry.id == item_id).first() if not result: return {"status": "Ignorelist entry with the given ID not found."}, 404 ignorelistentry_marshaled = marshal(result.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled['technology'] = result.technology.name ignorelistentry_marshaled['auth'] = self.auth_dict return ignorelistentry_marshaled, 200
def delete(self, audit_id): """ .. http:delete:: /api/1/issues/1234/justification Remove a justification on an audit issue on a specific item. **Example Request**: .. sourcecode:: http DELETE /api/1/issues/1234/justification HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 OK Vary: Accept Content-Type: application/json { "status": "deleted" } :statuscode 202: Accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval item = ItemAudit.query.filter(ItemAudit.id == audit_id).first() if not item: return { "Error": "Item with audit_id {} not found".format(audit_id) }, 404 item.justified_user_id = None item.justified = False item.justified_date = None item.justification = None db.session.add(item) db.session.commit() return {"status": "deleted"}, 202
def get(self, account_id): """ .. http:get:: /api/1/account/<int:id> Get a list of Accounts matching the given criteria **Example Request**: .. sourcecode:: http GET /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { third_party: false, name: "example_name", notes: null, role_name: null, number: "111111111111", active: true, id: 1, s3_name: "example_name", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval result = Account.query.filter(Account.id == account_id).first() account_marshaled = marshal(result.__dict__, ACCOUNT_FIELDS) account_marshaled['auth'] = self.auth_dict return account_marshaled, 200
def get(self, item_id): """ .. http:get:: /api/1/whitelistcidrs/<int:id> Get the whitelist entry with the given ID. **Example Request**: .. sourcecode:: http GET /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval result = NetworkWhitelistEntry.query.filter(NetworkWhitelistEntry.id == item_id).first() if not result: return {"status": "Whitelist entry with the given ID not found."}, 404 whitelistentry_marshaled = marshal(result.__dict__, WHITELIST_FIELDS) whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def delete(self, account_id): """ .. http:delete:: /api/1/account/1 Delete an account. **Example Request**: .. sourcecode:: http DELETE /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval # Need to unsubscribe any users first: users = User.query.filter( User.accounts.any(Account.id == account_id)).all() for user in users: user.accounts = [ account for account in user.accounts if not account.id == account_id ] db.session.add(user) db.session.commit() account = Account.query.filter(Account.id == account_id).first() db.session.delete(account) db.session.commit() return {'status': 'deleted'}, 202
def delete(self, account_id): """ .. http:delete:: /api/1/account/1 Delete an account. **Example Request**: .. sourcecode:: http DELETE /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval if not __check_admin__(): return {"Error": "You must be an admin to edit accounts"}, 403 # Need to unsubscribe any users first: users = User.query.filter(User.accounts.any(Account.id == account_id)).all() for user in users: user.accounts = [account for account in user.accounts if not account.id == account_id] db.session.add(user) db.session.commit() account = Account.query.filter(Account.id == account_id).first() db.session.delete(account) db.session.commit() return {'status': 'deleted'}, 202
def put(self, as_id): """ .. http:put:: /api/1/auditorsettings/<int ID> Update an AuditorSetting **Example Request**: .. sourcecode:: http PUT /api/1/auditorsettings/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { account: "aws-account-name", disabled: false, id: 1, issue: "User with password login.", technology: "iamuser" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval if not __check_admin__(): return {"Error": "You must be an admin to edit the auditor settings"}, 403 self.reqparse.add_argument('disabled', type=bool, required=True, location='json') args = self.reqparse.parse_args() disabled = args.pop('disabled', None) results = AuditorSettings.query.get(as_id) results.disabled = disabled db.session.add(results) db.session.commit() return 200
def put(self, as_id): """ .. http:put:: /api/1/auditorsettings/<int ID> Update an AuditorSetting **Example Request**: .. sourcecode:: http PUT /api/1/auditorsettings/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { account: "aws-account-name", disabled: false, id: 1, issue: "User with password login.", technology: "iamuser" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('disabled', type=bool, required=True, location='json') args = self.reqparse.parse_args() disabled = args.pop('disabled', None) results = AuditorSettings.query.get(as_id) results.disabled = disabled db.session.add(results) db.session.commit() return 200
def delete(self, revision_id, comment_id): """ .. http:delete:: /api/1/revisions/<int:revision_id>/comments/<int:comment_id> Delete a specific Revision Comment **Example Request**: .. sourcecode:: http DELETE /api/1/revisions/1141/comments/22 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'status': "deleted" } :statuscode 202: Comment Deleted :statuscode 404: Revision Comment with given ID not found. :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevisionComment.query.filter( ItemRevisionComment.id == comment_id) query = query.filter(ItemRevisionComment.revision_id == revision_id) irc = query.first() if irc is None: return {"status": "Revision Comment Not Found"}, 404 query.delete() db.session.commit() return {"status": "deleted"}, 202
def delete(self, revision_id, comment_id): """ .. http:delete:: /api/1/revisions/<int:revision_id>/comments/<int:comment_id> Delete a specific Revision Comment **Example Request**: .. sourcecode:: http DELETE /api/1/revisions/1141/comments/22 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'status': "deleted" } :statuscode 202: Comment Deleted :statuscode 404: Revision Comment with given ID not found. :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevisionComment.query.filter(ItemRevisionComment.id == comment_id) query = query.filter(ItemRevisionComment.revision_id == revision_id) irc = query.first() if irc is None: return {"status": "Revision Comment Not Found"}, 404 query.delete() db.session.commit() return {"status": "deleted"}, 202
def delete(self, item_id, comment_id): """ .. http:delete:: /api/1/items/<int:item_id>/comment/<int:comment_id> Deletes an item comment. **Example Request**: .. sourcecode:: http DELETE /api/1/items/1234/comment/7718 HTTP/1.1 Host: example.com Accept: application/json { } **Example Response**: .. sourcecode:: http HTTP/1.1 202 OK Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: Deleted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemComment.query.filter(ItemComment.id == comment_id) query.filter(ItemComment.user_id == current_user.id).delete() db.session.commit() return {'result': 'success'}, 202
def delete(self, item_id, comment_id): """ .. http:delete:: /api/1/items/<int:item_id>/comment/<int:comment_id> Deletes an item comment. **Example Request**: .. sourcecode:: http DELETE /api/1/items/1234/comment/7718 HTTP/1.1 Host: example.com Accept: application/json { } **Example Response**: .. sourcecode:: http HTTP/1.1 202 OK Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: Deleted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemComment.query.filter(ItemComment.id == comment_id) query = query.filter(ItemComment.user_id == current_user.id).delete() db.session.commit() return {'result': 'success'}, 202
def delete(self, item_id): """ .. http:delete:: /api/1/ignorelistentries/123 Delete a ignorelist entry. **Example Request**: .. sourcecode:: http DELETE /api/1/ignorelistentries/123 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval if not __check_admin__(): return {"Error": "You must be an admin to edit the ignore list"}, 403 IgnoreListEntry.query.filter(IgnoreListEntry.id == item_id).delete() db.session.commit() return {'status': 'deleted'}, 202
def delete(self, item_id): """ .. http:delete:: /api/1/whitelistcidrs/123 Delete a network whitelist entry. **Example Request**: .. sourcecode:: http DELETE /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval NetworkWhitelistEntry.query.filter( NetworkWhitelistEntry.id == item_id).delete() db.session.commit() return {'status': 'deleted'}, 202
def delete(self, account_id): """ .. http:delete:: /api/1/account/1 Delete an account. **Example Request**: .. sourcecode:: http DELETE /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval Account.query.filter(Account.id == account_id).delete() db.session.commit() return {'status': 'deleted'}, 202
def delete(self, item_id): """ .. http:delete:: /api/1/whitelistcidrs/123 Delete a network whitelist entry. **Example Request**: .. sourcecode:: http DELETE /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json { 'status': 'deleted' } :statuscode 202: accepted :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval NetworkWhitelistEntry.query.filter(NetworkWhitelistEntry.id == item_id).delete() db.session.commit() return {'status': 'deleted'}, 202
def post(self): """ .. http:post:: /api/1/ignorelistentries Create a new CIDR whitelist entry. **Example Request**: .. sourcecode:: http POST /api/1/ignorelistentries HTTP/1.1 Host: example.com Accept: application/json { "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } **Example Response**: .. sourcecode:: http HTTP/1.1 201 Created Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } :statuscode 201: created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument( 'prefix', required=True, type=unicode, help= 'A prefix must be provided which matches the objects you wish to ignore.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('technology', required=True, type=unicode, help='Network CIDR required.', location='json') args = self.reqparse.parse_args() prefix = args['prefix'] technology = args.get('technology', True) notes = args.get('notes', None) entry = IgnoreListEntry() entry.prefix = prefix if notes: entry.notes = notes technology = Technology.query.filter( Technology.name == technology).first() if not technology: return { "status": "Could not find a technology with the given name" }, 500 entry.tech_id = technology.id db.session.add(entry) db.session.commit() db.session.refresh(entry) ignorelistentry_marshaled = marshal(entry.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled['technology'] = entry.technology.name ignorelistentry_marshaled['auth'] = self.auth_dict return ignorelistentry_marshaled, 201
def put(self, account_id): """ .. http:put:: /api/1/account/1 Edit an existing account. **Example Request**: .. sourcecode:: http PUT /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json { 'name': 'edited_account' 's3_name': 'edited_account', 'number': '0123456789', 'notes': 'this account is for ...', 'active': true, 'third_party': false } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'name': 'edited_account' 's3_name': 'edited_account', 'number': '0123456789', 'notes': 'this account is for ...', 'active': true, 'third_party': false } :statuscode 200: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=False, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('s3_name', required=False, type=unicode, help='Will use name if s3_name not provided.', location='json') self.reqparse.add_argument('number', required=False, type=unicode, help='Add the account number if available.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('active', required=False, type=bool, help='Determines whether this account should be interrogated by security monkey.', location='json') self.reqparse.add_argument('third_party', required=False, type=bool, help='Determines whether this account is a known friendly third party account.', location='json') args = self.reqparse.parse_args() account = Account.query.filter(Account.id == account_id).first() if account: account.name = args['name'] account.s3_name = args['s3_name'] account.number = args['number'] account.notes = args['notes'] account.active = args['active'] account.third_party = args['third_party'] db.session.add(account) db.session.commit() updated_account = Account.query.filter(Account.id == account_id).first() marshaled_account = marshal(updated_account.__dict__, ACCOUNT_FIELDS) marshaled_account['auth'] = self.auth_dict else: return {'status': 'error. Account ID not found.'}, 404 return marshaled_account, 200
def get(self): """ .. http:get:: /api/1/revisions Get a list of revisions **Example Request**: .. sourcecode:: http GET /api/1/revisions?count=1 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "items": [ { "account": "example_account", "name": "Example Name", "region": "us-east-1", "item_id": 144, "active": false, "date_created": "2014-06-19 20:54:12.962951", "technology": "sqs", "id": 223757 } ], "total": 1, "page": 1, "auth": { "authenticated": true, "user": "******" } } :statuscode 200: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument("count", type=int, default=30, location="args") self.reqparse.add_argument("page", type=int, default=1, location="args") self.reqparse.add_argument("active", type=str, default=None, location="args") self.reqparse.add_argument("regions", type=str, default=None, location="args") self.reqparse.add_argument("accounts", type=str, default=None, location="args") self.reqparse.add_argument("names", type=str, default=None, location="args") self.reqparse.add_argument("technologies", type=str, default=None, location="args") self.reqparse.add_argument("searchconfig", type=str, default=None, location="args") args = self.reqparse.parse_args() page = args.pop("page", None) count = args.pop("count", None) for k, v in args.items(): if not v: del args[k] query = ItemRevision.query.join("item") if "regions" in args: regions = args["regions"].split(",") query = query.filter(Item.region.in_(regions)) if "accounts" in args: accounts = args["accounts"].split(",") query = query.join((Account, Account.id == Item.account_id)) query = query.filter(Account.name.in_(accounts)) if "technologies" in args: technologies = args["technologies"].split(",") query = query.join((Technology, Technology.id == Item.tech_id)) query = query.filter(Technology.name.in_(technologies)) if "names" in args: names = args["names"].split(",") query = query.filter(Item.name.in_(names)) if "active" in args: active = args["active"].lower() == "true" query = query.filter(ItemRevision.active == active) if "searchconfig" in args: searchconfig = args["searchconfig"] query = query.filter(cast(ItemRevision.config, String).ilike("%{}%".format(searchconfig))) query = query.order_by(ItemRevision.date_created.desc()) revisions = query.paginate(page, count) marshaled_dict = {"page": revisions.page, "total": revisions.total, "auth": self.auth_dict} items_marshaled = [] for revision in revisions.items: item_marshaled = marshal(revision.item.__dict__, ITEM_FIELDS) revision_marshaled = marshal(revision.__dict__, REVISION_FIELDS) account_marshaled = {"account": revision.item.account.name} technology_marshaled = {"technology": revision.item.technology.name} merged_marshaled = dict( item_marshaled.items() + revision_marshaled.items() + account_marshaled.items() + technology_marshaled.items() ) items_marshaled.append(merged_marshaled) marshaled_dict["items"] = items_marshaled marshaled_dict["count"] = len(items_marshaled) return marshaled_dict, 200
def get(self): """ .. http:get:: /api/1/issues Get a list of Audit Issues matching the given criteria **Example Request**: .. sourcecode:: http GET /api/1/issues HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { items: [ { account: "example_account", justification: null, name: "example_name", technology: "s3", issue: "Example Issue", region: "us-east-1", score: 10, notes: "Example Notes", item_id: 11, justified: false, justified_date: null, id: 595 } ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') self.reqparse.add_argument('regions', type=str, default=None, location='args') self.reqparse.add_argument('accounts', type=str, default=None, location='args') self.reqparse.add_argument('technologies', type=str, default=None, location='args') self.reqparse.add_argument('names', type=str, default=None, location='args') self.reqparse.add_argument('active', type=str, default=None, location='args') self.reqparse.add_argument('searchconfig', type=str, default=None, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) for k, v in args.items(): if not v: del args[k] query = ItemAudit.query.join("item") if 'regions' in args: regions = args['regions'].split(',') query = query.filter(Item.region.in_(regions)) if 'accounts' in args: accounts = args['accounts'].split(',') query = query.join((Account, Account.id == Item.account_id)) query = query.filter(Account.name.in_(accounts)) if 'technologies' in args: technologies = args['technologies'].split(',') query = query.join((Technology, Technology.id == Item.tech_id)) query = query.filter(Technology.name.in_(technologies)) if 'names' in args: names = args['names'].split(',') query = query.filter(Item.name.in_(names)) if 'active' in args: active = args['active'].lower() == "true" query = query.join((ItemRevision, Item.latest_revision_id == ItemRevision.id)) query = query.filter(ItemRevision.active == active) if 'searchconfig' in args: search = args['searchconfig'] query = query.filter( (ItemAudit.issue.ilike('%{}%'.format(search))) | (ItemAudit.notes.ilike('%{}%'.format(search))) | (ItemAudit.justification.ilike('%{}%'.format(search))) | (Item.name.ilike('%{}%'.format(search))) ) query = query.order_by(ItemAudit.justified, ItemAudit.score.desc()) issues = query.paginate(page, count) marshaled_dict = {} marshaled_dict['page'] = issues.page marshaled_dict['total'] = issues.total marshaled_dict['auth'] = self.auth_dict items_marshaled = [] for issue in issues.items: item_marshaled = marshal(issue.item.__dict__, ITEM_FIELDS) issue_marshaled = marshal(issue.__dict__, AUDIT_FIELDS) account_marshaled = {'account': issue.item.account.name} technology_marshaled = {'technology': issue.item.technology.name} if issue.justified: issue_marshaled = dict( issue_marshaled.items() + {'justified_user': issue.user.email}.items()) merged_marshaled = dict( item_marshaled.items() + issue_marshaled.items() + account_marshaled.items() + technology_marshaled.items()) items_marshaled.append(merged_marshaled) marshaled_dict['items'] = items_marshaled marshaled_dict['count'] = len(items_marshaled) return marshaled_dict, 200
def put(self, item_id): """ .. http:get:: /api/1/whitelistcidrs/<int:id> Update the whitelist entry with the given ID. **Example Request**: .. sourcecode:: http PUT /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "id": 123, "name": "Corp", "notes": "Corporate Network - New", "cidr": "2.2.0.0/16" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "name": "Corp", "notes": "Corporate Network - New", "cidr": "2.2.0.0/16", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=True, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('cidr', required=True, type=unicode, help='Network CIDR required.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') args = self.reqparse.parse_args() name = args['name'] cidr = args.get('cidr', True) notes = args.get('notes', None) result = NetworkWhitelistEntry.query.filter(NetworkWhitelistEntry.id == item_id).first() if not result: return {"status": "Whitelist entry with the given ID not found."}, 404 result.name = name result.cidr = cidr result.notes = notes db.session.add(result) db.session.commit() db.session.refresh(result) whitelistentry_marshaled = marshal(result.__dict__, WHITELIST_FIELDS) whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def post(self): """ .. http:post:: /api/1/settings Change the settings for the current user. **Example Request**: .. sourcecode:: http POST /api/1/settings HTTP/1.1 Host: example.com Accept: application/json { "accounts": [ 1, 2, 3, 6, 17, 21, 22 ], "daily_audit_email": true, "change_report_setting": "ALL" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "auth": { "authenticated": true, "user": "******" }, "settings": { "accounts": [ 1, 2, 3, 6, 17, 21, 22 ], "daily_audit_email": true, "change_report_setting": "ALL" } } :statuscode 200: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('accounts', required=True, type=list, help='Must provide accounts', location='json') self.reqparse.add_argument('change_report_setting', required=True, type=str, help='Must provide change_report_setting', location='json') self.reqparse.add_argument('daily_audit_email', required=True, type=bool, help='Must provide daily_audit_email', location='json') args = self.reqparse.parse_args() current_user.daily_audit_email = args['daily_audit_email'] current_user.change_reports = args['change_report_setting'] account_list = [] for account_id in args['accounts']: account = Account.query.filter(Account.id == account_id).first() if account: account_list.append(account) #current_user.accounts.append(account) current_user.accounts = account_list db.session.add(current_user) db.session.commit() retdict = {'auth': self.auth_dict} account_ids = [] for account in current_user.accounts: account_ids.append(account.id) retdict['settings'] = { "accounts": account_ids, "change_report_setting": current_user.change_reports, "daily_audit_email": current_user.daily_audit_email } return retdict, 200
def put(self, item_id): """ .. http:get:: /api/1/ignorelistentries/<int:id> Update the ignorelist entry with the given ID. **Example Request**: .. sourcecode:: http PUT /api/1/ignorelistentries/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('prefix', required=True, type=unicode, help='A prefix must be provided which matches the objects you wish to ignore.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('technology', required=True, type=unicode, help='Network CIDR required.', location='json') args = self.reqparse.parse_args() prefix = args['prefix'] technology = args.get('technology', True) notes = args.get('notes', None) result = IgnoreListEntry.query.filter(IgnoreListEntry.id == item_id).first() if not result: return {"status": "Whitelist entry with the given ID not found."}, 404 result.prefix = prefix result.notes = notes technology = Technology.query.filter(Technology.name == technology).first() if not technology: return {"status": "Could not find a technology with the given name"}, 500 result.tech_id = technology.id db.session.add(result) db.session.commit() updated_entry = IgnoreListEntry.query.filter(IgnoreListEntry.id == result.id).first() whitelistentry_marshaled = marshal(updated_entry.__dict__, IGNORELIST_FIELDS) whitelistentry_marshaled['technology'] = updated_entry.technology.name whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def post(self): """ .. http:post:: /api/1/account/ Create a new account. **Example Request**: .. sourcecode:: http POST /api/1/account/ HTTP/1.1 Host: example.com Accept: application/json { 'name': 'new_account' 's3_name': 'new_account', 'number': '0123456789', 'notes': 'this account is for ...', 'active': true, 'third_party': false } **Example Response**: .. sourcecode:: http HTTP/1.1 201 Created Vary: Accept Content-Type: application/json { 'name': 'new_account' 's3_name': 'new_account', 'number': '0123456789', 'notes': 'this account is for ...', 'active': true, 'third_party': false } :statuscode 201: created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=True, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('s3_name', required=False, type=unicode, help='Will use name if s3_name not provided.', location='json') self.reqparse.add_argument('number', required=False, type=unicode, help='Add the account number if available.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('active', required=False, type=bool, help='Determines whether this account should be interrogated by security monkey.', location='json') self.reqparse.add_argument('third_party', required=False, type=bool, help='Determines whether this account is a known friendly third party account.', location='json') args = self.reqparse.parse_args() name = args['name'] s3_name = args.get('s3_name', name) number = args.get('number', None) notes = args.get('notes', None) active = args.get('active', True) third_party = args.get('third_party', False) account = Account() account.name = name account.s3_name = s3_name account.number = number account.notes = notes account.active = active account.third_party = third_party db.session.add(account) db.session.commit() updated_account = Account.query.filter(Account.id == account.id).first() marshaled_account = marshal(updated_account.__dict__, ACCOUNT_FIELDS) marshaled_account['auth'] = self.auth_dict return marshaled_account, 201
def put(self, account_id): """ .. http:put:: /api/1/account/1 Edit an existing account. **Example Request**: .. sourcecode:: http PUT /api/1/account/1 HTTP/1.1 Host: example.com Accept: application/json { 'name': 'edited_account' 's3_name': 'edited_account', 'number': '0123456789', 'notes': 'this account is for ...', 'role_name': 'CustomRole', 'active': true, 'third_party': false } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { 'name': 'edited_account' 's3_name': 'edited_account', 'number': '0123456789', 'notes': 'this account is for ...', 'role_name': 'CustomRole', 'active': true, 'third_party': false } :statuscode 200: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=False, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('s3_name', required=False, type=unicode, help='Will use name if s3_name not provided.', location='json') self.reqparse.add_argument('number', required=False, type=unicode, help='Add the account number if available.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('role_name', required=False, type=unicode, help='Custom role name.', location='json') self.reqparse.add_argument('active', required=False, type=bool, help='Determines whether this account should be interrogated by security monkey.', location='json') self.reqparse.add_argument('third_party', required=False, type=bool, help='Determines whether this account is a known friendly third party account.', location='json') args = self.reqparse.parse_args() account = Account.query.filter(Account.id == account_id).first() if not account: return {'status': 'error. Account ID not found.'}, 404 account.name = args['name'] account.s3_name = args['s3_name'] account.number = args['number'] account.notes = args['notes'] account.role_name = args['role_name'] account.active = args['active'] account.third_party = args['third_party'] db.session.add(account) db.session.commit() db.session.refresh(account) marshaled_account = marshal(account.__dict__, ACCOUNT_FIELDS) marshaled_account['auth'] = self.auth_dict return marshaled_account, 200
def get(self): """ .. http:get:: /api/1/items Get a list of items matching the given criteria. **Example Request**: .. sourcecode:: http GET /api/1/items HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "items": [ { "account": "example_account", "region": "us-east-1", "technology": "sqs", "id": 14414, "name": "example_name", "num_issues": 3, "issue_score": 9, "unjustified_issue_score": 3, "active" true, "first_seen": "2014-06-17 19:47:07.299760", "last_seen": "2014-06-18 11:53:16.467709" } ], "total": 144, "page": 1, "auth": { "authenticated": true, "user": "******" } } :statuscode 200: no error :statuscode 401: Authenciation Error. Please Login. """ (auth, retval) = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') self.reqparse.add_argument('regions', type=str, default=None, location='args') self.reqparse.add_argument('accounts', type=str, default=None, location='args') self.reqparse.add_argument('active', type=str, default=None, location='args') self.reqparse.add_argument('names', type=str, default=None, location='args') self.reqparse.add_argument('technologies', type=str, default=None, location='args') self.reqparse.add_argument('searchconfig', type=str, default=None, location='args') self.reqparse.add_argument('ids', type=int, default=None, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) for k, v in args.items(): if not v: del args[k] # Read more about filtering: # http://docs.sqlalchemy.org/en/rel_0_7/orm/query.html query = Item.query.join( (ItemRevision, Item.latest_revision_id == ItemRevision.id)) if 'regions' in args: regions = args['regions'].split(',') query = query.filter(Item.region.in_(regions)) if 'accounts' in args: accounts = args['accounts'].split(',') query = query.join((Account, Account.id == Item.account_id)) query = query.filter(Account.name.in_(accounts)) if 'technologies' in args: technologies = args['technologies'].split(',') query = query.join((Technology, Technology.id == Item.tech_id)) query = query.filter(Technology.name.in_(technologies)) if 'names' in args: names = args['names'].split(',') query = query.filter(Item.name.in_(names)) if 'ids' in args: ids = args['ids'].split(',') query = query.filter(Item.id.in_(ids)) if 'active' in args: active = args['active'].lower() == "true" query = query.filter(ItemRevision.active == active) if 'searchconfig' in args: searchconfig = args['searchconfig'] query = query.filter( cast(ItemRevision.config, String).ilike('%{}%'.format(searchconfig))) query = query.order_by(ItemRevision.date_created.desc()) items = query.paginate(page, count) marshaled_dict = { 'page': items.page, 'total': items.total, 'auth': self.auth_dict } marshaled_items = [] for item in items.items: num_issues = len(item.issues) issue_score = 0 unjustified_issue_score = 0 for issue in item.issues: issue_score = issue_score + issue.score if not issue.justified: unjustified_issue_score += issue.score first_seen = str(item.revisions[-1].date_created) last_seen = str(item.revisions[0].date_created) active = item.revisions[0].active item_marshaled = {} item_marshaled = marshal(item.__dict__, ITEM_FIELDS) item_marshaled = dict( item_marshaled.items() + { 'account': item.account.name, 'technology': item.technology.name, 'num_issues': num_issues, 'issue_score': issue_score, 'unjustified_issue_score': unjustified_issue_score, 'active': active, 'first_seen': first_seen, 'last_seen': last_seen #'last_rev': item.revisions[0].config, }.items()) marshaled_items.append(item_marshaled) marshaled_dict['items'] = marshaled_items marshaled_dict['count'] = len(marshaled_items) return marshaled_dict, 200
def get(self): """ .. http:get:: /api/1/auditorsettings Get a list of AuditorSetting items **Example Request**: .. sourcecode:: http GET /api/1/auditorsettings HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { count: 15, items: [ { id: 1, account: "aws-account-name", technology: "iamuser", disabled: true, issue: "User with password login.", count: 15 }, ... ] auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') self.reqparse.add_argument('accounts', type=str, default=None, location='args') self.reqparse.add_argument('technologies', type=str, default=None, location='args') self.reqparse.add_argument('enabled', type=bool, default=None, location='args') self.reqparse.add_argument('issue', type=str, default=None, location='args') self.reqparse.add_argument('order_by', type=str, default=None, location='args') self.reqparse.add_argument('order_dir', type=str, default='Desc', location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) for k, v in args.items(): if not v: del args[k] query = AuditorSettings.query query = query.join((Account, Account.id == AuditorSettings.account_id)) query = query.join( (Technology, Technology.id == AuditorSettings.tech_id)) if 'accounts' in args: accounts = args['accounts'].split(',') query = query.filter(Account.name.in_(accounts)) if 'technologies' in args: technologies = args['technologies'].split(',') query = query.filter(Technology.name.in_(technologies)) if 'enabled' in args: query = query.filter( AuditorSettings.disabled != bool(args['enabled'])) if 'issue' in args: query = query.filter(AuditorSettings.issue_text == args['issue']) if 'order_by' in args: if args['order_by'] == 'account' and args['order_dir'] == 'Desc': query = query.order_by(Account.name.desc()) elif args['order_by'] == 'account' and args['order_dir'] == 'Asc': query = query.order_by(Account.name.asc()) elif args['order_by'] == 'technology' and args[ 'order_dir'] == 'Desc': query = query.order_by(Technology.name.desc()) elif args['order_by'] == 'technology' and args[ 'order_dir'] == 'Asc': query = query.order_by(Technology.name.asc()) elif args['order_by'] == 'enabled' and args['order_dir'] == 'Desc': query = query.order_by(AuditorSettings.disabled.asc()) elif args['order_by'] == 'enabled' and args['order_dir'] == 'Asc': query = query.order_by(AuditorSettings.disabled.desc()) elif args['order_by'] == 'issue' and args['order_dir'] == 'Desc': query = query.order_by(AuditorSettings.issue_text.desc()) elif args['order_by'] == 'issue' and args['order_dir'] == 'Asc': query = query.order_by(AuditorSettings.issue_text.asc()) elif args['order_by'] == 'issue_count': stmt = db.session.query( ItemAudit.auditor_setting_id, func.count('*').label('setting_count')).group_by( ItemAudit.auditor_setting_id).subquery() query = query.join( (stmt, AuditorSettings.id == stmt.c.auditor_setting_id)) if args['order_dir'] == 'Desc': query = query.order_by(stmt.c.setting_count.desc()) elif args['order_dir'] == 'Asc': query = query.order_by(stmt.c.setting_count.asc()) enabled_auditors = query.paginate(page, count) auditor_settings = [] for auditor_setting in enabled_auditors.items: marshalled = marshal(auditor_setting.__dict__, AUDITORSETTING_FIELDS) marshalled = dict( marshalled.items() + { 'account': auditor_setting.account.name, 'technology': auditor_setting.technology.name, 'count': len(auditor_setting.issues) }.items()) marshalled['issue'] = marshalled['issue_text'] del marshalled['issue_text'] auditor_settings.append(marshalled) ret_dict = { 'items': auditor_settings, 'page': enabled_auditors.page, 'total': enabled_auditors.total, 'count': len(auditor_settings), 'auth': self.auth_dict } return ret_dict, 200
def get(self): """ .. http:get:: /api/1/ignorelistentries Get a list of Ignorelist entries. **Example Request**: .. sourcecode:: http GET /api/1/ignorelistentries HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = IgnoreListEntry.query.order_by(IgnoreListEntry.id).paginate(page, count, error_out=False) items = [] for entry in result.items: ignorelistentry_marshaled = marshal(entry.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled["technology"] = entry.technology.name items.append(ignorelistentry_marshaled) marshaled_dict = {} marshaled_dict['total'] = result.total marshaled_dict['count'] = len(items) marshaled_dict['page'] = result.page marshaled_dict['items'] = items marshaled_dict['auth'] = self.auth_dict return marshaled_dict, 200
def get(self): """ .. http:get:: /api/1/accounts Get a list of Accounts matching the given criteria **Example Request**: .. sourcecode:: http GET /api/1/accounts HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { third_party: false, name: "example_name", notes: null, number: "111111111111", active: true, id: 1, s3_name: "example_name" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = Account.query.order_by(Account.id).paginate(page, count, error_out=False) items = [] for account in result.items: account_marshaled = marshal(account.__dict__, ACCOUNT_FIELDS) items.append(account_marshaled) marshaled_dict = {} marshaled_dict['total'] = result.total marshaled_dict['count'] = len(items) marshaled_dict['page'] = result.page marshaled_dict['items'] = items marshaled_dict['auth'] = self.auth_dict return marshaled_dict, 200
def post(self, revision_id): """ .. http:post:: /api/1/revisions/<int:revision_id>/comments Create a new Revision Comment. **Example Request**: .. sourcecode:: http POST /api/1/revisions/1141/comments HTTP/1.1 Host: example.com Accept: application/json { "text": "This is a Revision Comment." } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { 'id': 22, 'revision_id': 1141, "date_created": "2013-10-04 22:01:47", 'text': 'This is a Revision Comment.' } :statuscode 201: Revision Comment Created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('text', required=False, type=unicode, help='Must provide comment', location='json') args = self.reqparse.parse_args() irc = ItemRevisionComment() irc.user_id = current_user.id irc.revision_id = revision_id irc.text = args['text'] irc.date_created = datetime.datetime.utcnow() db.session.add(irc) db.session.commit() db.session.refresh(irc) revision_marshaled = marshal(irc.__dict__, REVISION_COMMENT_FIELDS) revision_marshaled = dict(revision_marshaled.items() + {'user': irc.user.email}.items()) return revision_marshaled, 200
def get(self): """ .. http:get:: /api/1/settings Get the settings for the given user. **Example Request**: .. sourcecode:: http GET /api/1/settings HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "auth": { "authenticated": true, "user": "******" }, "settings": [ { "accounts": [ 1, 2, 3, 6, 17, 21, 22 ], "change_reports": "ISSUES", "daily_audit_email": true } ] } :statuscode 200: no error :statuscode 401: Authentication Error. Please Authenticate. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval return_dict = {"auth": self.auth_dict} if not current_user.is_authenticated(): return_val = return_dict, 401 return return_val return_dict["settings"] = [] user = User.query.filter(User.id == current_user.get_id()).first() if user: sub_marshaled = marshal(user.__dict__, USER_SETTINGS_FIELDS) account_ids = [] for account in user.accounts: account_ids.append(account.id) sub_marshaled = dict(sub_marshaled.items() + {"accounts": account_ids}.items()) return_dict["settings"].append(sub_marshaled) return return_dict, 200
def put(self, item_id): """ .. http:get:: /api/1/ignorelistentries/<int:id> Update the ignorelist entry with the given ID. **Example Request**: .. sourcecode:: http PUT /api/1/ignorelistentries/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument( 'prefix', required=True, type=unicode, help= 'A prefix must be provided which matches the objects you wish to ignore.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('technology', required=True, type=unicode, help='Network CIDR required.', location='json') args = self.reqparse.parse_args() prefix = args['prefix'] technology = args.get('technology', True) notes = args.get('notes', None) result = IgnoreListEntry.query.filter( IgnoreListEntry.id == item_id).first() if not result: return { "status": "Whitelist entry with the given ID not found." }, 404 result.prefix = prefix result.notes = notes technology = Technology.query.filter( Technology.name == technology).first() if not technology: return { "status": "Could not find a technology with the given name" }, 500 result.tech_id = technology.id db.session.add(result) db.session.commit() db.session.refresh(result) whitelistentry_marshaled = marshal(result.__dict__, IGNORELIST_FIELDS) whitelistentry_marshaled['technology'] = result.technology.name whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def post(self, item_id): """ .. http:post:: /api/1/items/<int:item_id>/comments Adds an item comment. **Example Request**: .. sourcecode:: http POST /api/1/items/1234/comments HTTP/1.1 Host: example.com Accept: application/json { "text": "This item is my favorite." } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { 'item_id': 1234, 'id': 7718, 'comment': 'This item is my favorite.', 'user': '******' } { "date_created": "2014-10-11 23:03:47.716698", "id": 1, "text": "This is an item comment." } :statuscode 201: Created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('text', required=False, type=unicode, help='Must provide comment', location='json') args = self.reqparse.parse_args() ic = ItemComment() ic.user_id = current_user.id ic.item_id = item_id ic.text = args['text'] ic.date_created = datetime.datetime.utcnow() db.session.add(ic) db.session.commit() ic2 = ItemComment.query.filter(ItemComment.id == ic.id).first() comment_marshaled = marshal(ic2.__dict__, ITEM_COMMENT_FIELDS) comment_marshaled = dict(comment_marshaled.items() + {'user': ic2.user.email}.items()) return comment_marshaled, 201
def get(self, key_id): """ .. http:get:: /api/1/distinct Get a list of distinct regions, names, accounts, or technologies **Example Request**: .. sourcecode:: http GET /api/1/distinct/name HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json :statuscode 200: no error """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') self.reqparse.add_argument('select2', type=str, default="", location='args') self.reqparse.add_argument('searchconfig', type=str, default="", location='args') self.reqparse.add_argument('regions', type=str, default=None, location='args') self.reqparse.add_argument('accounts', type=str, default=None, location='args') self.reqparse.add_argument('technologies', type=str, default=None, location='args') self.reqparse.add_argument('names', type=str, default=None, location='args') self.reqparse.add_argument('active', type=str, default=None, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) q = args.pop('searchconfig', "").lower() select2 = args.pop('select2', "") for k, v in args.items(): if not v: del args[k] if select2.lower() == 'true': select2 = True else: select2 = False query = Item.query query = query.join((Account, Account.id == Item.account_id)) query = query.join((Technology, Technology.id == Item.tech_id)) query = query.join((ItemRevision, Item.latest_revision_id == ItemRevision.id)) if 'regions' in args and key_id != 'region': regions = args['regions'].split(',') query = query.filter(Item.region.in_(regions)) if 'accounts' in args and key_id != 'account': accounts = args['accounts'].split(',') query = query.filter(Account.name.in_(accounts)) if 'technologies' in args and key_id != 'tech': technologies = args['technologies'].split(',') query = query.filter(Technology.name.in_(technologies)) if 'names' in args and key_id != 'name': names = args['names'].split(',') query = query.filter(Item.name.in_(names)) if 'active' in args: active = args['active'].lower() == "true" query = query.filter(ItemRevision.active == active) if key_id == 'tech': if select2: query = query.distinct(Technology.name).filter(func.lower(Technology.name).like('%' + q + '%')) else: query = query.distinct(Technology.name) elif key_id == 'account': if select2: query = query.filter(Account.third_party == False) query = query.distinct(Account.name).filter(func.lower(Account.name).like('%' + q + '%')) else: query = query.distinct(Account.name) else: filter_by = None if key_id == "region": filter_by = Item.region elif key_id == "name": filter_by = Item.name else: return json.loads('{ "error": "Supply key in type,region,account,name" }') if select2: query = query.distinct(filter_by).filter(func.lower(filter_by).like('%' + q + '%')) else: query = query.distinct(filter_by) items = query.paginate(page, count, error_out=False) marshaled_dict = {} list_distinct = [] for item in items.items: if key_id == "tech": text = item.technology.name item_id = item.id elif key_id == "account": text = item.account.name item_id = item.id elif key_id == "region": text = item.region item_id = item.id elif key_id == "name": text = item.name item_id = item.id if(select2): list_distinct.append({"id": item_id, "text": text}) else: list_distinct.append(text) marshaled_dict['auth'] = self.auth_dict marshaled_dict['items'] = list_distinct marshaled_dict['page'] = items.page marshaled_dict['total'] = items.total marshaled_dict['key_id'] = key_id return marshaled_dict, 200
def get(self): """ .. http:get:: /api/1/whitelistcidrs Get a list of CIDR's whitelisted to be used in security groups. **Example Request**: .. sourcecode:: http GET /api/1/whitelistcidrs HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { "id": 123, "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = NetworkWhitelistEntry.query.order_by( NetworkWhitelistEntry.id).paginate(page, count, error_out=False) items = [] for entry in result.items: whitelistentry_marshaled = marshal(entry.__dict__, WHITELIST_FIELDS) items.append(whitelistentry_marshaled) marshaled_dict = { 'total': result.total, 'count': len(items), 'page': result.page, 'items': items, 'auth': self.auth_dict } return marshaled_dict, 200
def get(self): """ .. http:get:: /api/1/revisions Get a list of revisions **Example Request**: .. sourcecode:: http GET /api/1/revisions?count=1 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "items": [ { "account": "example_account", "name": "Example Name", "region": "us-east-1", "item_id": 144, "active": false, "date_created": "2014-06-19 20:54:12.962951", "technology": "sqs", "id": 223757 } ], "total": 1, "page": 1, "auth": { "authenticated": true, "user": "******" } } :statuscode 200: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') self.reqparse.add_argument('active', type=str, default=None, location='args') self.reqparse.add_argument('regions', type=str, default=None, location='args') self.reqparse.add_argument('accounts', type=str, default=None, location='args') self.reqparse.add_argument('names', type=str, default=None, location='args') self.reqparse.add_argument('technologies', type=str, default=None, location='args') self.reqparse.add_argument('searchconfig', type=str, default=None, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) for k, v in args.items(): if not v: del args[k] query = ItemRevision.query.join("item") if 'regions' in args: regions = args['regions'].split(',') query = query.filter(Item.region.in_(regions)) if 'accounts' in args: accounts = args['accounts'].split(',') query = query.join((Account, Account.id == Item.account_id)) query = query.filter(Account.name.in_(accounts)) if 'technologies' in args: technologies = args['technologies'].split(',') query = query.join((Technology, Technology.id == Item.tech_id)) query = query.filter(Technology.name.in_(technologies)) if 'names' in args: names = args['names'].split(',') query = query.filter(Item.name.in_(names)) if 'active' in args: active = args['active'].lower() == "true" query = query.filter(ItemRevision.active == active) if 'searchconfig' in args: searchconfig = args['searchconfig'] query = query.filter( cast(ItemRevision.config, String).ilike('%{}%'.format(searchconfig))) query = query.order_by(ItemRevision.date_created.desc()) revisions = query.paginate(page, count) marshaled_dict = { 'page': revisions.page, 'total': revisions.total, 'auth': self.auth_dict } items_marshaled = [] for revision in revisions.items: item_marshaled = marshal(revision.item.__dict__, ITEM_FIELDS) revision_marshaled = marshal(revision.__dict__, REVISION_FIELDS) account_marshaled = {'account': revision.item.account.name} technology_marshaled = { 'technology': revision.item.technology.name } merged_marshaled = dict(item_marshaled.items() + revision_marshaled.items() + account_marshaled.items() + technology_marshaled.items()) items_marshaled.append(merged_marshaled) marshaled_dict['items'] = items_marshaled marshaled_dict['count'] = len(items_marshaled) return marshaled_dict, 200
def put(self, item_id): """ .. http:get:: /api/1/whitelistcidrs/<int:id> Update the whitelist entry with the given ID. **Example Request**: .. sourcecode:: http PUT /api/1/whitelistcidrs/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "id": 123, "name": "Corp", "notes": "Corporate Network - New", "cidr": "2.2.0.0/16" } **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "id": 123, "name": "Corp", "notes": "Corporate Network - New", "cidr": "2.2.0.0/16", auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 404: item with given ID not found :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=True, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('cidr', required=True, type=unicode, help='Network CIDR required.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') args = self.reqparse.parse_args() name = args['name'] cidr = args.get('cidr', True) notes = args.get('notes', None) result = NetworkWhitelistEntry.query.filter( NetworkWhitelistEntry.id == item_id).first() if not result: return { "status": "Whitelist entry with the given ID not found." }, 404 result.name = name result.cidr = cidr result.notes = notes db.session.add(result) db.session.commit() db.session.refresh(result) whitelistentry_marshaled = marshal(result.__dict__, WHITELIST_FIELDS) whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 200
def get(self, revision_id): """ .. http:get:: /api/1/revision/1234 Get a specific revision. **Example Request**: .. sourcecode:: http GET /api/1/revision/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "auth": { "authenticated": true, "user": "******" }, "item_id": 114, "comments": [], "active": false, "date_created": "2013-10-04 22:01:47", "config": {}, "id":123 } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevision.query.filter(ItemRevision.id == revision_id) result = query.first() comments = [] for comment in result.comments: comment_marshaled = marshal(comment, REVISION_COMMENT_FIELDS) comments.append( dict(comment_marshaled.items() + {'user': comment.user.email}.items())) revision_marshaled = marshal(result, REVISION_FIELDS) revision_marshaled = dict(revision_marshaled.items() + {'config': result.config}.items() + {'auth': self.auth_dict}.items() + {'comments': comments}.items()) self.reqparse.add_argument('compare', type=int, default=None, location='args') args = self.reqparse.parse_args() compare_id = args.pop('compare', None) if compare_id: query = ItemRevision.query.filter(ItemRevision.id == compare_id) compare_result = query.first() pdiff = PolicyDiff(result.config, compare_result.config) revision_marshaled = dict( revision_marshaled.items() + {'diff_html': pdiff.produceDiffHTML()}.items()) return revision_marshaled, 200
def get(self): """ .. http:get:: /api/1/whitelistcidrs Get a list of CIDR's whitelisted to be used in security groups. **Example Request**: .. sourcecode:: http GET /api/1/whitelistcidrs HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { "id": 123, "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = NetworkWhitelistEntry.query.order_by(NetworkWhitelistEntry.id).paginate(page, count, error_out=False) items = [] for entry in result.items: whitelistentry_marshaled = marshal(entry.__dict__, WHITELIST_FIELDS) items.append(whitelistentry_marshaled) marshaled_dict = { 'total': result.total, 'count': len(items), 'page': result.page, 'items': items, 'auth': self.auth_dict } return marshaled_dict, 200
def post(self, audit_id): """ .. http:post:: /api/1/issues/1234/justification Justify an audit issue on a specific item. **Example Request**: .. sourcecode:: http POST /api/1/issues/1234/justification HTTP/1.1 Host: example.com Accept: application/json { 'justification': 'I promise not to abuse this.' } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { "result": { "justification": "I promise not to abuse this.", "issue": "Example Issue", "notes": "Example Notes", "score": 0, "item_id": 11890, "justified_user": "******", "justified": true, "justified_date": "2014-06-19 21:45:58.779168", "id": 1234 }, "auth": { "authenticated": true, "user": "******" } } :statuscode 201: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('justification', required=False, type=str, help='Must provide justification', location='json') args = self.reqparse.parse_args() item = ItemAudit.query.filter(ItemAudit.id == audit_id).first() if not item: return {"Error": "Item with audit_id {} not found".format(audit_id)}, 404 item.justified_user_id = current_user.id item.justified = True item.justified_date = datetime.datetime.utcnow() item.justification = args['justification'] db.session.add(item) db.session.commit() db.session.refresh(item) retdict = {'auth': self.auth_dict} if item.user: retdict['result'] = dict( marshal(item.__dict__, AUDIT_FIELDS).items() + {"justified_user": item.user.email}.items()) else: retdict['result'] = dict( marshal(item.__dict__, AUDIT_FIELDS).items() + {"justified_user": None}.items()) return retdict, 200
def post(self): """ .. http:post:: /api/1/whitelistcidrs Create a new CIDR whitelist entry. **Example Request**: .. sourcecode:: http POST /api/1/whitelistcidrs HTTP/1.1 Host: example.com Accept: application/json { "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22" } **Example Response**: .. sourcecode:: http HTTP/1.1 201 Created Vary: Accept Content-Type: application/json { "id": 123, "name": "Corp", "notes": "Corporate Network", "cidr": "1.2.3.4/22" } :statuscode 201: created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('name', required=True, type=unicode, help='Must provide account name', location='json') self.reqparse.add_argument('cidr', required=True, type=unicode, help='Network CIDR required.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') args = self.reqparse.parse_args() name = args['name'] cidr = args.get('cidr', True) notes = args.get('notes', None) whitelist_entry = NetworkWhitelistEntry() whitelist_entry.name = name whitelist_entry.cidr = cidr if notes: whitelist_entry.notes = notes db.session.add(whitelist_entry) db.session.commit() db.session.refresh(whitelist_entry) whitelistentry_marshaled = marshal(whitelist_entry.__dict__, WHITELIST_FIELDS) whitelistentry_marshaled['auth'] = self.auth_dict return whitelistentry_marshaled, 201
def post(self, item_id): """ .. http:post:: /api/1/items/<int:item_id>/comments Adds an item comment. **Example Request**: .. sourcecode:: http POST /api/1/items/1234/comments HTTP/1.1 Host: example.com Accept: application/json { "text": "This item is my favorite." } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { 'item_id': 1234, 'id': 7718, 'comment': 'This item is my favorite.', 'user': '******' } { "date_created": "2014-10-11 23:03:47.716698", "id": 1, "text": "This is an item comment." } :statuscode 201: Created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('text', required=False, type=unicode, help='Must provide comment', location='json') args = self.reqparse.parse_args() ic = ItemComment() ic.user_id = current_user.id ic.item_id = item_id ic.text = args['text'] ic.date_created = datetime.datetime.utcnow() db.session.add(ic) db.session.commit() db.session.refresh(ic) comment_marshaled = marshal(ic.__dict__, ITEM_COMMENT_FIELDS) comment_marshaled = dict( comment_marshaled.items() + {'user': ic.user.email}.items() ) return comment_marshaled, 201
def get(self, revision_id): """ .. http:get:: /api/1/revision/1234 Get a specific revision. **Example Request**: .. sourcecode:: http GET /api/1/revision/123 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "auth": { "authenticated": true, "user": "******" }, "item_id": 114, "comments": [], "active": false, "date_created": "2013-10-04 22:01:47", "config": {}, "id":123 } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = ItemRevision.query.filter(ItemRevision.id == revision_id) result = query.first() comments = [] for comment in result.comments: comment_marshaled = marshal(comment, REVISION_COMMENT_FIELDS) comments.append(dict(comment_marshaled.items() + {"user": comment.user.email}.items())) revision_marshaled = marshal(result, REVISION_FIELDS) revision_marshaled = dict( revision_marshaled.items() + {"config": result.config}.items() + {"auth": self.auth_dict}.items() + {"comments": comments}.items() ) self.reqparse.add_argument("compare", type=int, default=None, location="args") args = self.reqparse.parse_args() compare_id = args.pop("compare", None) if compare_id: query = ItemRevision.query.filter(ItemRevision.id == compare_id) compare_result = query.first() pdiff = PolicyDiff(result.config, compare_result.config) revision_marshaled = dict(revision_marshaled.items() + {"diff_html": pdiff.produceDiffHTML()}.items()) return revision_marshaled, 200
def get(self): """ .. http:get:: /api/1/accounts Get a list of Accounts matching the given criteria **Example Request**: .. sourcecode:: http GET /api/1/accounts HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { third_party: false, name: "example_name", notes: null, role_name: null, number: "111111111111", active: true, id: 1, s3_name: "example_name" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = Account.query.order_by(Account.id).paginate(page, count, error_out=False) items = [] for account in result.items: account_marshaled = marshal(account.__dict__, ACCOUNT_FIELDS) items.append(account_marshaled) marshaled_dict = { 'total': result.total, 'count': len(items), 'page': result.page, 'items': items, 'auth': self.auth_dict } return marshaled_dict, 200
def post(self, audit_id): """ .. http:post:: /api/1/issues/1234/justification Justify an audit issue on a specific item. **Example Request**: .. sourcecode:: http POST /api/1/issues/1234/justification HTTP/1.1 Host: example.com Accept: application/json { 'justification': 'I promise not to abuse this.' } **Example Response**: .. sourcecode:: http HTTP/1.1 201 OK Vary: Accept Content-Type: application/json { "result": { "justification": "I promise not to abuse this.", "issue": "Example Issue", "notes": "Example Notes", "score": 0, "item_id": 11890, "justified_user": "******", "justified": true, "justified_date": "2014-06-19 21:45:58.779168", "id": 1234 }, "auth": { "authenticated": true, "user": "******" } } :statuscode 201: no error :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('justification', required=False, type=str, help='Must provide justification', location='json') args = self.reqparse.parse_args() item = ItemAudit.query.filter(ItemAudit.id == audit_id).first() if not item: return { "Error": "Item with audit_id {} not found".format(audit_id) }, 404 item.justified_user_id = current_user.id item.justified = True item.justified_date = datetime.datetime.utcnow() item.justification = args['justification'] db.session.add(item) db.session.commit() db.session.refresh(item) retdict = {'auth': self.auth_dict} if item.user: retdict['result'] = dict( marshal(item.__dict__, AUDIT_FIELDS).items() + {"justified_user": item.user.email}.items()) else: retdict['result'] = dict( marshal(item.__dict__, AUDIT_FIELDS).items() + {"justified_user": None}.items()) return retdict, 200
def post(self): """ .. http:post:: /api/1/ignorelistentries Create a new CIDR whitelist entry. **Example Request**: .. sourcecode:: http POST /api/1/ignorelistentries HTTP/1.1 Host: example.com Accept: application/json { "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } **Example Response**: .. sourcecode:: http HTTP/1.1 201 Created Vary: Accept Content-Type: application/json { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" } :statuscode 201: created :statuscode 401: Authentication Error. Please Login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('prefix', required=True, type=unicode, help='A prefix must be provided which matches the objects you wish to ignore.', location='json') self.reqparse.add_argument('notes', required=False, type=unicode, help='Add context.', location='json') self.reqparse.add_argument('technology', required=True, type=unicode, help='Network CIDR required.', location='json') args = self.reqparse.parse_args() prefix = args['prefix'] technology = args.get('technology', True) notes = args.get('notes', None) entry = IgnoreListEntry() entry.prefix = prefix if notes: entry.notes = notes technology = Technology.query.filter(Technology.name == technology).first() if not technology: return {"status": "Could not find a technology with the given name"}, 500 entry.tech_id = technology.id db.session.add(entry) db.session.commit() updated_entry = IgnoreListEntry.query.filter(IgnoreListEntry.id == entry.id).first() ignorelistentry_marshaled = marshal(updated_entry.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled['technology'] = entry.technology.name ignorelistentry_marshaled['auth'] = self.auth_dict return ignorelistentry_marshaled, 201
def get(self, item_id): """ .. http:get:: /api/1/item/1234 Get a specific item **Example Request**: .. sourcecode:: http GET /api/1/item/1234 HTTP/1.1 Host: example.com Accept: application/json **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { "item": { "account": "example_account", "region": "us-east-1", "technology": "elb", "id": 1234, "name": "example_name" }, "revisions": [ { "active": false, "date_created": "2014-04-11 17:05:06.701936", "config": {}, "item_id": 1234, "id": 213784 } ], "auth": { "authenticated": true, "user": "******" }, "issues": [], "comments": [] } :statuscode 200: no error :statuscode 401: Authenticaiton Error Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval query = Item.query.filter(Item.id == item_id) result = query.first() # result should be an Item with a list of audit thingers and a list of # revisions retval = {} item_marshaled = marshal(result.__dict__, ITEM_FIELDS) item_marshaled = dict(item_marshaled.items() + {'account': result.account.name}.items() + {'technology': result.technology.name}.items()) retval['item'] = item_marshaled retval['issues'] = [] retval['auth'] = self.auth_dict comments_marshaled = [] for comment in result.comments: comment_marshaled = marshal(comment, ITEM_COMMENT_FIELDS) comment_marshaled = dict(comment_marshaled.items() + {'user': comment.user.email}.items()) comments_marshaled.append(comment_marshaled) retval['comments'] = comments_marshaled for issue in result.issues: issue_marshaled = marshal(issue.__dict__, AUDIT_FIELDS) if issue.user is not None: issue_marshaled = dict( issue_marshaled.items() + {'justified_user': issue.user.email}.items()) retval['issues'].append(issue_marshaled) retval['revisions'] = [] for revision in result.revisions: revision_marshaled = marshal(revision.__dict__, REVISION_FIELDS) revision_marshaled = dict(revision_marshaled.items() + {'config': revision.config}.items()) retval['revisions'].append(revision_marshaled) return retval, 200
def get(self): """ .. http:get:: /api/1/ignorelistentries Get a list of Ignorelist entries. **Example Request**: .. sourcecode:: http GET /api/1/ignorelistentries HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example Response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { count: 1, items: [ { "id": 123, "prefix": "noisy_", "notes": "Security Monkey shouldn't track noisy_* objects", "technology": "securitygroup" }, ], total: 1, page: 1, auth: { authenticated: true, user: "******" } } :statuscode 200: no error :statuscode 401: Authentication failure. Please login. """ auth, retval = __check_auth__(self.auth_dict) if auth: return retval self.reqparse.add_argument('count', type=int, default=30, location='args') self.reqparse.add_argument('page', type=int, default=1, location='args') args = self.reqparse.parse_args() page = args.pop('page', None) count = args.pop('count', None) result = IgnoreListEntry.query.order_by(IgnoreListEntry.id).paginate( page, count, error_out=False) items = [] for entry in result.items: ignorelistentry_marshaled = marshal(entry.__dict__, IGNORELIST_FIELDS) ignorelistentry_marshaled["technology"] = entry.technology.name items.append(ignorelistentry_marshaled) marshaled_dict = { 'total': result.total, 'count': len(items), 'page': result.page, 'items': items, 'auth': self.auth_dict } return marshaled_dict, 200