diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle
index b99a5b46..062f5655 100644
--- a/docs-android/app/build.gradle
+++ b/docs-android/app/build.gradle
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0-beta1'
+ classpath 'com.android.tools.build:gradle:2.1.0'
}
}
apply plugin: 'com.android.application'
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
index 0c9232cb..0da860a8 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
@@ -87,13 +87,13 @@ public class MainActivity extends AppCompatActivity {
tagListView.setEmptyView(tagProgressView);
JSONObject cacheTags = PreferenceUtil.getCachedJson(this, PreferenceUtil.PREF_CACHED_TAGS_JSON);
if (cacheTags != null) {
- tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("stats")));
+ tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("tags")));
}
- TagResource.stats(this, new HttpCallback() {
+ TagResource.list(this, new HttpCallback() {
@Override
public void onSuccess(JSONObject response) {
PreferenceUtil.setCachedJson(MainActivity.this, PreferenceUtil.PREF_CACHED_TAGS_JSON, response);
- tagListView.setAdapter(new TagListAdapter(response.optJSONArray("stats")));
+ tagListView.setAdapter(new TagListAdapter(response.optJSONArray("tags")));
tagProgressView.setVisibility(View.GONE);
tagListView.setEmptyView(tagEmptyView);
}
@@ -158,6 +158,7 @@ public class MainActivity extends AppCompatActivity {
@Override
public void onFinish() {
// Force logout in all cases, so the user is not stuck in case of network error
+ PreferenceUtil.clearAuthToken(MainActivity.this);
ApplicationContext.getInstance().setUserInfo(getApplicationContext(), null);
startActivity(new Intent(MainActivity.this, LoginActivity.class));
finish();
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
index f921a804..213bd59d 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
@@ -46,7 +46,7 @@ public class TagListAdapter extends BaseAdapter {
// Reorder tags by parent/child relation and compute depth
int depth = 0;
- initTags(tags, JSONObject.NULL.toString(), depth);
+ initTags(tags, "", depth);
}
/**
@@ -60,11 +60,10 @@ public class TagListAdapter extends BaseAdapter {
// Get all tags with this parent
for (JSONObject tag : tags) {
String tagParentId = tag.optString("parent");
- if (tagParentId.equals(parentId)) {
+ if (parentId.equals(tagParentId)) {
TagItem tagItem = new TagItem();
tagItem.id = tag.optString("id");
tagItem.name = tag.optString("name");
- tagItem.count = tag.optInt("count");
tagItem.color = tag.optString("color");
tagItem.depth = depth;
tagItemList.add(tagItem);
@@ -99,8 +98,6 @@ public class TagListAdapter extends BaseAdapter {
TagItem tagItem = getItem(position);
TextView tagTextView = (TextView) view.findViewById(R.id.tagTextView);
tagTextView.setText(tagItem.name);
- TextView tagCountTextView = (TextView) view.findViewById(R.id.tagCountTextView);
- tagCountTextView.setText(String.format(Locale.ENGLISH, "%d", tagItem.count));
// Label color filtering
ImageView labelImageView = (ImageView) view.findViewById(R.id.labelImageView);
@@ -125,7 +122,6 @@ public class TagListAdapter extends BaseAdapter {
public static class TagItem {
private String id;
private String name;
- private int count;
private String color;
private int depth;
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
index 34539d14..f7c17ec4 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
@@ -16,14 +16,14 @@ import okhttp3.Request;
*/
public class TagResource extends BaseResource {
/**
- * GET /tag/stats.
+ * GET /tag/list.
*
* @param context Context
* @param callback Callback
*/
- public static void stats(Context context, HttpCallback callback) {
+ public static void list(Context context, HttpCallback callback) {
Request request = new Request.Builder()
- .url(HttpUrl.parse(getApiUrl(context) + "/tag/stats"))
+ .url(HttpUrl.parse(getApiUrl(context) + "/tag/list"))
.get()
.build();
OkHttpUtil.buildClient(context)
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
index da8537ea..5df8974d 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
@@ -126,6 +126,7 @@ public class PreferenceUtil {
/**
* Returns auth token cookie from shared preferences.
*
+ * @param context Context
* @return Auth token
*/
public static String getAuthToken(Context context) {
@@ -140,6 +141,16 @@ public class PreferenceUtil {
return null;
}
+ /**
+ * Clear all auth tokens.
+ *
+ * @param context Context
+ */
+ public static void clearAuthToken(Context context) {
+ PersistentCookieStore cookieStore = new PersistentCookieStore(context);
+ cookieStore.removeAll();
+ }
+
/**
* Returns cleaned server URL.
*
diff --git a/docs-android/app/src/main/res/layout/tag_list_item.xml b/docs-android/app/src/main/res/layout/tag_list_item.xml
index 2724a7b7..f238f1fb 100644
--- a/docs-android/app/src/main/res/layout/tag_list_item.xml
+++ b/docs-android/app/src/main/res/layout/tag_list_item.xml
@@ -28,17 +28,5 @@
android:textColor="#212121"
android:text="Appartement"
android:textSize="14sp"/>
-
-
\ No newline at end of file
diff --git a/docs-core/pom.xml b/docs-core/pom.xml
index 498aee4b..85e0267d 100644
--- a/docs-core/pom.xml
+++ b/docs-core/pom.xml
@@ -5,7 +5,7 @@
com.sismics.docs
docs-parent
- 1.4-SNAPSHOT
+ 1.5-SNAPSHOT
..
diff --git a/docs-stress/pom.xml b/docs-stress/pom.xml
index e6cb862b..0ea52568 100644
--- a/docs-stress/pom.xml
+++ b/docs-stress/pom.xml
@@ -5,7 +5,7 @@
com.sismics.docs
docs-parent
- 1.4-SNAPSHOT
+ 1.5-SNAPSHOT
..
diff --git a/docs-web-common/pom.xml b/docs-web-common/pom.xml
index 1a736939..5a7e8a30 100644
--- a/docs-web-common/pom.xml
+++ b/docs-web-common/pom.xml
@@ -5,7 +5,7 @@
com.sismics.docs
docs-parent
- 1.4-SNAPSHOT
+ 1.5-SNAPSHOT
..
diff --git a/docs-web/pom.xml b/docs-web/pom.xml
index a3cba6c6..b66010c1 100644
--- a/docs-web/pom.xml
+++ b/docs-web/pom.xml
@@ -5,7 +5,7 @@
com.sismics.docs
docs-parent
- 1.4-SNAPSHOT
+ 1.5-SNAPSHOT
..
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java
index 480b9a51..ea0c7141 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java
@@ -31,7 +31,24 @@ import java.util.List;
public class AclResource extends BaseResource {
/**
* Add an ACL.
- *
+ *
+ * @api {put} /acl Add an ACL
+ * @apiName PutAcl
+ * @apiGroup Acl
+ * @apiParam {String} source Source ID
+ * @apiParam {String="READ","WRITE"} perm Permission
+ * @apiParam {String} target Target ID
+ * @apiParam {String="USER","GROUP","SHARE"} type Target type
+ * @apiSuccess {String} id Acl ID
+ * @apiSuccess {String} perm Permission
+ * @apiSuccess {String} name Target name
+ * @apiSuccess {String="USER","GROUP","SHARE"} type Target type
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) InvalidTarget This target does not exist
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param sourceId Source ID
* @param permStr Permission
* @param targetName Target name
@@ -110,6 +127,19 @@ public class AclResource extends BaseResource {
/**
* Deletes an ACL.
+ *
+ * @api {delete} /acl/:source/:perm/:target Delete an ACL
+ * @apiName DeleteAcl
+ * @apiGroup Acl
+ * @apiParam {String} source Source ID
+ * @apiParam {String="READ","WRITE"} perm Permission
+ * @apiParam {String} target Target ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) AclError Cannot delete base ACL on a document or a tag
+ * @apiPermission user
+ * @apiVersion 1.5.0
*
* @param sourceId Source ID
* @param permStr Permission
@@ -162,6 +192,19 @@ public class AclResource extends BaseResource {
/**
* Search possible ACL target.
+ *
+ * @api {get} /acl/target/search Search in ACL targets
+ * @apiName GetAclTargetSearch
+ * @apiGroup Acl
+ * @apiParam {String} search Search query
+ * @apiSuccess {Object[]} users List of users
+ * @apiSuccess {String} users.name Username
+ * @apiSuccess {Object[]} groups List of groups
+ * @apiSuccess {String} groups.name Group name
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission user
+ * @apiVersion 1.5.0
*
* @param search Search query
* @return Response
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java
index b5426eb2..2b48cf0b 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java
@@ -63,8 +63,19 @@ public class AppResource extends BaseResource {
private static final Logger log = LoggerFactory.getLogger(AppResource.class);
/**
- * Return the information about the application.
- *
+ * Returns informations about the application.
+ *
+ * @api {get} /app Get application informations
+ * @apiName GetApp
+ * @apiGroup App
+ * @apiSuccess {String} current_version API current version
+ * @apiSuccess {String} min_version API minimum version
+ * @apiSuccess {String} total_memory Allocated JVM memory (in bytes)
+ * @apiSuccess {String} free_memory Free JVM memory (in bytes)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -88,7 +99,26 @@ public class AppResource extends BaseResource {
/**
* Retrieve the application logs.
- *
+ *
+ * @api {get} /app/log Get application logs
+ * @apiName GetAppLog
+ * @apiGroup App
+ * @apiParam {String="FATAL","ERROR","WARN","INFO","DEBUG"} level Minimum log level
+ * @apiParam {String} tag Filter on this logger tag
+ * @apiParam {String} message Filter on this message
+ * @apiParam {Number} limit Total number of logs to return
+ * @apiParam {Number} offset Start at this index
+ * @apiSuccess {String} total Total number of logs
+ * @apiSuccess {Object[]} logs List of logs
+ * @apiSuccess {String} logs.date Date
+ * @apiSuccess {String} logs.level Level
+ * @apiSuccess {String} logs.tag Tag
+ * @apiSuccess {String} logs.message Message
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) ServerError MEMORY appender not configured
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param minLevel Filter on logging level
* @param tag Filter on logger name / tag
* @param message Filter on message
@@ -107,6 +137,7 @@ public class AppResource extends BaseResource {
if (!authenticate()) {
throw new ForbiddenClientException();
}
+
// Get the memory appender
org.apache.log4j.Logger logger = org.apache.log4j.Logger.getRootLogger();
Appender appender = logger.getAppender("MEMORY");
@@ -141,7 +172,16 @@ public class AppResource extends BaseResource {
/**
* Destroy and rebuild Lucene index.
- *
+ *
+ * @api {post} /app/batch/reindex Rebuild the search index
+ * @apiName PostAppBatchReindex
+ * @apiGroup App
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) IndexingError Error rebuilding the index
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -155,7 +195,7 @@ public class AppResource extends BaseResource {
try {
AppContext.getInstance().getIndexingService().rebuildIndex();
} catch (Exception e) {
- throw new ServerException("IndexingError", "Error rebuilding index", e);
+ throw new ServerException("IndexingError", "Error rebuilding the index", e);
}
// Always return OK
@@ -166,7 +206,16 @@ public class AppResource extends BaseResource {
/**
* Clean storage.
- *
+ *
+ * @api {post} /app/batch/clean_storage Clean the file and DB storage
+ * @apiName PostAppBatchCleanStorage
+ * @apiGroup App
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) FileError Error deleting orphan files
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -275,7 +324,16 @@ public class AppResource extends BaseResource {
/**
* Recompute the quota for each user.
- *
+ *
+ * @api {post} /app/batch/recompute_quote Recompute user quotas
+ * @apiName PostAppBatchRecomputeQuota
+ * @apiGroup App
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) MissingFile File does not exist
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -327,6 +385,16 @@ public class AppResource extends BaseResource {
/**
* Add base ACLs to tags.
*
+ * @api {post} /app/batch/recompute_quote Add base ACL to tags
+ * @apiDescription This resource must be used after migrating to 1.5.
+ * It will not do anything if base ACL are already present on tags.
+ * @apiName PostAppBatchTagAcls
+ * @apiGroup App
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java
index 83f5b798..91eeb8e9 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java
@@ -30,7 +30,26 @@ import javax.ws.rs.core.Response;
public class AuditLogResource extends BaseResource {
/**
* Returns the list of all logs for a document or user.
- *
+ *
+ * @api {get} /auditlog Get audit logs
+ * @apiDescription If no document ID is provided, logs for the current user will be returned.
+ * @apiName GetAuditlog
+ * @apiGroup Auditlog
+ * @apiParam {String} [document] Document ID
+ * @apiSuccess {String} total Total number of logs
+ * @apiSuccess {Object[]} logs List of logs
+ * @apiSuccess {String} logs.id ID
+ * @apiSuccess {String} logs.username Username
+ * @apiSuccess {String} logs.target Entity ID
+ * @apiSuccess {String="Acl","Comment","Document","File","Group","Tag","User"} logs.class Entity type
+ * @apiSuccess {String="CREATE","UPDATE","DELETE"} logs.type Type
+ * @apiSuccess {String} logs.message Message
+ * @apiSuccess {Number} logs.create_date Create date (timestamp)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java
index ad3fe187..f05d6d56 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java
@@ -21,6 +21,29 @@ import com.sismics.util.filter.TokenBasedSecurityFilter;
* @author jtremeaux
*/
public abstract class BaseResource {
+ /**
+ * @apiDefine admin Admin
+ * Only the admin user can access this resource
+ */
+
+ /**
+ * @apiDefine user Authenticated user
+ * All authenticated users can access this resource
+ */
+
+ /**
+ * @apiDefine none Anonymous user
+ * This resource can be accessed anonymously
+ */
+
+ /**
+ * @apiDefine server Server error
+ */
+
+ /**
+ * @apiDefine client Client error
+ */
+
/**
* Injects the HTTP request.
*/
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java
index ce745054..49a88fec 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java
@@ -25,6 +25,22 @@ import java.util.List;
public class CommentResource extends BaseResource {
/**
* Add a comment.
+ *
+ * @api {put} /comment Add a comment
+ * @apiName PutComment
+ * @apiGroup Comment
+ * @apiParam {String} id Document ID
+ * @apiParam {String} content Comment content
+ * @apiSuccess {String} id Comment ID
+ * @apiSuccess {String} content Content
+ * @apiSuccess {String} creator Username
+ * @apiSuccess {String} creator_gravatar Creator Gravatar hash
+ * @apiSuccess {Number} create_date Create date (timestamp)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
*
* @param documentId Document ID
* @param content Comment content
@@ -67,7 +83,17 @@ public class CommentResource extends BaseResource {
/**
* Delete a comment.
- *
+ *
+ * @api {delete} /comment/:id Delete a comment
+ * @apiName DeleteComment
+ * @apiGroup Comment
+ * @apiParam {String} id Comment ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Comment or document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id Comment ID
* @return Response
*/
@@ -105,7 +131,22 @@ public class CommentResource extends BaseResource {
/**
* Get all comments on a document.
- *
+ *
+ * @api {get} /comment/:id Get comments
+ * @apiName GetComment
+ * @apiGroup Comment
+ * @apiParam {String} id Document ID
+ * @apiParam {String} share Share ID
+ * @apiSuccess {Object[]} comments List of comments
+ * @apiSuccess {String} comments.id Comment ID
+ * @apiSuccess {String} comments.content Content
+ * @apiSuccess {String} comments.creator Username
+ * @apiSuccess {String} comments.creator_gravatar Creator Gravatar hash
+ * @apiSuccess {Number} comments.create_date Create date (timestamp)
+ * @apiError (client) NotFound Document not found
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param documentId DocumentID
* @return Response
*/
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java
index 1f7bccbc..918725fa 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java
@@ -56,7 +56,56 @@ import java.util.*;
public class DocumentResource extends BaseResource {
/**
* Returns a document.
- *
+ *
+ * @api {get} /document/:id Get a document
+ * @apiName GetDocument
+ * @apiGroup Document
+ * @apiParam {String} id Document ID
+ * @apiParam {String} share Share ID
+ * @apiSuccess {String} id ID
+ * @apiSuccess {String} title Title
+ * @apiSuccess {String} description Description
+ * @apiSuccess {Number} create_date Create date (timestamp)
+ * @apiSuccess {String="eng","fra","jpn"} language Language
+ * @apiSuccess {Boolean} shared True if the document is shared
+ * @apiSuccess {Number} file_count Number of files in this document
+ * @apiSuccess {Object[]} tags List of tags
+ * @apiSuccess {String} tags.id ID
+ * @apiSuccess {String} tags.name Name
+ * @apiSuccess {String} tags.color Color
+ * @apiSuccess {String} subject Subject
+ * @apiSuccess {String} identifier Identifier
+ * @apiSuccess {String} publisher Publisher
+ * @apiSuccess {String} format Format
+ * @apiSuccess {String} source Source
+ * @apiSuccess {String} type Type
+ * @apiSuccess {String} coverage Coverage
+ * @apiSuccess {String} rights Rights
+ * @apiSuccess {String} creator Username of the creator
+ * @apiSuccess {Boolean} writable True if the document is writable by the current user
+ * @apiSuccess {Object[]} acls List of ACL
+ * @apiSuccess {String} acls.id ID
+ * @apiSuccess {String="READ","WRITE"} acls.perm Permission
+ * @apiSuccess {String} acls.name Target name
+ * @apiSuccess {String="USER","GROUP","SHARE"} acls.type Target type
+ * @apiSuccess {Object[]} inherited_acls List of ACL not directly applied to this document
+ * @apiSuccess {String="READ","WRITE"} inherited_acls.perm Permission
+ * @apiSuccess {String} inherited_acls.source_id Source ID
+ * @apiSuccess {String} inherited_acls.source_name Source name
+ * @apiSuccess {String} inherited_acls.id ID
+ * @apiSuccess {String} inherited_acls.name Target name
+ * @apiSuccess {String="USER","GROUP","SHARE"} inherited_acls.type Target type
+ * @apiSuccess {Object[]} contributors List of users having contributed to this document
+ * @apiSuccess {String} contributors.username Username
+ * @apiSuccess {String} contributors.email E-mail
+ * @apiSuccess {Object[]} relations List of document related to this one
+ * @apiSuccess {String} relations.id ID
+ * @apiSuccess {String} relations.title Title
+ * @apiSuccess {String} relations.source True if this document is the source of the relation
+ * @apiError (client) NotFound Document not found
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param shareId Share ID
* @return Response
@@ -166,7 +215,22 @@ public class DocumentResource extends BaseResource {
/**
* Export a document to PDF.
- *
+ *
+ * @api {get} /document/:id/pdf Export a document to PDF
+ * @apiName GetDocumentPdf
+ * @apiGroup Document
+ * @apiParam {String} id Document ID
+ * @apiParam {String} share Share ID
+ * @apiParam {Boolean} metadata If true, export metadata
+ * @apiParam {Boolean} comments If true, export comments
+ * @apiParam {Boolean} fitimagetopage If true, fit the images to pages
+ * @apiParam {Number} margin Margin around the pages, in millimeter
+ * @apiSuccess {String} pdf The whole response is the PDF file
+ * @apiError (client) NotFound Document not found
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param shareId Share ID
* @param metadata Export metadata
@@ -233,7 +297,33 @@ public class DocumentResource extends BaseResource {
/**
* Returns all documents.
- *
+ *
+ * @api {get} /document/list Get documents
+ * @apiName GetDocumentList
+ * @apiGroup Document
+ * @apiParam {String} limit Total number of documents to return
+ * @apiParam {String} offset Start at this index
+ * @apiParam {Number} sort_column Column index to sort on
+ * @apiParam {Boolean} asc If true, sort in ascending order
+ * @apiParam {String} search Search query
+ * @apiSuccess {Number} total Total number of documents
+ * @apiSuccess {Object[]} documents List of documents
+ * @apiSuccess {String} documents.id ID
+ * @apiSuccess {String} documents.title Title
+ * @apiSuccess {String} documents.description Description
+ * @apiSuccess {Number} documents.create_date Create date (timestamp)
+ * @apiSuccess {String="eng","fra","jpn"} documents.language Language
+ * @apiSuccess {Boolean} documents.shared True if the document is shared
+ * @apiSuccess {Number} documents.file_count Number of files in this document
+ * @apiSuccess {Object[]} documents.tags List of tags
+ * @apiSuccess {String} documents.tags.id ID
+ * @apiSuccess {String} documents.tags.name Name
+ * @apiSuccess {String} documents.tags.color Color
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) SearchError Error searching in documents
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param limit Page limit
* @param offset Page offset
* @param sortColumn Sort column
@@ -422,7 +512,30 @@ public class DocumentResource extends BaseResource {
/**
* Creates a new document.
- *
+ *
+ * @api {put} /document Add a document
+ * @apiName PutDocument
+ * @apiGroup Document
+ * @apiParam {String} title Title
+ * @apiParam {String} [description] Description
+ * @apiParam {String} [subject] Subject
+ * @apiParam {String} [identifier] Identifier
+ * @apiParam {String} [publisher] Publisher
+ * @apiParam {String} [format] Format
+ * @apiParam {String} [source] Source
+ * @apiParam {String} [type] Type
+ * @apiParam {String} [coverage] Coverage
+ * @apiParam {String} [rights] Rights
+ * @apiParam {String[]} [tags] List of tags ID
+ * @apiParam {String[]} [relations] List of related documents ID
+ * @apiParam {String="eng","fra","jpn"} language Language
+ * @apiParam {Number} [create_date] Create date (timestamp)
+ * @apiSuccess {String} id Document ID
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param title Title
* @param description Description
* @param subject Subject
@@ -532,7 +645,32 @@ public class DocumentResource extends BaseResource {
/**
* Updates the document.
- *
+ *
+ * @api {post} /document/:id Update a document
+ * @apiName PostDocument
+ * @apiGroup Document
+ * @apiParam {String} id ID
+ * @apiParam {String} title Title
+ * @apiParam {String} [description] Description
+ * @apiParam {String} [subject] Subject
+ * @apiParam {String} [identifier] Identifier
+ * @apiParam {String} [publisher] Publisher
+ * @apiParam {String} [format] Format
+ * @apiParam {String} [source] Source
+ * @apiParam {String} [type] Type
+ * @apiParam {String} [coverage] Coverage
+ * @apiParam {String} [rights] Rights
+ * @apiParam {String[]} [tags] List of tags ID
+ * @apiParam {String[]} [relations] List of related documents ID
+ * @apiParam {String="eng","fra","jpn"} language Language
+ * @apiParam {Number} [create_date] Create date (timestamp)
+ * @apiSuccess {String} id Document ID
+ * @apiError (client) ForbiddenError Access denied or document not writable
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param title Title
* @param description Description
* @return Response
@@ -675,7 +813,17 @@ public class DocumentResource extends BaseResource {
/**
* Deletes a document.
- *
+ *
+ * @api {delete} /document/:id Delete a document
+ * @apiName DeleteDocument
+ * @apiGroup Document
+ * @apiParam {String} id ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id Document ID
* @return Response
*/
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
index 35520179..cd4e9b46 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
@@ -61,7 +61,28 @@ import com.sismics.util.mime.MimeTypeUtil;
public class FileResource extends BaseResource {
/**
* Add a file (with or without a document).
- *
+ *
+ * @api {put} /file Add a file
+ * @apiDescription A file can be added without associated document, and will go in a temporary storage waiting for one.
+ * This resource accepts only multipart/form-data.
+ * @apiName PutFile
+ * @apiGroup File
+ * @apiParam {String} id Document ID
+ * @apiParam {String} file File data
+ * @apiSuccess {String} status Status OK
+ * @apiSuccess {String} id File ID
+ * @apiSuccess {Number} size File size (in bytes)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Document not found
+ * @apiError (server) StreamError Error reading the input file
+ * @apiError (server) ErrorGuessMime Error guessing mime type
+ * @apiError (client) InvalidFileType File type not recognized
+ * @apiError (client) QuotaReached Quota limit reached
+ * @apiError (server) FileError Error adding a file
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param fileBodyPart File to add
* @return Response
@@ -179,7 +200,20 @@ public class FileResource extends BaseResource {
/**
* Attach a file to a document.
- *
+ *
+ * @api {post} /file/:fileId Attach a file to a document
+ * @apiName PostFile
+ * @apiGroup File
+ * @apiParam {String} fileId File ID
+ * @apiParam {String} id Document ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) IllegalFile File not orphan
+ * @apiError (server) AttachError Error attaching file to document
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id File ID
* @return Response
*/
@@ -235,7 +269,7 @@ public class FileResource extends BaseResource {
documentUpdatedAsyncEvent.setDocumentId(documentId);
AppContext.getInstance().getAsyncEventBus().post(documentUpdatedAsyncEvent);
} catch (Exception e) {
- throw new ClientException("AttachError", "Error attaching file to document", e);
+ throw new ServerException("AttachError", "Error attaching file to document", e);
}
// Always return OK
@@ -246,7 +280,19 @@ public class FileResource extends BaseResource {
/**
* Reorder files.
- *
+ *
+ * @api {post} /file/:reorder Reorder files
+ * @apiName PostFileReorder
+ * @apiGroup File
+ * @apiParam {String} id Document ID
+ * @apiParam {String[]} order List of files ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param idList List of files ID in the new order
* @return Response
@@ -287,7 +333,24 @@ public class FileResource extends BaseResource {
/**
* Returns files linked to a document or not linked to any document.
- *
+ *
+ * @api {post} /file/list Get files
+ * @apiName GetFileList
+ * @apiGroup File
+ * @apiParam {String} id Document ID
+ * @apiParam {String} share Share ID
+ * @apiSuccess {Object[]} files List of files
+ * @apiSuccess {String} files.id ID
+ * @apiSuccess {String} files.mimetype MIME type
+ * @apiSuccess {String} files.document_id Document ID
+ * @apiSuccess {String} files.create_date Create date (timestamp)
+ * @apiSuccess {String} files.size File size (in bytes)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Document not found
+ * @apiError (server) FileError Unable to get the size of a file
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param shareId Sharing ID
* @return Response
@@ -333,7 +396,18 @@ public class FileResource extends BaseResource {
/**
* Deletes a file.
- *
+ *
+ * @api {delete} /file/:id Delete a file
+ * @apiName DeleteFile
+ * @apiGroup File
+ * @apiParam {String} id File ID
+ * @apiParam {String} share Share ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound File or document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id File ID
* @return Response
*/
@@ -399,7 +473,21 @@ public class FileResource extends BaseResource {
/**
* Returns a file.
- *
+ *
+ * @api {delete} /file/:id/data Get a file data
+ * @apiName GetFile
+ * @apiGroup File
+ * @apiParam {String} id File ID
+ * @apiParam {String} share Share ID
+ * @apiParam {String="web","thumb"} [size] Size variation
+ * @apiSuccess {Object} file The file data is the whole response
+ * @apiError (client) SizeError Size must be web or thumb
+ * @apiError (client) ForbiddenError Access denied or document not visible
+ * @apiError (client) NotFound File not found
+ * @apiError (server) ServiceUnavailable Error reading the file
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param fileId File ID
* @return Response
*/
@@ -498,7 +586,18 @@ public class FileResource extends BaseResource {
/**
* Returns all files from a document, zipped.
- *
+ *
+ * @api {get} /file/zip Get zipped files
+ * @apiName GetFileZip
+ * @apiGroup File
+ * @apiParam {String} id Document ID
+ * @apiParam {String} share Share ID
+ * @apiSuccess {Object} file The ZIP file is the whole response
+ * @apiError (client) NotFound Document not found
+ * @apiError (server) InternalServerError Error creating the ZIP file
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @return Response
*/
@@ -542,7 +641,6 @@ public class FileResource extends BaseResource {
ByteStreams.copy(decryptedStream, zipOutputStream);
zipOutputStream.closeEntry();
} catch (Exception e) {
- e.printStackTrace();
throw new WebApplicationException(e);
}
index++;
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java
index d345ee97..13d6915f 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java
@@ -34,7 +34,20 @@ import java.util.List;
public class GroupResource extends BaseResource {
/**
* Add a group.
- *
+ *
+ * @api {put} /group Add a group
+ * @apiName PutGroup
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiParam {String} [parent] Parent group name
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) GroupAlreadyExists This group already exists
+ * @apiError (client) ParentGroupNotFound Parent group not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@PUT
@@ -79,7 +92,21 @@ public class GroupResource extends BaseResource {
/**
* Update a group.
- *
+ *
+ * @api {post} /group/:name Update a group
+ * @apiName PostGroup
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiParam {String} [parent] Parent group name
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) GroupAlreadyExists This group already exists
+ * @apiError (client) ParentGroupNotFound Parent group not found
+ * @apiError (client) NotFound Group not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -131,7 +158,17 @@ public class GroupResource extends BaseResource {
/**
* Delete a group.
- *
+ *
+ * @api {delete} /group/:name Delete a group
+ * @apiName DeleteGroup
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Group not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@DELETE
@@ -160,7 +197,19 @@ public class GroupResource extends BaseResource {
/**
* Add a user to a group.
- *
+ *
+ * @api {put} /group/:name Add a user to a group
+ * @apiName PutGroupMember
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiParam {String} username Username
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Group or user not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param groupName Group name
* @param username Username
* @return Response
@@ -217,7 +266,19 @@ public class GroupResource extends BaseResource {
/**
* Remove an user from a group.
- *
+ *
+ * @api {delete} /group/:name/:username Remove a user from a group
+ * @apiName DeleteGroupMember
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiParam {String} username Username
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Group or user not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param groupName Group name
* @param username Username
* @return Response
@@ -260,7 +321,19 @@ public class GroupResource extends BaseResource {
/**
* Returns all active groups.
- *
+ *
+ * @api {get} /group Get groups
+ * @apiName GetGroupList
+ * @apiGroup Group
+ * @apiParam {Number} sort_column Column index to sort on
+ * @apiParam {Boolean} asc If true, sort in ascending order
+ * @apiSuccess {Object[]} groups List of groups
+ * @apiSuccess {String} groups.name Name
+ * @apiSuccess {String} groups.parent Parent name
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param sortColumn Sort index
* @param asc If true, ascending sorting, else descending
* @return Response
@@ -291,7 +364,19 @@ public class GroupResource extends BaseResource {
/**
* Get a group.
- *
+ *
+ * @api {get} /group/:name Get a group
+ * @apiName GetGroup
+ * @apiGroup Group
+ * @apiParam {String} name Group name
+ * @apiSuccess {String} name Group name
+ * @apiSuccess {String} parent Parent name
+ * @apiSuccess {String[]} members List of members
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Group not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param groupName Group name
* @return Response
*/
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java
index 9e4d49e5..28d9eb7c 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java
@@ -29,6 +29,21 @@ public class ShareResource extends BaseResource {
/**
* Add a share to a document.
*
+ * @api {put} /share Share a document
+ * @apiName PutShare
+ * @apiGroup Share
+ * @apiParam {String} id Document ID
+ * @apiParam {String} name Share name
+ * @apiSuccess {String} id Acl ID
+ * @apiSuccess {String="READ","WRITE"} perm Permission
+ * @apiSuccess {String} name Share name
+ * @apiSuccess {String="SHARE"} type ACL type (always SHARE)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Share not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param documentId Document ID
* @param name Share name
* @return Response
@@ -76,6 +91,17 @@ public class ShareResource extends BaseResource {
/**
* Deletes a share.
*
+ * @api {delete} /share/:id Unshare a document
+ * @apiName DeleteShare
+ * @apiGroup Share
+ * @apiParam {String} id Acl ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ShareNotFound Share not found
+ * @apiError (client) DocumentNotFound Document not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id Share ID
* @return Response
*/
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java
index 9e8f5871..452c2268 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java
@@ -33,7 +33,19 @@ import java.util.Set;
public class TagResource extends BaseResource {
/**
* Returns the list of all visible tags.
- *
+ *
+ * @api {get} /tag/list Get tags
+ * @apiName GetTagList
+ * @apiGroup Tag
+ * @apiSuccess {Object[]} tags List of tags
+ * @apiSuccess {String} tags.id ID
+ * @apiSuccess {String} tags.name Name
+ * @apiSuccess {String} tags.color Color
+ * @apiSuccess {String} tags.parent Parent
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -73,6 +85,25 @@ public class TagResource extends BaseResource {
/**
* Returns a tag.
*
+ * @api {get} /tag/:id Get a tag
+ * @apiName GetTag
+ * @apiGroup Tag
+ * @apiSuccess {String} id ID
+ * @apiSuccess {String} name Name
+ * @apiSuccess {String} creator Username of the creator
+ * @apiSuccess {String} color Color
+ * @apiSuccess {String} parent Parent
+ * @apiSuccess {Boolean} writable True if the tag is writable by the current user
+ * @apiSuccess {Object[]} acls List of ACL
+ * @apiSuccess {String} acls.id ID
+ * @apiSuccess {String="READ","WRITE"} acls.perm Permission
+ * @apiSuccess {String} acls.name Target name
+ * @apiSuccess {String="USER","GROUP","SHARE"} acls.type Target type
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Tag not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param id Tag ID
* @return Response
*/
@@ -113,7 +144,21 @@ public class TagResource extends BaseResource {
/**
* Creates a new tag.
- *
+ *
+ * @api {put} /tag Create a tag
+ * @apiName PutTag
+ * @apiGroup Tag
+ * @apiParam {String} name Name
+ * @apiParam {String} color Color
+ * @apiParam {String} parent Parent ID
+ * @apiSuccess {String} id Tag ID
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) SpacesNotAllowed Spaces are not allowed in tag name
+ * @apiError (client) ParentNotFound Parent not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param name Name
* @param color Color
* @param parentId Parent ID
@@ -178,7 +223,23 @@ public class TagResource extends BaseResource {
/**
* Update a tag.
- *
+ *
+ * @api {post} /tag/:id Update a tag
+ * @apiName PostTag
+ * @apiGroup Tag
+ * @apiParam {String} id Tag ID
+ * @apiParam {String} name Name
+ * @apiParam {String} color Color
+ * @apiParam {String} parent Parent ID
+ * @apiSuccess {String} id Tag ID
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) SpacesNotAllowed Spaces are not allowed in tag name
+ * @apiError (client) ParentNotFound Parent not found
+ * @apiError (client) NotFound Tag not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param name Name
* @param color Color
* @param parentId Parent ID
@@ -240,6 +301,16 @@ public class TagResource extends BaseResource {
/**
* Delete a tag.
+ *
+ * @api {delete} /tag/:id Delete a tag
+ * @apiName DeleteTag
+ * @apiGroup Tag
+ * @apiParam {String} id Tag ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Tag not found
+ * @apiPermission user
+ * @apiVersion 1.5.0
*
* @param id Tag ID
* @return Response
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/ThemeResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/ThemeResource.java
index 46032995..dbd7bd15 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/ThemeResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/ThemeResource.java
@@ -39,7 +39,14 @@ import java.util.Map;
public class ThemeResource extends BaseResource {
/**
* Returns custom CSS stylesheet.
- *
+ *
+ * @api {get} /theme/stylesheet Get the CSS stylesheet
+ * @apiName GetThemeStylesheet
+ * @apiGroup Theme
+ * @apiSuccess {String} stylesheet The whole response is the stylesheet
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -60,6 +67,15 @@ public class ThemeResource extends BaseResource {
/**
* Returns the theme configuration.
*
+ * @api {get} /theme Get the theme configuration
+ * @apiName GetTheme
+ * @apiGroup Theme
+ * @apiSuccess {String} name Application name
+ * @apiSuccess {String} color Main color
+ * @apiSuccess {String} css Custom CSS
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -75,6 +91,18 @@ public class ThemeResource extends BaseResource {
/**
* Change the theme configuration.
*
+ * @api {post} /theme Change the theme configuration
+ * @apiName PostTheme
+ * @apiGroup Theme
+ * @apiParam {String} name Application name
+ * @apiParam {String} color Main color
+ * @apiParam {String} css Custom CSS
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param color Theme color
* @param name Application name
* @param css Custom CSS
@@ -117,6 +145,26 @@ public class ThemeResource extends BaseResource {
return Response.ok().entity(response.build()).build();
}
+ /**
+ * Change a theme image.
+ *
+ * @api {put} /theme/image/:type Change a theme image
+ * @apiDescription This resource accepts only multipart/form-data.
+ * @apiName PutThemeImage
+ * @apiGroup Theme
+ * @apiParam {String="logo","background"} type Image type
+ * @apiParam {String} image Image data
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NoImageProvided An image is required
+ * @apiError (server) CopyError Error copying the image to the theme directory
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
+ * @param type Image type
+ * @param imageBodyPart Image data
+ * @return Response
+ */
@PUT
@Path("image/{type: logo|background}")
@Consumes("multipart/form-data")
@@ -143,6 +191,20 @@ public class ThemeResource extends BaseResource {
return Response.ok().build();
}
+ /**
+ * Get theme images.
+ *
+ * @api {get} /theme/image/:type Get a theme image
+ * @apiName GetThemeImage
+ * @apiGroup Theme
+ * @apiParam {String="logo","background"} type Image type
+ * @apiSuccess {String} image The whole response is the image
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
+ * @param type Image type
+ * @return Response
+ */
@GET
@Produces("image/*")
@Path("image/{type: logo|background}")
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
index 433812ec..d32042dd 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java
@@ -67,7 +67,23 @@ import com.sismics.util.totp.GoogleAuthenticatorKey;
public class UserResource extends BaseResource {
/**
* Creates a new user.
- *
+ *
+ * @api {put} /user Register a new user
+ * @apiName PutUser
+ * @apiGroup User
+ * @apiParam {String{3..50}} username Username
+ * @apiParam {String{8..50}} password Password
+ * @apiParam {String{1..100}} email E-mail
+ * @apiParam {Number} storage_quota Storage quota (in bytes)
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (server) PrivateKeyError Error while generating a private key
+ * @apiError (client) AlreadyExistingUsername Login already used
+ * @apiError (server) UnknownError Unknown server error
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param username User's username
* @param password Password
* @param email E-Mail
@@ -88,7 +104,7 @@ public class UserResource extends BaseResource {
username = ValidationUtil.validateLength(username, "username", 3, 50);
ValidationUtil.validateAlphanumeric(username, "username");
password = ValidationUtil.validateLength(password, "password", 8, 50);
- email = ValidationUtil.validateLength(email, "email", 3, 50);
+ email = ValidationUtil.validateLength(email, "email", 1, 100);
Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota");
ValidationUtil.validateEmail(email, "email");
@@ -115,7 +131,7 @@ public class UserResource extends BaseResource {
if ("AlreadyExistingUsername".equals(e.getMessage())) {
throw new ServerException("AlreadyExistingUsername", "Login already used", e);
} else {
- throw new ServerException("UnknownError", "Unknown Server Error", e);
+ throw new ServerException("UnknownError", "Unknown server error", e);
}
}
@@ -126,8 +142,19 @@ public class UserResource extends BaseResource {
}
/**
- * Updates user informations.
- *
+ * Updates the current user informations.
+ *
+ * @api {post} /user Update the current user
+ * @apiName PostUser
+ * @apiGroup User
+ * @apiParam {String{8..50}} password Password
+ * @apiParam {String{1..100}} email E-mail
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param password Password
* @param email E-Mail
* @return Response
@@ -142,7 +169,7 @@ public class UserResource extends BaseResource {
// Validate the input data
password = ValidationUtil.validateLength(password, "password", 8, 50, true);
- email = ValidationUtil.validateLength(email, "email", null, 100, true);
+ email = ValidationUtil.validateLength(email, "email", 1, 100, true);
// Update the user
UserDao userDao = new UserDao();
@@ -165,8 +192,22 @@ public class UserResource extends BaseResource {
}
/**
- * Updates user informations.
- *
+ * Updates a user informations.
+ *
+ * @api {post} /user/:username Update a user
+ * @apiName PostUserUsername
+ * @apiGroup User
+ * @apiParam {String} username Username
+ * @apiParam {String{8..50}} password Password
+ * @apiParam {String{1..100}} email E-mail
+ * @apiParam {Number} storage_quota Storage quota (in bytes)
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) UserNotFound User not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param username Username
* @param password Password
* @param email E-Mail
@@ -186,7 +227,7 @@ public class UserResource extends BaseResource {
// Validate the input data
password = ValidationUtil.validateLength(password, "password", 8, 50, true);
- email = ValidationUtil.validateLength(email, "email", null, 100, true);
+ email = ValidationUtil.validateLength(email, "email", 1, 100, true);
// Check if the user exists
UserDao userDao = new UserDao();
@@ -218,8 +259,17 @@ public class UserResource extends BaseResource {
}
/**
- * Checks if a username is available. Search only on active accounts.
- *
+ * Checks if a username is available.
+ * Search only on active accounts.
+ *
+ * @api {get} /user/check_username Check username availability
+ * @apiName GetUserCheckUsername
+ * @apiGroup User
+ * @apiParam {String} username Username
+ * @apiSuccess {String} status Status OK or KO
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param username Username to check
* @return Response
*/
@@ -244,7 +294,22 @@ public class UserResource extends BaseResource {
/**
* This resource is used to authenticate the user and create a user session.
* The "session" is only used to identify the user, no other data is stored in the session.
- *
+ *
+ * @api {post} /user/login Login a user
+ * @apiDescription This resource creates an authentication token and gives it back in a cookie.
+ * All authenticated resources will check this cookie to find the user currently logged in.
+ * @apiName PostUserLogin
+ * @apiGroup User
+ * @apiParam {String} username Username
+ * @apiParam {String} password Password
+ * @apiParam {String} code TOTP validation code
+ * @apiParam {Boolean} remember If true, create a long lasted token
+ * @apiSuccess {String} auth_token A cookie named auth_token containing the token ID
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationCodeRequired A TOTP validation code is required
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @param username Username
* @param password Password
* @param longLasted Remember the user next time, create a long lasted session.
@@ -309,7 +374,17 @@ public class UserResource extends BaseResource {
/**
* Logs out the user and deletes the active session.
- *
+ *
+ * @api {post} /user/logout Logout a user
+ * @apiDescription This resource deletes the authentication token created by POST /user/login and removes the cookie.
+ * @apiName PostUserLogout
+ * @apiGroup User
+ * @apiSuccess {String} auth_token An expired cookie named auth_token containing no value
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (server) AuthenticationTokenError Error deleting the authentication token
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -337,7 +412,7 @@ public class UserResource extends BaseResource {
try {
authenticationTokenDao.delete(authToken);
} catch (Exception e) {
- throw new ServerException("AuthenticationTokenError", "Error deleting authentication token: " + authToken, e);
+ throw new ServerException("AuthenticationTokenError", "Error deleting the authentication token: " + authToken, e);
}
// Deletes the client token in the HTTP response
@@ -347,8 +422,17 @@ public class UserResource extends BaseResource {
}
/**
- * Delete a user.
- *
+ * Deletes the current user.
+ *
+ * @api {delete} /user Delete the current user
+ * @apiDescription All associated entities will be deleted as well.
+ * @apiName DeleteUser
+ * @apiGroup User
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied or the admin user cannot be deleted
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@DELETE
@@ -396,7 +480,17 @@ public class UserResource extends BaseResource {
/**
* Deletes a user.
- *
+ *
+ * @api {delete} /user/:username Delete a user
+ * @apiDescription All associated entities will be deleted as well.
+ * @apiName DeleteUserUsername
+ * @apiGroup User
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied or the admin user cannot be deleted
+ * @apiError (client) UserNotFound The user does not exist
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param username Username
* @return Response
*/
@@ -412,7 +506,7 @@ public class UserResource extends BaseResource {
UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(username);
if (user == null) {
- throw new ClientException("UserNotFound", "The user doesn't exist");
+ throw new ClientException("UserNotFound", "The user does not exist");
}
// Ensure that the admin user is not deleted
@@ -455,7 +549,22 @@ public class UserResource extends BaseResource {
/**
* Returns the information about the connected user.
- *
+ *
+ * @api {get} /user Get the current user
+ * @apiName GetUser
+ * @apiGroup User
+ * @apiSuccess {Boolean} anonymous True if no user is connected
+ * @apiSuccess {Boolean} is_default_password True if the admin has the default password
+ * @apiSuccess {String} username Username
+ * @apiSuccess {String} email E-mail
+ * @apiSuccess {Number} storage_quota Storage quota (in bytes)
+ * @apiSuccess {Number} storage_current Quota used (in bytes)
+ * @apiSuccess {Boolean} totp_enabled True if TOTP authentication is enabled
+ * @apiSuccess {String[]} base_functions Base functions
+ * @apiSuccess {String[]} groups Groups
+ * @apiPermission none
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -513,7 +622,21 @@ public class UserResource extends BaseResource {
/**
* Returns the information about a user.
- *
+ *
+ * @api {get} /user/:username Get a user
+ * @apiName GetUserUsername
+ * @apiGroup User
+ * @apiParam {String} username Username
+ * @apiSuccess {String} username Username
+ * @apiSuccess {String} email E-mail
+ * @apiSuccess {Number} storage_quota Storage quota (in bytes)
+ * @apiSuccess {Number} storage_current Quota used (in bytes)
+ * @apiSuccess {String[]} groups Groups
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) UserNotFound The user does not exist
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param username Username
* @return Response
*/
@@ -528,7 +651,7 @@ public class UserResource extends BaseResource {
UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(username);
if (user == null) {
- throw new ClientException("UserNotFound", "The user doesn't exist");
+ throw new ClientException("UserNotFound", "The user does not exist");
}
// Groups
@@ -552,7 +675,24 @@ public class UserResource extends BaseResource {
/**
* Returns all active users.
- *
+ *
+ * @api {get} /user/list Get users
+ * @apiName GetUserList
+ * @apiGroup User
+ * @apiParam {Number} sort_column Column index to sort on
+ * @apiParam {Boolean} asc If true, sort in ascending order
+ * @apiParam {String} group Filter on this group
+ * @apiSuccess {Object[]} users List of users
+ * @apiSuccess {String} users.id ID
+ * @apiSuccess {String} users.username Username
+ * @apiSuccess {String} users.email E-mail
+ * @apiSuccess {Number} users.storage_quota Storage quota (in bytes)
+ * @apiSuccess {Number} users.storage_current Quota used (in bytes)
+ * @apiSuccess {Number} users.create_date Create date (timestamp)
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param sortColumn Sort index
* @param asc If true, ascending sorting, else descending
* @param groupName Only return users from this group
@@ -600,7 +740,21 @@ public class UserResource extends BaseResource {
/**
* Returns all active sessions.
- *
+ *
+ * @api {get} /user/session Get active sessions
+ * @apiDescription This resource lists all active token which can be used to log in to the current user account.
+ * @apiName GetUserSession
+ * @apiGroup User
+ * @apiSuccess {Object[]} sessions List of sessions
+ * @apiSuccess {Number} create_date Create date of this token
+ * @apiSuccess {String} ip IP used to log in
+ * @apiSuccess {String} user_agent User agent used to log in
+ * @apiSuccess {Number} last_connection_date Last connection date (timestamp)
+ * @apiSuccess {Boolean} current If true, this token is the current one
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@GET
@@ -635,7 +789,16 @@ public class UserResource extends BaseResource {
/**
* Deletes all active sessions except the one used for this request.
- *
+ *
+ * @api {delete} /user/session Delete all sessions
+ * @apiDescription This resource deletes all active token linked to this account, except the one used to make this request.
+ * @apiName DeleteUserSession
+ * @apiGroup User
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@DELETE
@@ -660,7 +823,17 @@ public class UserResource extends BaseResource {
/**
* Enable time-based one-time password.
- *
+ *
+ * @api {post} /user/enable_totp Enable TOTP authentication
+ * @apiDescription This resource enables the Time-based One-time Password authentication.
+ * All following login will need a validation code generated from the given secret seed.
+ * @apiName PostUserEnableTotp
+ * @apiGroup User
+ * @apiSuccess {String} secret Secret TOTP seed to initiate the algorithm
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @return Response
*/
@POST
@@ -687,7 +860,17 @@ public class UserResource extends BaseResource {
/**
* Disable time-based one-time password.
- *
+ *
+ * @api {post} /user/disable_totp Disable TOTP authentication
+ * @apiName PostUserDisableTotp
+ * @apiGroup User
+ * @apiParam {String{1..100}} password Password
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
* @param password Password
* @return Response
*/
@@ -720,7 +903,7 @@ public class UserResource extends BaseResource {
/**
* Returns the authentication token value.
- *
+ *
* @return Token value
*/
private String getAuthToken() {
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
index 06ba5ee8..6dfef3b0 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/VocabularyResource.java
@@ -20,6 +20,25 @@ import java.util.List;
*/
@Path("/vocabulary")
public class VocabularyResource extends BaseResource {
+ /**
+ * Get a vocabulary.
+ *
+ * @api {get} /vocabulary/:name Get a vocabulary
+ * @apiName GetVocabularyName
+ * @apiGroup Vocabulary
+ * @apiParam {String} name Vocabulary name
+ * @apiSuccess {Object[]} entries List of vocabulary entries
+ * @apiSuccess {String} entries.id ID
+ * @apiSuccess {String} entries.name Name
+ * @apiSuccess {String} entries.value Value
+ * @apiSuccess {Number} entries.order Order
+ * @apiError (client) ForbiddenError Access denied
+ * @apiPermission user
+ * @apiVersion 1.5.0
+ *
+ * @param name Name
+ * @return Response
+ */
@GET
@Path("{name: [a-z0-9\\-]+}")
public Response get(@PathParam("name") String name) {
@@ -46,8 +65,23 @@ public class VocabularyResource extends BaseResource {
}
/**
- * Add a vocabulary.
- *
+ * Add a vocabulary entry.
+ *
+ * @api {put} /vocabulary Add a vocabulary entry
+ * @apiName PutVocabulary
+ * @apiGroup Vocabulary
+ * @apiParam {String{1..50}} name Vocabulary name
+ * @apiParam {String{1..500}} value Entry value
+ * @apiParam {Number} order Entry order
+ * @apiSuccess {String} id ID
+ * @apiSuccess {String} name Name
+ * @apiSuccess {String} value Value
+ * @apiSuccess {Number} order Order
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param name Name
* @param value Value
* @param orderStr Order
@@ -86,7 +120,24 @@ public class VocabularyResource extends BaseResource {
}
/**
- * Update a vocabulary.
+ * Update a vocabulary entry.
+ *
+ * @api {post} /vocabulary/:id Update a vocabulary entry
+ * @apiName PostVocabularyId
+ * @apiGroup Vocabulary
+ * @apiParam {String} id Entry ID
+ * @apiParam {String{1..50}} name Vocabulary name
+ * @apiParam {String{1..500}} value Entry value
+ * @apiParam {Number} order Entry order
+ * @apiSuccess {String} id ID
+ * @apiSuccess {String} name Name
+ * @apiSuccess {String} value Value
+ * @apiSuccess {Number} order Order
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) ValidationError Validation error
+ * @apiError (client) NotFound Vocabulary not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
*
* @param id ID
* @param name Name
@@ -145,8 +196,18 @@ public class VocabularyResource extends BaseResource {
}
/**
- * Delete a vocabulary.
- *
+ * Delete a vocabulary entry.
+ *
+ * @api {delete} /vocabulary/:id Delete vocabulary entry
+ * @apiName DeleteVocabularyId
+ * @apiGroup Vocabulary
+ * @apiParam {String} id Entry ID
+ * @apiSuccess {String} status Status OK
+ * @apiError (client) ForbiddenError Access denied
+ * @apiError (client) NotFound Vocabulary not found
+ * @apiPermission admin
+ * @apiVersion 1.5.0
+ *
* @param id ID
* @return Response
*/
diff --git a/docs-web/src/main/webapp/Gruntfile.js b/docs-web/src/main/webapp/Gruntfile.js
index 5dba6d2d..ec2c6404 100644
--- a/docs-web/src/main/webapp/Gruntfile.js
+++ b/docs-web/src/main/webapp/Gruntfile.js
@@ -4,9 +4,8 @@ module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
- dist: {
- src: ['dist']
- }
+ init: ['dist'],
+ after: ['dist/style.css', 'dist/docs.js', 'dist/share.js', 'dist/less.css', 'dist/app']
},
ngmin: {
dist: {
@@ -78,12 +77,6 @@ module.exports = function(grunt) {
dest: 'dist/share.html'
}
},
- remove: {
- dist: {
- fileList: ['dist/style.css', 'dist/docs.js', 'dist/share.js', 'dist/less.css'],
- dirList: ['dist/app']
- }
- },
cleanempty: {
options: {
files: false,
@@ -100,6 +93,12 @@ module.exports = function(grunt) {
to: grunt.option('apiurl') || '../api'
}]
}
+ },
+ apidoc: {
+ generate: {
+ src: '../java/',
+ dest: 'dist/apidoc/'
+ }
}
});
@@ -111,12 +110,12 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-htmlrefs');
grunt.loadNpmTasks('grunt-css');
grunt.loadNpmTasks('grunt-contrib-less');
- grunt.loadNpmTasks('grunt-remove');
grunt.loadNpmTasks('grunt-ngmin');
grunt.loadNpmTasks('grunt-text-replace');
+ grunt.loadNpmTasks('grunt-apidoc');
// Default tasks.
- grunt.registerTask('default', ['clean', 'ngmin', 'concat:docs', 'concat:share', 'less', 'concat:css', 'cssmin',
- 'uglify:docs', 'uglify:share', 'copy', 'remove', 'cleanempty', 'htmlrefs:index', 'htmlrefs:share', 'replace']);
+ grunt.registerTask('default', ['clean:init', 'ngmin', 'concat:docs', 'concat:share', 'less', 'concat:css', 'cssmin',
+ 'uglify:docs', 'uglify:share', 'copy', 'clean:after', 'cleanempty', 'htmlrefs:index', 'htmlrefs:share', 'replace', 'apidoc']);
};
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/package.json b/docs-web/src/main/webapp/package.json
index 29eefd62..97c22aee 100644
--- a/docs-web/src/main/webapp/package.json
+++ b/docs-web/src/main/webapp/package.json
@@ -2,25 +2,48 @@
"name": "sismics-docs",
"description": "Lightweight document management system",
"readme": "See http://github.com/simics/docs for more informations.",
- "version": "0.0.1",
+ "version": "1.5.0",
"repository": {
"type": "git",
"url": "git://github.com/sismics/docs.git"
},
+ "apidoc": {
+ "name": "Sismics Docs API",
+ "title": "Sismics Docs API",
+ "url": "/api",
+ "template": {
+ "withCompare": false,
+ "withGenerator": false
+ },
+ "order": [
+ "User",
+ "Group",
+ "Document",
+ "File",
+ "Tag",
+ "Comment",
+ "Share",
+ "Acl",
+ "Auditlog",
+ "App",
+ "Theme",
+ "Vocabulary"
+ ]
+ },
"devDependencies": {
- "grunt": "~0.4.2",
- "grunt-contrib-uglify": "~0.3.2",
- "grunt-contrib-concat": "~0.3.0",
- "grunt-contrib-copy": "~0.5.0",
- "grunt-contrib-clean": "~0.5.0",
- "grunt-cleanempty": "~0.2.0",
- "grunt-htmlrefs": "~0.5.0",
- "grunt-css": "~0.5.4",
- "grunt-contrib-less": "~0.9.0",
- "grunt-remove": "~0.1.0",
+ "grunt": "^1.0.1",
+ "grunt-apidoc": "^0.11.0",
+ "grunt-cleanempty": "^1.0.4",
+ "grunt-contrib-clean": "^1.0.0",
+ "grunt-contrib-concat": "^1.0.1",
+ "grunt-contrib-copy": "^1.0.0",
+ "grunt-contrib-less": "^1.3.0",
+ "grunt-contrib-uglify": "^1.0.1",
+ "grunt-css": "^0.5.4",
+ "grunt-htmlrefs": "^0.5.0",
"grunt-ngmin": "0.0.3",
- "grunt-text-replace": "~0.3.11",
- "protractor": "~3.2.2",
- "selenium": "~2.20.0"
+ "grunt-text-replace": "^0.4.0",
+ "protractor": "^3.3.0",
+ "selenium": "^2.20.0"
}
}
diff --git a/docs-web/src/main/webapp/src/partial/docs/document.default.html b/docs-web/src/main/webapp/src/partial/docs/document.default.html
index 0d814030..c15b146b 100644
--- a/docs-web/src/main/webapp/src/partial/docs/document.default.html
+++ b/docs-web/src/main/webapp/src/partial/docs/document.default.html
@@ -51,6 +51,8 @@
+ - Crafted with by Sismics
+ - API Documentation
- Version: {{ app.current_version }}
- Memory: {{ app.free_memory / 1000000 | number: 0 }}/{{ app.total_memory / 1000000 | number: 0 }} MB
diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.html b/docs-web/src/main/webapp/src/partial/docs/document.view.html
index a6a7fb94..3e94f557 100644
--- a/docs-web/src/main/webapp/src/partial/docs/document.view.html
+++ b/docs-web/src/main/webapp/src/partial/docs/document.view.html
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html b/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html
index 6cd7fe70..d9033895 100644
--- a/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html
+++ b/docs-web/src/main/webapp/src/partial/docs/settings.user.edit.html
@@ -27,7 +27,7 @@
+ ng-minlength="1" ng-maxlength="100" placeholder="E-mail" ng-model="user.email"/>
diff --git a/docs-web/src/main/webapp/src/partial/share/share.html b/docs-web/src/main/webapp/src/partial/share/share.html
index c581ae07..9ea9ed90 100644
--- a/docs-web/src/main/webapp/src/partial/share/share.html
+++ b/docs-web/src/main/webapp/src/partial/share/share.html
@@ -1,7 +1,7 @@
-
-
+
+
Export
diff --git a/docs-web/src/main/webapp/src/style/main.less b/docs-web/src/main/webapp/src/style/main.less
index dbf01f1c..84db7663 100644
--- a/docs-web/src/main/webapp/src/style/main.less
+++ b/docs-web/src/main/webapp/src/style/main.less
@@ -254,6 +254,13 @@ input[readonly].share-link {
}
}
+// Export dropdown
+.btn-export {
+ .dropdown-menu {
+ left: -62px;
+ }
+}
+
/* Styling for the ngProgress itself */
#ngProgress {
margin: 0;
diff --git a/pom.xml b/pom.xml
index cbd0371d..b3cadb17 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.sismics.docs
docs-parent
pom
- 1.4-SNAPSHOT
+ 1.5-SNAPSHOT
Docs Parent