Table of Contents
While not strictly part of the Java API provided by the Guacamole project, guacamole-ext is an API exposed by the Guacamole web application within a separate project such that extensions, specifically authentication providers, can be written to tweak Guacamole to fit well in existing deployments.
Extensions to Guacamole can:
- Provide alternative authentication methods and sources of connection/user data. 
- Theme or brand Guacamole through additional CSS files and static resources. 
- Extend Guacamole's JavaScript code by providing JavaScript that will be loaded automatically. 
- Add additional display languages, or alter the translation strings of existing languages. 
Guacamole extensions are standard Java .jar files which contain
            all classes and resources required by the extension, as well as the Guacamole extension
            manifest. There is no set structure to an extension except that the manifest must be in
            the root of the archive. Java classes and packages, if any, will be read from the
                .jar relative to the root, as well.
Beyond this, the semantics and locations associated with all other resources within the extension are determined by the extension manifest alone.
The Guacamole extension manifest is a single JSON file,
                    guac-manifest.json, which describes the location of each
                resource, the type of each resource, and the version of Guacamole that the extension
                was built for. The manifest can contain the following properties:
| Property | Description | 
|---|---|
| guacamoleVersion | The version string of the Guacamole release that this
                                    extension is written for. This property is required
                                        for all extensions. The special version string
                                         | 
| name | A human-readable name for the extension. This property is required for all extensions. When your extension is successfully loaded, a message acknowledging the successful loading of your extension by name will be logged. | 
| namespace | A unique string which identifies your extension. This property is required for all extensions. This string should be unique enough that it is unlikely to collide with the namespace of any other extension. If your extension contains static resources, those resources will be served at a path derived from the namespace provided here. | 
| authProviders | An array of the classnames of all
                                         | 
| js | An array of all JavaScript files within the extension. All paths within this array must be relative paths, and will be interpreted relative to the root of the archive. JavaScript files declared here will be automatically loaded when the web application loads within the user's browser. | 
| css | An array of all CSS files within the extension. All paths within this array must be relative paths, and will be interpreted relative to the root of the archive. CSS files declared here will be automatically applied when the web application loads within the user's browser. | 
| translations | An array of all translation files within the extension. All paths within this array must be relative paths, and will be interpreted relative to the root of the archive. Translation files declared here will be automatically added to the available languages. If a translation file provides a language that already exists within Guacamole, its strings will override the strings of the existing translation. | 
| resources | An object where each property name is the name of a web resource file, and each value is the mimetype for that resource. All paths within this object must be relative paths, and will be interpreted relative to the root of the archive. Web resources declared here will be made available to the
                                    application at
                                             | 
The only absolutely required properties are guacamoleVersion,
                    name, and namespace, as they are used
                to identify the extension and for compatibility checks. The most minimal
                    guac-manifest.json will look something like this:
{
    "guacamoleVersion" : "0.9.8",
    "name" : "My Extension",
    "namespace" : "my-extension"
}This will allow the extension to load, but does absolutely nothing otherwise.
                Lacking the semantic information provided by the other properties, no other files
                within the extension will be used. A typical guac-manifest.json
                for an extension providing theming or branding would be more involved:
{
    "guacamoleVersion" : "0.9.8",
    "name"      : "My Extension",
    "namespace" : "my-extension",
    "css" : [ "theme.css" ],
    "resources" : {
        "images/logo.png"   : "image/png",
        "images/cancel.png" : "image/png",
        "images/delete.png" : "image/png"
    }
}The configuration of the Guacamole server is exposed through the
                Environment interface, specifically the
                LocalEnvironment implementation of this interface. Through
                Environment, you can access all properties declared within
                guacamole.properties, determine the proper hostname/port of
                guacd, and access the contents of
                GUACAMOLE_HOME.
If your extension requires generic, unstructured configuration parameters,
                    guacamole.properties is a reasonable and simple location
                for them. The Environment interface provides direct access to
                    guacamole.properties and simple mechanisms for reading and
                parsing the properties therein. The value of a property can be retrieved calling
                    getProperty(), which will return
                    null or a default value for undefined properties, or
                    getRequiredProperty(), which will throw an exception
                for undefined properties.
For convenience, guacamole-ext contains several pre-defined property base classes for common types:
| Class Name | Value Type | Interpretation | 
|---|---|---|
| BooleanGuacamoleProperty | Boolean | The values "true" and "false" are parsed as their corresponding Booleanvalues. Any other value results
                                in a parse error. | 
| IntegerGuacamoleProperty | Integer | Numeric strings are parsed as Integervalues. Non-numeric strings will result in a parse error. | 
| LongGuacamoleProperty | Long | Numeric strings are parsed as Longvalues.
                                Non-numeric strings will result in a parse error. | 
