diff --git a/api.py b/api.py index 70cbdfb2f..d8346f90b 100755 --- a/api.py +++ b/api.py @@ -21,32 +21,39 @@ import sys arguments = len(sys.argv) - 1 +syntax = """=== Wekan API Python CLI: Shows IDs for addcard === +# AUTHORID is USERID that writes card or custom field. +If *nix: chmod +x api.py => ./api.py users + Syntax: + User API: + python3 api.py user # Current user and list of current user boards + python3 api.py boards USERID # Boards of USERID + python3 api.py swimlanes BOARDID # Swimlanes of BOARDID + python3 api.py lists BOARDID # Lists of BOARDID + python3 api.py list BOARDID LISTID # Info of LISTID + python3 api.py createlist BOARDID LISTTITLE # Create list + python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION + python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION + python3 api.py customfields BOARDID # Custom Fields of BOARDID + python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID + python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board + python3 api.py listattachments BOARDID # List attachments + + Admin API: + python3 api.py users # All users + python3 api.py boards # All Public Boards + python3 api.py newuser USERNAME EMAIL PASSWORD +""" + if arguments == 0: - print("=== Wekan API Python CLI: Shows IDs for addcard ===") - print("AUTHORID is USERID that writes card.") - print("If *nix: chmod +x api.py => ./api.py users") - print("Syntax:") - print(" python3 api.py users # All users") - print(" python3 api.py boards # All Public Boards") - print(" python3 api.py boards USERID # Boards of USERID") - print(" python3 api.py board BOARDID # Info of BOARDID") - print(" python3 api.py customfields BOARDID # Custom Fields of BOARDID") - print(" python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID") - print(" python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board") - print(" python3 api.py swimlanes BOARDID # Swimlanes of BOARDID") - print(" python3 api.py lists BOARDID # Lists of BOARDID") - print(" python3 api.py list BOARDID LISTID # Info of LISTID") - print(" python3 api.py createlist BOARDID LISTTITLE # Create list") - print(" python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION") - print(" python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION") - print(" python3 api.py listattachments BOARDID # List attachments") - print(" python3 api.py newuser USERNAME EMAIL PASSWORD") + print(syntax) + exit + # TODO: # print(" python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64") # print(" python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file") # print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file") # print(" python3 api.py attachmentsdownload BOARDID # All attachments as files") - exit # ------- SETTINGS START ------------- @@ -62,33 +69,6 @@ wekanurl = 'http://localhost:4000/' # ------- SETTINGS END ------------- """ -EXAMPLE: - -python3 api.py - -OR: -chmod +x api.py -./api.py - -=== Wekan API Python CLI: Shows IDs for addcard === -AUTHORID is USERID that writes card. -Syntax: - python3 api.py users # All users - python3 api.py boards USERID # Boards of USERID - python3 api.py board BOARDID # Info of BOARDID - python3 api.py customfields BOARDID # Custom Fields of BOARDID - python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID - python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board - python3 api.py swimlanes BOARDID # Swimlanes of BOARDID - python3 api.py lists BOARDID # Lists of BOARDID - python3 api.py list BOARDID LISTID # Info of LISTID - python3 api.py createlist BOARDID LISTTITLE # Create list - python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION - python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION - python3 api.py listattachments BOARDID # List attachments - python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64 - python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file - === ADD CUSTOM FIELD TO BOARD === Type: text, number, date, dropdown, checkbox, currency, stringtemplate. @@ -145,6 +125,8 @@ wekanloginurl = wekanurl + loginurl apiboards = 'api/boards/' apiattachments = 'api/attachments/' apiusers = 'api/users' +apiuser = 'api/user' +apiallusers = 'api/allusers' e = 'export' s = '/' l = 'lists' @@ -153,10 +135,13 @@ sws = 'swimlanes' cs = 'cards' cf = 'custom-fields' bs = 'boards' +apbs = 'allpublicboards' atl = 'attachmentslist' at = 'attachment' ats = 'attachments' users = wekanurl + apiusers +user = wekanurl + apiuser +allusers = wekanurl + apiallusers # ------- API URL GENERATION END ----------- @@ -372,6 +357,16 @@ if arguments == 1: print(data2) # ------- LIST OF USERS END ----------- + if sys.argv[1] == 'user': + # ------- LIST OF ALL USERS START ----------- + headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)} + print(user) + print("=== USER ===\n") + body = requests.get(user, headers=headers) + data2 = body.text.replace('}',"}\n") + print(data2) + # ------- LIST OF ALL USERS END ----------- + if sys.argv[1] == 'boards': # ------- LIST OF PUBLIC BOARDS START ----------- diff --git a/models/boards.js b/models/boards.js index b98c02048..153e369c2 100644 --- a/models/boards.js +++ b/models/boards.js @@ -2002,12 +2002,12 @@ if (Meteor.isServer) { */ JsonRoutes.add('GET', '/api/boards/:boardId', function(req, res) { try { - Authentication.checkUserId(req.userId); - const id = req.params.boardId; + const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, - data: Boards.findOne({ _id: id }), + data: Boards.findOne({ _id: paramBoardId }), }); } catch (error) { JsonRoutes.sendResult(res, { @@ -2120,8 +2120,8 @@ if (Meteor.isServer) { * @return_type string */ JsonRoutes.add('PUT', '/api/boards/:boardId/labels', function(req, res) { - Authentication.checkUserId(req.userId); const id = req.params.boardId; + Authentication.checkBoardAccess(req.userId, id); try { if (req.body.hasOwnProperty('label')) { const board = Boards.findOne({ _id: id }); @@ -2214,8 +2214,8 @@ if (Meteor.isServer) { * swimlaneId: string}] */ JsonRoutes.add('GET', '/api/boards/:boardId/attachments', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Attachments.files diff --git a/models/cardComments.js b/models/cardComments.js index d580e91ca..d4ba53385 100644 --- a/models/cardComments.js +++ b/models/cardComments.js @@ -235,9 +235,9 @@ if (Meteor.isServer) { res, ) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: CardComments.find({ @@ -273,10 +273,10 @@ if (Meteor.isServer) { '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCommentId = req.params.commentId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: CardComments.findOne({ @@ -309,9 +309,9 @@ if (Meteor.isServer) { '/api/boards/:boardId/cards/:cardId/comments', function (req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const id = CardComments.direct.insert({ userId: req.body.authorId, text: req.body.comment, @@ -355,10 +355,10 @@ if (Meteor.isServer) { '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCommentId = req.params.commentId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); CardComments.remove({ _id: paramCommentId, cardId: paramCardId, diff --git a/models/cards.js b/models/cards.js index e30483aa1..b1c6d7608 100644 --- a/models/cards.js +++ b/models/cards.js @@ -3202,9 +3202,9 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/swimlanes/:swimlaneId/cards', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramSwimlaneId = req.params.swimlaneId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Cards.find({ @@ -3244,9 +3244,9 @@ if (Meteor.isServer) { req, res, ) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Cards.find({ @@ -3281,10 +3281,10 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Cards.findOne({ @@ -3497,10 +3497,10 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( 'PUT', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); if (req.body.hasOwnProperty('title')) { const newTitle = req.body.title; @@ -3855,10 +3855,10 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( 'DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const card = Cards.findOne({ _id: paramCardId, @@ -3895,10 +3895,10 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( 'GET', '/api/boards/:boardId/cardsByCustomField/:customFieldId/:customFieldValue', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCustomFieldId = req.params.customFieldId; const paramCustomFieldValue = req.params.customFieldValue; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Cards.find({ diff --git a/models/checklistItems.js b/models/checklistItems.js index e9ad17c44..a93b75a8d 100644 --- a/models/checklistItems.js +++ b/models/checklistItems.js @@ -265,9 +265,9 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramItemId = req.params.itemId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const checklistItem = ChecklistItems.findOne({ _id: paramItemId }); if (checklistItem) { JsonRoutes.sendResult(res, { @@ -299,9 +299,9 @@ if (Meteor.isServer) { 'PUT', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramItemId = req.params.itemId; + Authentication.checkBoardAccess(req.userId, paramBoardId); function isTrue(data) { try { @@ -350,9 +350,9 @@ if (Meteor.isServer) { 'DELETE', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramItemId = req.params.itemId; + Authentication.checkBoardAccess(req.userId, paramBoardId); ChecklistItems.direct.remove({ _id: paramItemId }); JsonRoutes.sendResult(res, { code: 200, diff --git a/models/checklists.js b/models/checklists.js index e974ffef7..302becdb9 100644 --- a/models/checklists.js +++ b/models/checklists.js @@ -248,9 +248,9 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/cards/:cardId/checklists', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const checklists = Checklists.find({ cardId: paramCardId }).map(function( doc, ) { @@ -292,10 +292,10 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramChecklistId = req.params.checklistId; const paramCardId = req.params.cardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const checklist = Checklists.findOne({ _id: paramChecklistId, cardId: paramCardId, @@ -336,10 +336,10 @@ if (Meteor.isServer) { 'POST', '/api/boards/:boardId/cards/:cardId/checklists', function(req, res) { - Authentication.checkUserId(req.userId); // Check user is logged in //Authentication.checkLoggedIn(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); // Check user has permission to add checklist to the card const board = Boards.findOne({ _id: paramBoardId, @@ -398,9 +398,9 @@ if (Meteor.isServer) { 'DELETE', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramChecklistId = req.params.checklistId; + Authentication.checkBoardAccess(req.userId, paramBoardId); Checklists.remove({ _id: paramChecklistId }); JsonRoutes.sendResult(res, { code: 200, diff --git a/models/customFields.js b/models/customFields.js index c4098e498..30c48f589 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -301,8 +301,8 @@ if (Meteor.isServer) { req, res, ) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: CustomFields.find({ boardIds: { $in: [paramBoardId] } }).map( @@ -330,9 +330,9 @@ if (Meteor.isServer) { 'GET', '/api/boards/:boardId/custom-fields/:customFieldId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCustomFieldId = req.params.customFieldId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: CustomFields.findOne({ @@ -361,8 +361,8 @@ if (Meteor.isServer) { req, res, ) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const board = Boards.findOne({ _id: paramBoardId }); const id = CustomFields.direct.insert({ name: req.body.name, @@ -406,9 +406,9 @@ if (Meteor.isServer) { 'PUT', '/api/boards/:boardId/custom-fields/:customFieldId', (req, res) => { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramFieldId = req.params.customFieldId; + Authentication.checkBoardAccess(req.userId, paramBoardId); if (req.body.hasOwnProperty('name')) { CustomFields.direct.update( @@ -479,9 +479,9 @@ if (Meteor.isServer) { 'POST', '/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items', (req, res) => { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramCustomFieldId = req.params.customFieldId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const paramItems = req.body.items; if (req.body.hasOwnProperty('items')) { @@ -522,10 +522,10 @@ if (Meteor.isServer) { 'PUT', '/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items/:dropdownItemId', (req, res) => { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramDropdownItemId = req.params.dropdownItemId; const paramCustomFieldId = req.params.customFieldId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const paramName = req.body.name; if (req.body.hasOwnProperty('name')) { @@ -563,10 +563,10 @@ if (Meteor.isServer) { 'DELETE', '/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items/:dropdownItemId', (req, res) => { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; paramCustomFieldId = req.params.customFieldId; paramDropdownItemId = req.params.dropdownItemId; + Authentication.checkBoardAccess(req.userId, paramBoardId); CustomFields.direct.update( { _id: paramCustomFieldId }, @@ -598,8 +598,8 @@ if (Meteor.isServer) { 'DELETE', '/api/boards/:boardId/custom-fields/:customFieldId', function(req, res) { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const id = req.params.customFieldId; CustomFields.remove({ _id: id, boardIds: { $in: [paramBoardId] } }); JsonRoutes.sendResult(res, { diff --git a/models/lists.js b/models/lists.js index 09be14248..50f7a7803 100644 --- a/models/lists.js +++ b/models/lists.js @@ -493,8 +493,8 @@ if (Meteor.isServer) { */ JsonRoutes.add('GET', '/api/boards/:boardId/lists', function(req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, @@ -528,9 +528,9 @@ if (Meteor.isServer) { res, ) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, data: Lists.findOne({ @@ -557,8 +557,8 @@ if (Meteor.isServer) { */ JsonRoutes.add('POST', '/api/boards/:boardId/lists', function(req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); const board = Boards.findOne(paramBoardId); const id = Lists.insert({ title: req.body.title, @@ -595,9 +595,9 @@ if (Meteor.isServer) { res, ) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); Lists.remove({ _id: paramListId, boardId: paramBoardId }); JsonRoutes.sendResult(res, { code: 200, diff --git a/models/swimlanes.js b/models/swimlanes.js index 30384a860..04a4f4e2a 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -399,8 +399,8 @@ if (Meteor.isServer) { */ JsonRoutes.add('GET', '/api/boards/:boardId/swimlanes', function(req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); JsonRoutes.sendResult(res, { code: 200, @@ -435,9 +435,10 @@ if (Meteor.isServer) { res, ) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramSwimlaneId = req.params.swimlaneId; + Authentication.checkBoardAccess(req.userId, paramBoardId); + JsonRoutes.sendResult(res, { code: 200, data: Swimlanes.findOne({ @@ -465,8 +466,9 @@ if (Meteor.isServer) { */ JsonRoutes.add('POST', '/api/boards/:boardId/swimlanes', function(req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; + Authentication.checkBoardAccess(req.userId, paramBoardId); + const board = Boards.findOne(paramBoardId); const id = Swimlanes.insert({ title: req.body.title, @@ -503,9 +505,9 @@ if (Meteor.isServer) { '/api/boards/:boardId/swimlanes/:swimlaneId', function(req, res) { try { - Authentication.checkUserId(req.userId); const paramBoardId = req.params.boardId; const paramSwimlaneId = req.params.swimlaneId; + Authentication.checkBoardAccess(req.userId, paramBoardId); Swimlanes.remove({ _id: paramSwimlaneId, boardId: paramBoardId }); JsonRoutes.sendResult(res, { code: 200,