diff --git a/api-doc/reference/Admin-API.v1.yaml b/api-doc/reference/Admin-API.v1.yaml index 9bb56b5ccde62a74c396cf6fb69d34c4e55f5328..5d4df4d67522a23fd146f9075c1e0593a9f0899e 100644 --- a/api-doc/reference/Admin-API.v1.yaml +++ b/api-doc/reference/Admin-API.v1.yaml @@ -17,6 +17,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Device' + examples: {} operationId: get-api-admin-device requestBody: description: '' @@ -29,19 +30,41 @@ paths: type: string in: query name: deviceId - description: Returns the device information. + description: Returns the device detailed information. put: summary: '' operationId: put-api-admin-device responses: '200': description: OK + '500': + description: Internal Server Error + description: Update device data. + parameters: + - schema: + type: string + in: query + name: username + - schema: + type: string + in: query + name: deviceId + - schema: + type: string + in: query + name: deviceName delete: summary: '' operationId: delete-api-admin-device responses: '200': description: OK + content: + application/json: + schema: + $ref: './User-API.v1.yaml#/components/schemas/DeviceRevocationResponse' + '500': + description: Internal Server Error parameters: - schema: type: string @@ -71,61 +94,161 @@ paths: type: string in: query name: username + description: Get a list of devices for a user. /api/admin/directory/entry: - get: - summary: Your GET endpoint - tags: [] - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserProfile' - operationId: get-api-admin-directory-entry - description: '' put: summary: '' operationId: put-api-admin-directory-entry responses: '200': description: OK + description: "Update a user's profile." post: - summary: '' + summary: User profile operationId: post-api-admin-directory-entry responses: '200': description: OK + '500': + description: Internal Server Error + description: Create a user profile. + parameters: + - schema: + type: string + in: query + name: directory + delete: + summary: '' + operationId: delete-api-admin-directory-entry + responses: + '200': + description: OK + description: Method might probably never be implemented. /api/admin/user: get: - summary: Your GET endpoint + summary: User profile - User tags: [] - responses: {} + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UserProfile' operationId: get-api-admin-user + description: "Get the user's profile." + parameters: + - schema: + type: string + in: query + name: username post: summary: '' operationId: post-api-admin-user responses: '200': description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Create an internal user. delete: summary: '' operationId: delete-api-admin-user responses: '200': description: OK + content: + application/json: + schema: + $ref: './User-API.v1.yaml#/components/schemas/DeviceRevocationResponse' + '500': + description: Internal Server Error + description: Revoke a user. + parameters: + - schema: + type: string + in: query + name: username put: summary: '' operationId: put-api-admin-user responses: '200': description: OK + '500': + description: Internal Server Error + description: Update User data. + parameters: + - schema: + type: string + in: query + name: username + - schema: + type: string + in: query + name: password /api/admin/users: get: - summary: Your GET endpoint + summary: Users Profile tags: [] - responses: {} + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/UserProfile' operationId: get-api-admin-users + description: Return a list of users. + /api/subscription: + get: + summary: Subscription status - License + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SubscriptionStatusResponse' + headers: + Access-Control-Allow-Origin: + schema: + type: string + description: Server Domain of Certificate Authority + operationId: get-api-subscription + description: Get the subscription status. + post: + summary: '' + operationId: post-api-subscription + responses: + '200': + description: OK + description: 'Upload the license here, which is basically just uploading a base64 representation of the keypair - and store on disk.' + /api/update: + get: + summary: System Status + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/FullSystemStatusResponse' + operationId: get-api-update + description: Return the current version number and the available version number of Jams(for update). + post: + summary: '' + operationId: post-api-update + responses: + '200': + description: OK + description: Update the version. components: schemas: Device: @@ -164,3 +287,65 @@ components: organization: type: string description: "The user's extended information which is not critical to Jami operations, usually provided by LDAP, Active Directory or other backend." + User: + title: User + type: object + properties: + username: + type: string + password: + type: string + userType: + type: string + enum: + - AD + - LDAP + - LOCAL + realm: + type: string + accessLevel: + type: string + enum: + - ADMIN + - USER + needsPasswordReset: + type: boolean + ethAddress: + type: string + ethKey: + type: string + jamiId: + type: string + SubscriptionStatusResponse: + title: SubscriptionStatusResponse + type: object + properties: + licenseInformation: + $ref: '#/components/schemas/LicenseInformation' + activated: + type: boolean + versions: + type: object + LicenseInformation: + title: LicenseInformation + type: object + properties: + type: + type: string + enum: + - COMMUNITY + - PREMIUM + products: + type: array + items: + type: string + FullSystemStatusResponse: + title: FullSystemStatusResponse + type: object + properties: + localVersions: + type: object + remoteVersions: + type: object + updateAvailable: + type: boolean diff --git a/api-doc/reference/Install-API.v1.yaml b/api-doc/reference/Install-API.v1.yaml index 03b15027dd565d4523768b30618c33b3af4fbcc2..0e3c6958d078a65c7456f63f8589cb2c69531580 100644 --- a/api-doc/reference/Install-API.v1.yaml +++ b/api-doc/reference/Install-API.v1.yaml @@ -13,6 +13,20 @@ paths: responses: '200': description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AuthTokenResponse' + '500': + description: Internal Server Error + description: 'Configure Server to use selected Authentication Source as authentication backend, save settings in config.json file.' + get: + summary: Authentication Source + operationId: get-api-install-auth + responses: + '200': + description: OK + description: "Get server's Authentication Source." /api/install/ca: post: summary: '' @@ -20,6 +34,16 @@ paths: responses: '200': description: OK + '500': + description: Internal Server Error + description: Save Certificate Authority. + get: + summary: Certificate Request + operationId: get-api-install-ca + responses: + '200': + description: OK + description: Get Certificate Authority. /api/install/settings: post: summary: '' @@ -27,6 +51,16 @@ paths: responses: '200': description: OK + '500': + description: Internal Server Error + description: Finish Server installation. + get: + summary: '' + operationId: get-api-install-settings + responses: + '200': + description: OK + description: Get Server Settings. /api/install/start: post: summary: '' @@ -34,5 +68,52 @@ paths: responses: '200': description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AuthTokenResponse' + '403': + description: Forbidden + description: Authenticate user. + get: + summary: '' + operationId: get-api-install-start + responses: + '200': + description: OK + headers: + showLogin: + schema: + type: boolean + description: 'true' + description: Check if user should login or sign-up. + put: + summary: '' + operationId: put-api-install-start + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AuthTokenResponse' + '500': + description: Internal Server Error + description: Create administrative user account. components: - schemas: {} + schemas: + AuthTokenResponse: + title: AuthTokenResponse + type: object + properties: + token_type: + type: string + access_token: + type: string + expires_in: + type: number + scope: + type: string + enum: + - ADMIN + - USER diff --git a/api-doc/reference/Nameserver-API.v1.yaml b/api-doc/reference/Nameserver-API.v1.yaml index baec648acd279ccffc6982dde2375a150fde71fa..ae9de47f4fb8fb0b9f784282974d308c669fc393 100644 --- a/api-doc/reference/Nameserver-API.v1.yaml +++ b/api-doc/reference/Nameserver-API.v1.yaml @@ -16,8 +16,17 @@ paths: get: summary: Address lookup tags: [] - responses: {} + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AddrLookupResponse' + '404': + description: Not Found operationId: get-api-nameserver-addr-addr + description: Get Username from Adress. '/api/nameserver/name/{name}': parameters: - schema: @@ -31,6 +40,31 @@ paths: responses: '200': description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/NameLookupResponse' + '404': + description: Not Found operationId: get-api-nameserver-name-name + description: Get Address from username. components: - schemas: {} + schemas: + AddrLookupResponse: + title: AddrLookupResponse + type: object + properties: + name: + type: string + NameLookupResponse: + title: NameLookupResponse + type: object + properties: + name: + type: string + addr: + type: string + publicKey: + type: string + signature: + type: string diff --git a/api-doc/reference/Security-API.v1.yaml b/api-doc/reference/Security-API.v1.yaml index 05e04371a9b6cb270e7d0e9da2c43d8a9f947117..0b8d608963b591e75322988f87a5afa3d105081b 100644 --- a/api-doc/reference/Security-API.v1.yaml +++ b/api-doc/reference/Security-API.v1.yaml @@ -12,5 +12,66 @@ paths: responses: '200': description: OK + content: + application/json: + schema: + $ref: './Install-API.v1.yaml#/components/schemas/AuthTokenResponse' + '403': + description: Forbidden + description: This method returns the token which is used for all the next calls to the API. + parameters: + - schema: + type: string + in: query + name: username + - schema: + type: string + in: query + name: password + - schema: + type: string + in: header + name: authorization + /api/auth/contacts: + get: + summary: User contacts + tags: [] + responses: {} + operationId: get-api-auth-contacts + description: "Get User's contacts" + put: + summary: '' + operationId: put-api-auth-contacts + responses: + '200': + description: OK + description: "Update User's contact." + delete: + summary: '' + operationId: delete-api-auth-contacts + responses: + '200': + description: OK + description: "Delete user's contact." + /api/auth/ocsp: + get: + summary: OCSP + tags: [] + responses: {} + operationId: get-api-auth-ocsp + description: Get OCSP. + /api/auth/crl: + get: + summary: CRL + tags: [] + responses: + '200': + description: OK + content: + text/plain: + schema: + type: string + operationId: get-api-auth-crl + description: Get CRL. components: schemas: {} diff --git a/api-doc/reference/User-API.v1.yaml b/api-doc/reference/User-API.v1.yaml index 07b6a4c77b933afdd75ed1daade127caaaa78e9d..fa5e3f9e44a2b2786629907657ce9c2036052190 100644 --- a/api-doc/reference/User-API.v1.yaml +++ b/api-doc/reference/User-API.v1.yaml @@ -11,6 +11,21 @@ paths: tags: [] responses: {} operationId: get-api-auth-contacts + description: "Get User's contacts." + put: + summary: '' + operationId: put-api-auth-contacts + responses: + '200': + description: OK + description: "Update User's contact." + delete: + summary: '' + operationId: delete-api-auth-contacts + responses: + '200': + description: OK + description: "Delete user's contact." '/api/auth/device/{deviceId}': parameters: - schema: @@ -29,12 +44,21 @@ paths: schema: $ref: './Admin-API.v1.yaml#/components/schemas/Device' operationId: get-api-auth-device-deviceId + description: "Get a user's specified device." put: summary: '' operationId: put-api-auth-device-deviceId responses: '200': description: OK + '500': + description: Internal Server Error + description: "Update a user's device informations." + parameters: + - schema: + type: string + in: query + name: deviceName post: summary: '' operationId: post-api-auth-device-deviceId @@ -44,7 +68,23 @@ paths: content: application/json: schema: - allOf: [] + $ref: '#/components/schemas/DeviceRegistrationResponse' + '500': + description: Internal Server Error + description: Create/Store a device for a user. + delete: + summary: '' + operationId: delete-api-auth-device-deviceId + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceRevocationResponse' + '500': + description: Internal Server Error + description: "Delete a user's device." /api/auth/devices: get: summary: Get the list of devices @@ -59,12 +99,22 @@ paths: items: $ref: './Admin-API.v1.yaml#/components/schemas/Device' operationId: get-api-auth-devices + description: "Get user's devices." /api/auth/directories: get: - summary: Get the directories connect to JAMS + summary: "Get the directories connect to JAMS, Authentication Sources' Directories" tags: [] - responses: {} + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AuthModuleKey' operationId: get-api-auth-directories + description: Get directories in Authentication Sources (Local/AD/LDAP). /api/auth/directory/entry: get: summary: Get the profile of a user @@ -77,6 +127,14 @@ paths: schema: $ref: './Admin-API.v1.yaml#/components/schemas/UserProfile' operationId: get-api-auth-directory-entry + description: 'This is an endpoint to manipulate directory entry-data, this make sense only for local setups. Get a user profile from a directory.' + put: + summary: '' + operationId: put-api-auth-directory-entry + responses: + '200': + description: OK + description: Modify a profile only in the case of a LOCAL directory. /api/auth/directory/search: get: summary: Search the directory @@ -98,14 +156,65 @@ paths: items: $ref: './Admin-API.v1.yaml#/components/schemas/UserProfile' operationId: get-api-auth-directory-search + description: Search user profiles in directory. /api/auth/user: get: summary: User endpoint tags: [] - responses: {} + responses: + '200': + description: OK operationId: get-api-auth-user + description: "Read user's profile (User can \"read\" his own profile)." + put: + summary: '' + operationId: put-api-auth-user + responses: + '200': + description: OK + '500': + description: Internal Server Error + description: "Update some user profile's fields(password, privatekey, publickey) if authentication source is LOCAL." components: - schemas: {} + schemas: + DeviceRegistrationResponse: + title: DeviceRegistrationResponse + type: object + properties: + certificateChain: + type: string + displayName: + type: string + nameServer: + type: string + deviceReceipt: + type: string + receiptSignature: + type: string + userPhoto: + type: string + DeviceRevocationResponse: + title: DeviceRevocationResponse + type: object + properties: + success: + type: boolean + errorDetails: + type: string + timestamp: + type: string + AuthModuleKey: + title: AuthModuleKey + type: object + properties: + realm: + type: string + type: + type: string + enum: + - AD + - LDAP + - LOCAL securitySchemes: API Key - 1: name: API Key diff --git a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java index ffbca27b868807ce98d7fc2ef74ebb7ab41c2904..06968295ad130f6b35e5404b570e5292a0795dec 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java @@ -26,6 +26,7 @@ import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; +import net.jami.jams.common.dao.DeleteStatementBuilder; import net.jami.jams.common.dao.SelectStatementBuilder; import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.dao.UpdateStatementBuilder; @@ -34,7 +35,6 @@ import net.jami.jams.common.dao.connectivity.SQLConnection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; @Slf4j @@ -46,7 +46,6 @@ public abstract class AbstractDao<T> { private Class<T> tClass; public abstract boolean storeObject(T object); - public abstract boolean deleteObject(LinkedHashMap<String,String> constraints); public List<T> getObjects(StatementList constraints){ List<T> result = new ArrayList<>(); @@ -82,4 +81,20 @@ public abstract class AbstractDao<T> { DataStore.connectionPool.returnConnection(connection); } } + + public boolean deleteObject(StatementList delete){ + SQLConnection connection = DataStore.connectionPool.getConnection(); + try{ + PreparedStatement ps = DeleteStatementBuilder.buildStatement(tableName,delete,connection); + return ps.execute(); + } + catch (Exception e){ + log.error("An error has occurred while trying to fetch a device: " + e.toString()); + return false; + } + finally { + DataStore.connectionPool.returnConnection(connection); + } + } + } diff --git a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java index 1e33d86b870963fd13319a7f4ef1047d97fceb23..ac39587e242fdca3ef2aa509b661ac9e4c9abb22 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java @@ -22,25 +22,40 @@ */ package net.jami.datastore.dao; -import net.jami.jams.common.dao.StatementList; +import lombok.extern.slf4j.Slf4j; +import net.jami.datastore.main.DataStore; +import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.contacts.Contact; -import java.util.LinkedHashMap; +import java.sql.PreparedStatement; +import java.sql.SQLException; +@Slf4j public class ContactDao extends AbstractDao<Contact> { - @Override - public boolean storeObject(Contact object) { - return false; - } - - @Override - public boolean deleteObject(LinkedHashMap<String, String> constraints) { - return false; + public ContactDao() { + SQLConnection connection = DataStore.connectionPool.getConnection(); + try { + this.setTableName("contacts"); + this.setTClass(Contact.class); + String createTable = "CREATE TABLE contacts (" + + "owner varchar(255), " + + "contact varchar(255)," + + "displayName varchar(255),"+ + "PRIMARY KEY (owner,contact))"; + PreparedStatement ps = connection.getConnection().prepareStatement(createTable); + ps.execute(); + } + catch (SQLException e){ + log.error("Could not create the contacts table with error " + e.getMessage()); + } + finally { + DataStore.connectionPool.returnConnection(connection); + } } @Override - public boolean updateObject(StatementList update, StatementList constraints) { + public boolean storeObject(Contact object) { return false; } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java index 6af5941495ee0edb7f6a933f9a93004e25a63f06..2c5f897889c8d566fb347f71d3ad4bd6cd48fc54 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java @@ -30,7 +30,6 @@ import net.jami.jams.common.objects.devices.Device; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.LinkedHashMap; @Slf4j public class DeviceDao extends AbstractDao<Device> { @@ -78,11 +77,6 @@ public class DeviceDao extends AbstractDao<Device> { } } - @Override - public boolean deleteObject(LinkedHashMap<String, String> constraints) { - return false; - } - @Override public boolean updateObject(StatementList update, StatementList constraints) { return false; diff --git a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java index 7cb9e1587a8ab624870a486a862c109cc27722be..5f0a9df589064180e6866e4ea64f032ed5a4744b 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java @@ -30,7 +30,6 @@ import net.jami.jams.common.objects.system.SystemAccount; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.LinkedHashMap; @Slf4j public class SystemDao extends AbstractDao<SystemAccount> { @@ -76,11 +75,6 @@ public class SystemDao extends AbstractDao<SystemAccount> { } } - @Override - public boolean deleteObject(LinkedHashMap<String, String> constraints) { - return false; - } - @Override public boolean updateObject(StatementList update, StatementList constraints) { return false; diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java index e5b75b84902df1a90abb9fd8f39c77c4985d5ac6..2c46552e98c53678012531bed779b92f4a337e7b 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java @@ -29,7 +29,6 @@ import net.jami.jams.common.objects.user.User; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.LinkedHashMap; @Slf4j public class UserDao extends AbstractDao<User> { @@ -83,10 +82,4 @@ public class UserDao extends AbstractDao<User> { DataStore.connectionPool.returnConnection(connection); } } - - - @Override - public boolean deleteObject(LinkedHashMap<String, String> constraints) { - return false; - } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDAO.java b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java similarity index 90% rename from datastore/src/main/java/net/jami/datastore/dao/UserProfileDAO.java rename to datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java index 1f1d4096fde5916969f9a52fb243c8ca9231d854..e2df45111a4afc700662fdea0e68558306ca559e 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDAO.java +++ b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java @@ -29,13 +29,12 @@ import net.jami.jams.common.objects.user.UserProfile; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.LinkedHashMap; @Slf4j -public class UserProfileDAO extends AbstractDao<UserProfile> { +public class UserProfileDao extends AbstractDao<UserProfile> { //Fis this to include the fields from AD/LDAP. - public UserProfileDAO() { + public UserProfileDao() { SQLConnection connection = DataStore.connectionPool.getConnection(); try { this.setTableName("local_directory"); @@ -60,9 +59,4 @@ public class UserProfileDAO extends AbstractDao<UserProfile> { public boolean storeObject(UserProfile object) { return false; } - - @Override - public boolean deleteObject(LinkedHashMap<String, String> constraints) { - return false; - } } diff --git a/datastore/src/main/java/net/jami/datastore/main/DataStore.java b/datastore/src/main/java/net/jami/datastore/main/DataStore.java index 41ed66eefbed2b3d301b0ed153d381eab663ba7f..852cdaeafea5f50450e8183b5342a1c0decf2418 100644 --- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java +++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java @@ -24,6 +24,7 @@ package net.jami.datastore.main; import lombok.Getter; import lombok.Setter; +import net.jami.datastore.dao.ContactDao; import net.jami.datastore.dao.DeviceDao; import net.jami.datastore.dao.SystemDao; import net.jami.datastore.dao.UserDao; @@ -46,6 +47,7 @@ public class DataStore implements AuthenticationSource { private UserDao userDao; private DeviceDao deviceDao; private SystemDao systemDao; + private ContactDao contactDao; //Implicitly connect to debry. public DataStore(String connectionString) { @@ -53,6 +55,7 @@ public class DataStore implements AuthenticationSource { userDao = new UserDao(); deviceDao = new DeviceDao(); systemDao = new SystemDao(); + contactDao = new ContactDao(); } public boolean userExists(String username){ diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..8c3d05f6edd63e10845b5ea6e26975c3ab194a5c --- /dev/null +++ b/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java @@ -0,0 +1,60 @@ +/* +* Copyright (C) 2020 by Savoir-faire Linux +* Authors: William Enright <william.enright@savoirfairelinux.com> +* Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> +* Johnny Flores <johnny.flores@savoirfairelinux.com> +* Mohammed Raza <mohammed.raza@savoirfairelinux.com> +* Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +package net.jami.jams.common.dao; + +import net.jami.jams.common.dao.connectivity.SQLConnection; + +import java.sql.PreparedStatement; + +public class DeleteStatementBuilder { + + public static PreparedStatement buildStatement(String table, StatementList statementElements, + SQLConnection connection) throws Exception { + PreparedStatement ps = null; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("DELETE FROM ").append(table); + if(statementElements != null) { + stringBuilder.append(" WHERE "); + for (StatementElement statementElement : statementElements.getStatements()) { + stringBuilder + .append(statementElement.getColumn()) + .append(" ") + .append(statementElement.getOperator()) + .append(" ") + .append("?") + .append(" ") + .append(statementElement.getNextStatementRelation()); + } + ps = connection.getConnection().prepareStatement(stringBuilder.toString()); + int i = 1; + for (StatementElement statementElement : statementElements.getStatements()) { + ps.setString(i, statementElement.getValue()); + i++; + } + } + else{ + ps = connection.getConnection().prepareStatement(stringBuilder.toString()); + } + return ps; + } +} diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/contacts/Contact.java b/jams-common/src/main/java/net/jami/jams/common/objects/contacts/Contact.java index 2804fd9605299b4dbd70e598aaf4c8e4388388a2..dfcf11b391b0b0dcc43ead99a63f88183f40affa 100644 --- a/jams-common/src/main/java/net/jami/jams/common/objects/contacts/Contact.java +++ b/jams-common/src/main/java/net/jami/jams/common/objects/contacts/Contact.java @@ -22,10 +22,46 @@ */ package net.jami.jams.common.objects.contacts; +import com.jsoniter.annotation.JsonIgnore; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; +import net.jami.jams.common.serialization.database.DatabaseObject; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; @Getter @Setter -public class Contact { +@NoArgsConstructor +public class Contact implements DatabaseObject { + + @JsonIgnore //Ignore the owner because he is irrelevant. + private String owner; + private String uri; + private String displayName; + + public Contact(ResultSet rs) throws Exception { + this.owner = rs.getString("owner"); + this.uri = rs.getString("uri"); + this.displayName = rs.getString("displayName"); + } + + @Override + public PreparedStatement getInsert(PreparedStatement ps) throws Exception { + ps.setString(1,owner); + ps.setString(2,uri); + ps.setString(3,displayName); + return ps; + } + + @Override + public PreparedStatement getDelete(PreparedStatement ps) throws Exception { + return null; + } + + @Override + public PreparedStatement getUpdate(PreparedStatement ps) throws Exception { + return null; + } } diff --git a/jams-common/src/main/java/net/jami/jams/common/serialization/database/DatabaseObject.java b/jams-common/src/main/java/net/jami/jams/common/serialization/database/DatabaseObject.java index 2198d8cac27346ea957e9460e74004d02eedf541..0489430e839adb39190231da637a55253987d813 100644 --- a/jams-common/src/main/java/net/jami/jams/common/serialization/database/DatabaseObject.java +++ b/jams-common/src/main/java/net/jami/jams/common/serialization/database/DatabaseObject.java @@ -25,7 +25,6 @@ package net.jami.jams.common.serialization.database; import java.sql.PreparedStatement; public interface DatabaseObject { - PreparedStatement getInsert(PreparedStatement ps) throws Exception; PreparedStatement getDelete(PreparedStatement ps) throws Exception; PreparedStatement getUpdate(PreparedStatement ps) throws Exception; diff --git a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java index 814a9658155dba0b3b700873d995c33e761e7fda..863b549c20bbedc4ea70d63d1633de73135e775a 100644 --- a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java +++ b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java @@ -23,7 +23,6 @@ package net.jami.jams.server.core; import lombok.extern.slf4j.Slf4j; -import net.jami.jams.server.Server; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.StandardContext; @@ -36,8 +35,6 @@ import org.apache.tomcat.util.descriptor.web.ErrorPage; import java.awt.*; import java.io.File; import java.net.URI; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java index 9b0626fde9b5bb026e0ac1caa672ac7128dfb703..e43a40d46f0535fba9b314d60ca0092882189816 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java @@ -22,28 +22,48 @@ */ package net.jami.jams.server.servlets.api.auth.contacts; +import com.jsoniter.JsonIterator; +import com.jsoniter.output.JsonStream; +import net.jami.jams.common.dao.StatementElement; +import net.jami.jams.common.dao.StatementList; +import net.jami.jams.common.objects.contacts.Contact; + import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.List; + +import static net.jami.jams.server.Server.dataStore; @WebServlet("/api/auth/contacts") public class ContactServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doGet(req, resp); + StatementList statementList = new StatementList(); + statementList.addStatement(new StatementElement("owner","=",req.getAttribute("username").toString(),"")); + List<Contact> contactList = dataStore.getContactDao().getObjects(statementList); + resp.getOutputStream().write(JsonStream.serialize(contactList).getBytes()); } @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doPut(req, resp); + Contact contact = JsonIterator.deserialize(req.getInputStream().readAllBytes(),Contact.class); + contact.setOwner(req.getAttribute("username").toString()); + if(dataStore.getContactDao().storeObject(contact)) resp.setStatus(200); + else resp.sendError(500,"Could not store device!"); } + //TODO: Because deleting requires sending the URI in the body, didn't want to do this now. @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doDelete(req, resp); + StatementList statementList = new StatementList(); + statementList.addStatement(new StatementElement("owner","=",req.getAttribute("username").toString(),"AND")); + statementList.addStatement(new StatementElement("uri","=",req.getParameter("uri"),"")); + if(dataStore.getContactDao().deleteObject(statementList)) resp.setStatus(200); + else resp.sendError(500,"Could not delete a contact!"); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/AdminApiFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/AdminApiFilter.java index 0cf7d3fcf3322820d97b2183eb57e537ad939fdd..de794eb1ab865ad8f858e70f04a516a034320b32 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/AdminApiFilter.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/AdminApiFilter.java @@ -25,16 +25,16 @@ package net.jami.jams.server.servlets.filters; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.SignedJWT; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.server.Server; +import javax.servlet.Filter; +import javax.servlet.FilterChain; import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/ApiFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/ApiFilter.java index a125c4e4e5aab338a623bb974f8a3607350f5f06..2ab0ce4d7fdb81f40d0a364a0768cc6f9445bbe2 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/ApiFilter.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/ApiFilter.java @@ -25,15 +25,15 @@ package net.jami.jams.server.servlets.filters; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.SignedJWT; +import lombok.extern.slf4j.Slf4j; +import net.jami.jams.server.Server; + import javax.servlet.Filter; import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; -import lombok.extern.slf4j.Slf4j; -import net.jami.jams.server.Server; - -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java index af6c2d9a52b189c490a5cd7f215dbc49252fea3c..68e1a23558f34967757794399e01929215553885 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/InstallFilter.java @@ -25,15 +25,15 @@ package net.jami.jams.server.servlets.filters; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.SignedJWT; +import lombok.extern.slf4j.Slf4j; +import net.jami.jams.server.Server; + import javax.servlet.Filter; import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; -import lombok.extern.slf4j.Slf4j; -import net.jami.jams.server.Server; - -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;