| StringGuacamoleProperty | String | The property value is returned as an untouched String. No parsing is performed, and
                                parse errors cannot occur. | 
| FileGuacamoleProperty | File | The property is interpreted as a filename, and a new Filepointing to that filename is
                                returned. If the filename is invalid, a parse error will be thrown.
                                Note that the file need not exist or be accessible for the filename
                                to be valid. | 
To use these types, you must extend the base class, implementing the
                    getName() function to identify your property.
                Typically, you would declare these properties as static members of some class
                containing all properties relevant to your extension:
public class MyProperties {
    public static MY_PROPERTY = new IntegerGuacamoleProperty() {
        @Override
        public String getName() { return "my-property"; }
    };
}Your property can then be retrieved with getProperty() or
                    getRequiredProperty():
Integer value = environment.getProperty(MyProperties.MY_PROPERTY);If you need more sophisticated parsing, you can also implement your own property
                types by implementing the GuacamoleProperty interface. The
                only functions to implement are getName(), which returns
                the name of the property, and parseValue(), which parses a
                given string and returns its value.
If you need more structured data than provided by simple properties, you can place
                completely arbitrary files in a hierarchy of your choosing anywhere within
                    GUACAMOLE_HOME as long as you avoid placing your files in
                directories reserved for other purposes as described above.
The Environment interface exposes the location of
                    GUACAMOLE_HOME through the
                    getGuacamoleHome() function. This function returns a
                standard Java File which can then be used to locate other
                files or directories within GUACAMOLE_HOME:
File myConfigFile = new File(environment.getGuacamoleHome(), "my-config.xml");
There is no guarantee that GUACAMOLE_HOME or your file will
                    exist, and you should verify this before proceeding further in your extension's
                    configuration process, but once this is done you can simply parse your file as
                    you see fit.
The main use of guacamole-ext is to provide custom authentication
            for Guacamole through the implementation of authentication
            providers. An authentication provider is any class which implements
            the AuthenticationProvider interface,
            implementing the only function defined by that interface:
                getUserContext(). This function is
            required to return a "context" which provides access to only those
            users and configurations accessible with the given credentials, and
            enforces its own security model.
The credentials given are abstract and while Guacamole the web
            application implements a username/password driven login screen, you
            are not required to user usernames and passwords; the
                Credentials class given to the
            authentication provider provides access to all HTTP parameters in
            general, as well as cookies and SSL information.
The Guacamole web application includes a basic authentication
            provider implementation which parses an XML file to determine which
            users exist, their corresponding passwords, and what configurations
            those users have access to. This is the part of Guacamole that reads
            the user-mapping.xml file. If you use a custom
            authentication provider for your authentication, this file will
            probably not be required.
The community has implemented authentication providers which
            access databases, use LDAP, or even perform no authentication at
            all, redirecting all users to a single configuration specified in
                guacamole.properties.
A minimal authentication provider is implemented in the tutorials later, and the upstream authentication provider implemented within Guacamole, as well as the authentication providers implemented by the community, are good examples for how authentication can be extended without having to implement a whole new web application.
The SimpleAuthenticationProvider class
                provides a much simpler means of implementing authentication
                when you do not require the ability to add and remove users and
                connections. It is an abstract class and requires only one
                function implementation:
                    getAuthorizedConfigurations().
This function is required to return a
                    Map of unique IDs to configurations,
                where these configurations are all configurations accessible
                with the provided credentials. As before, the credentials given
                are abstract. You are not required to use usernames and
                passwords.
The configurations referred to by the function name are
                instances of GuacamoleConfiguration (part
                of guacamole-common), which is just a wrapper around a protocol
                name and set of parameter name/value pairs. The name of the
                protocol to use and a set of parameters is the minimum
                information required for other parts of the Guacamole API to
                complete the handshake required by the Guacamole
                protocol.
When a class that extends
                    SimpleAuthenticationProvider is asked
                for more advanced operations by the web application,
                    SimpleAuthenticationProvider simply
                returns that there is no permission to do so. This effectively
                disables all administrative functionality within the web
                interface.
If you choose to go the simple route, most of the rest of this
                chapter is irrelevant. Permissions, security model, and various
                classes will be discussed that are all handled for you
                automatically by
                    SimpleAuthenticationProvider.
The UserContext is the root of all
                operations. It is used to list, create, modify, or delete users
                and connections, as well as to query available
                permissions.
