User of Server Code

You need to be aware of who executes server code on Kii Cloud. Kii Cloud has the access control mechanism for protecting application data from being accessed by unauthorized users. For server code to access some application data, therefore, it must be executed by a user who has the appropriate permission to access the data or with an app admin context that would grant the app administrator's privilege.

Server code can be executed with one of the following user privileges.

Anonymous user

This is the default user at the time server code is launched.

An anonymous user can use features for reading data without login.

Server code runs with an anonymous user's privilege by default, so it has limited access to data. You can perform tasks like some simple calculation, accessing resources outside Kii Cloud and reading an application scope bucket as an anonymous user, but you need to get other privileges (those shown below) in order to read data stored in user scope buckets.

The following code accesses a bucket myAppBucket in the application scope with an anonymous user's privilege. Manipulation of KiiObjects is omitted.

function main(params, context, done) {
  // Handle application scope bucket.
  var appBucket = Kii.bucketWithName("myAppBucket");

  done("Success");
}

User who manually executes server code

If server code is manually executed, it can get an access token of the user who executed the code. By logging in with this token, server code can execute Kii Cloud APIs with this user's privilege. This will allow the code to access buckets in this user's scope.

If server code is executed manually, you can execute the server code as if the user who executed the server code has logged in. If the server code is executed via a trigger-based hook, you can execute the server code as if the user who triggered the execution has logged in.

In both cases, you will get the access token with the getAccessToken() method and execute the login with this access token. Once the login is done, you can access the data in the target bucket.

function main(params, context, done) {
  if (context.getAccessToken() == null) {
     done("Sorry, we don't allow an anonymous user");
     return;
  }
  KiiUser.authenticateWithToken(context.getAccessToken(), {
    success: function(theUser) {
      // Handle application scope bucket.
      var appBucket = Kii.bucketWithName("myAppBucket");

      // Handle group scope bucket. (You need groupID parameter)
      var group = KiiGroup.groupWithName(params.groupID);
      var groupBucket = group.bucketWithName("myGroupBucket");

      // Handle user scope bucket.
      // You can use getCurrentUser(). It is same as theUser in this code.
      var user = KiiUser.getCurrentUser();
      var userBucket = user.bucketWithName("myUserBucket");

      done("Success");
    },
    failure: function(theUser, errorString) {
      done("Error authenticating: " + errorString);
    }
  });
}

Any authenticated user

You can log in as any user in server code by specifying the valid username and password. After logging in, the server code can execute Kii Cloud API with this user's privilege.

If you have an application scope bucket that is open to only a specific user, this strategy might be useful (alternatively, you can use the app administrator context as described in the next section).

function main(params, context, done) {
  // Define the secret account.
  var username = "servercode";
  var password = "123ABC";

  // Authenticate a user.
  KiiUser.authenticate(username, password, {
    success: function(theUser) {
        // Handle application scope bucket.
        var appBucket = Kii.bucketWithName("myAppBucket");

        // Handle group scope bucket. (You need groupID parameter)
        var group = KiiGroup.groupWithName(params.groupID);
        var groupBucket = group.bucketWithName("myGroupBucket");

        // Handle user scope bucket.
        // You can use getCurrentUser(). It is same as theUser in this code.
        var user = KiiUser.getCurrentUser();
        var userBucket = user.bucketWithName("myUserBucket");

        done("Success");
    },
    failure: function(theUser, errorString) {
        done("Error authenticating: " + errorString);
    }
  })
}

Administrator

By using the admin context in server code, it can access all data in the application as an administrator. Just using the administrator context is sufficient; you do not need to log in as an administrator. There is an endpoint parameter in the server code that provides a method for getting an admin context. By specifying the user ID or group ID in this context, you will be able to access the user and group objects with the administrator privilege.

In both cases, you will get the app administrator context with the getAppAdminContext method and access the data in the target bucket using the methods in the context.

function main(params, context, done) {
  // Get the administrator's context.
  var admin = context.getAppAdminContext();

  // Create a bucket in the application scope.
  var appBucket = admin.bucketWithName("myAppBucket");

  // Create a bucket in a group scope by specifying the groupID parameter.
  var group = admin.groupWithID(params.groupID);
  var groupBucket = group.bucketWithName("myGroupBucket");

  // Create user scope bucket by specifying the userID parameter.
  var user = admin.userWithID(params.userID);
  var userBucket = user.bucketWithName("myUserBucket");

  // Return a value to the caller.
  done(appBucket + "," + userBucket);
}

Make sure to use the methods provided by the context returned by the getAppAdminContext method (the variable "admin" in the above sample code) to gain the app administrator privileges. If you use the Kii.bucketWithName or KiiObject.objectWithURI method, for example, you will be accessing an application-scope bucket and object as an anonymous user.

See Admin Features to learn the features available with the app administrator privilege (in this page, the procedure for getting the app administrator context is presented, but you do not need this procedure in server code). Also, refer to the JSDoc for the details.

For an example that uses the administrator's privilege, see also Setting Data Automatically with a Trigger-based Hook.

Be careful that you are not logging in as the app administrator. Executing the getCurrentUser method will not return the app administrator token. If you execute the method in the above sample code, for instance, you will get a null that represents an anonymous user.

Be careful when leveraging the app administrator privilege. The data is usually protected with ACLs, but the app administrator privilege will override the protection and allow full access to all data. If your server code is going to handle confidential data, consider implementing some protections against unauthorized execution in your server code, like checking the user who has initiated the execution and adding some parameter check.

Creating a data area for management

You can use the administrator privilege to protect some data from being accessed by users. This will encapsulate all accesses to the bucket with server code, preventing unauthorized access by users.

First, create an application scope bucket and modify its ACL to revoke user's access privilege (you can further change the scope ACL to disallow users from creating a new bucket). Then, implement your server code to get an admin context and use it to manipulate this bucket.

See also Application-scope data for the related discussion.