The Guacamole web application uses permissions queries against
                the UserContext to determine what
                operations to present, but beware that it is up to the
                        UserContext to actually enforce
                    these restrictions. The Guacamole web application
                will not enforce restrictions on behalf of the
                    UserContext.
The UserContext is the sole means of
                entry and the sole means of modification available to a
                logged-in user. If the UserContext
                refuses to perform an operation (by throwing an exception), the
                user cannot perform the operation at all.
Access to users and connections is given through
                    Directory classes. These
                    Directory classes are similar to Java
                collections, but they also embody object update semantics.
                Objects can be retrieved from a Directory
                using its get() function and added or
                removed with add() and
                    remove() respectively, but objects
                already in the set can also be updated by passing an updated
                object to its update() function.
An implementation of a Directory can
                rely on these functions to define the semantics surrounding all
                operations. The add() function is
                called only when creating new objects, the
                    update() function is called only
                when updating an object previously retrieved with
                    get(), and
                    remove() is called only when
                removing an existing object by its identifier.
When implementing an
                    AuthenticationProvider, you must
                ensure that the UserContext will only
                return Directory classes that
                automatically enforce the permissions associated with all
                objects and the associated user.
The permissions system within guacamole-ext is an advisory system. It is the means by which an authentication module describes to the web application what a user is allowed to do. The body of permissions granted to a user describes which objects that user can see and what they can do to those objects, and thus suggests how the Guacamole interface should appear to that user.
Permissions are not the means by which access is restricted; they are purely a means of describing access level. An implementation may internally use the permission objects to define restrictions, but this is not required. It is up to the implementation to enforce its own restrictions by throwing exceptions when an operation is not allowed, and to correctly communicate the abilities of individual users through these permissions.
System permissions describe access to operations that manipulate the system as a whole, rather than specific objects. This includes the creation of new objects, as object creation directly affects the system, and per-object controls cannot exist before the object is actually created.
- ADMINISTER
- The user is a super-user - the Guacamole equivalent of root. They are allowed to manipulate of system-level permissions and all other objects. This permission implies all others. 
- CREATE_CONNECTION
- The user is allowed to create new connections. If a user has this permission, the management interface will display components related to connection creation, such as the "Manage" and "New Connection" buttons. 
- CREATE_CONNECTION_GROUP
- The user is allowed to create new connection groups. If a user has this permission, the management interface will display components related to connection group creation, such as the "Manage" and "New Group" buttons. 
- CREATE_USER
- The user is allowed to create other users. If a user has this permission, the management interface will display components related to user creation, such as the "Manage" and "New User" buttons. 
Object permissions describe access to operations that affect a particular object. Guacamole currently defines three types of objects which can be associated with permissions: users, connections, and connection groups. Each object permission associates a single user with an action that may be performed on a single object.
- ADMINISTER
- The user may grant or revoke permissions involving this object. "Involving", in this case, refers to either side of the permission association, and includes both the user to whom the permission is granted and the object the permission affects. 
- DELETE
- The user may delete this object. This is distinct from the - ADMINISTERpermission which deals only with permissions. A user with this permission will see the "Delete" button when applicable.
- READ
- The user may see that this object exists and read the properties of that object. - Note that the implementation is not required to divulge the true underlying properties of any object. The parameters of a connection, the type or contents of a connection group, the password of a user, etc. all need not be exposed. - This is particularly important from the perspective of security when it comes to connections, as the parameters of a connection are only truly needed when a connection is being modified, and likely should not be exposed otherwise. The actual connection operation is always performed internally by the authentication provider, and thus does not require client-side knowledge of anything beyond the connection's existence. 
- UPDATE
- The user may change the properties of this object. - In the case of users, this means the user's password can be altered. Permissions are not considered properties of a user, nor objects in their own right, but rather associations between a user and an action which may involve another object. - The properties of a connection include its name, protocol, parent connection group, and parameters. The properties of a connection group include its name, type, parent connection group, and children. 
Authentication modules must return Connection objects which
                each implement a connect() function. When this function is
                called, the connection must be made if permission is available.
This new separation of concerns makes more sense when you
                consider that as connecting is an operation on a
                    Connection, access to performing that
                operation must be restricted through the
                    AuthenticationProvider, and thus must
                be enforced within the
                    AuthenticationProvider. This
                separation also opens the door for things like load balancing of
                connections and restricting concurrent access to
                connections.
When a connection is made or terminated, it is also the duty
                of the authentication module to maintain the connection history.
                Each connection has a corresponding list of
                    ConnectionRecord objects, each of
                which is associated with a past connection or a currently-active
                connection. This information will ultimately be exposed to the
                user as a history list when they view a connection in the
                management interface or as a simple active user count on the
                connection, advising the user of existing activity.