Security and multiple sites in Appian

Hi,

I have two applications and the respective sites for those applications for now. In future these count of applications may grow.

Now, I got a requirement that I have to provide a common interface which user can use to navigate the respective site based on the application groups user belonging to.

Some users may have access to both sites and some users have access to a single site.

Can someone advise how and the best way to handle the situation. 

Thanks in advance.

  Discussion posts and replies are publicly visible

  • Assuming you simply need to hide/show components such as links on an interface, you can utilize a!isUserMemberOfGroup() to determine if the link should show based on group membership:

    a!linkField(
      showWhen: a!isUserMemberOfGroup(
        username: loggedInUser(),
        group: cons!YOUR_ACCESS_GROUP_HERE,
        matchAllGroups: true    
      ),
      links: {/* link here */}
    )

    If that is not what you are looking for, please provide any additional details on your use case.

  • 0
    Certified Lead Developer

    In addition to what Chris supplied already, which I agree with, I find it useful to base Site Viewership for each individual site on one specific "site viewership" group.  The group in question can contain other sub-groups as needed.  But it makes it relatively easy at all times to use a simple expression evaluating group membership for the current user, to determine whether they should have access to a particular site.

  • I have a series of steps to gracefully achieve it. 

    1. Create a common application and the all users group of that app should have the all users group of all the other apps. 
    2. Create a site in that app and use the code below to create the interface to navigate to different sites. 
      a!localVariables(
        local!columnsInARow: 4,
        local!configurations: {
          {
            icon: "cubes",
            title: "Manage Stock",
            description: "Manage your inventory in the system",
            showWhen: true,
            url: null
          },
          {
            icon: "dollar",
            title: "Manage Price",
            description: "Manage pricing of items you offer",
            showWhen: true,
            url: null
          },
          {
            icon: "users",
            title: "Manage Users",
            description: "Manage users within your organization",
            showWhen: true,
            url: null
          },
          {
            icon: "ad",
            title: "Manage Ads",
            description: "Manage advertisments across platforms",
            showWhen: true,
            url: null
          },
          {
            icon: "cogs",
            title: "More settings",
            description: "Access more settings of the system",
            showWhen: true,
            url: null
          }
        },
        local!visibleConfigurations: reject(
          a!isNullOrEmpty(_),
          a!forEach(
            items: local!configurations,
            expression: if(or(fv!item.showWhen), fv!item, null)
          )
        ),
        local!numberOfRows: ceiling(
          count(local!visibleConfigurations) / local!columnsInARow
        ),
        {
          a!forEach(
            items: enumerate(local!numberOfRows),
            expression: a!columnsLayout(
              columns: {
                a!forEach(
                  items: index(
                    local!visibleConfigurations,
                    enumerate(local!columnsInARow) + 1 + (fv!item * local!columnsInARow),
                    null
                  ),
                  expression: a!columnLayout(
                    contents: a!cardLayout(
                      contents: {
                        a!richTextDisplayField(
                          labelPosition: "COLLAPSED",
                          value: {
                            a!richTextIcon(
                              icon: fv!item.icon,
                              color: "ACCENT",
                              size: "LARGE"
                            ),
                            char(10),
                            a!richTextItem(text: fv!item.title, size: "MEDIUM"),
                            char(10),
                            a!richTextItem(
                              text: fv!item.description,
                              color: "SECONDARY",
                              size: "SMALL"
                            )
                          },
                          align: "CENTER"
                        )
                      },
                      link: a!safeLink(uri: fv!item.url),
                      /* • Replace dynamic link with any other link type*/
                      height: "SHORT",
                      showWhen: not(a!isNullOrEmpty(fv!item))
                    ),
                    
                  )
                )
              }
            )
          )
        }
      )
    3. Now in front of showWhen you can use the function Chris proposed to check the security and the code will auto handle the visibility. 

    There is just one overhead with this approach. You will need to update this interface everytime you add/remove a site in the system

  • 0
    Certified Lead Developer
    in reply to Harshit Bumb (Appyzie)
    You will need to update this interface everytime you add/remove a site

    I doubt there's any easy way around this, unless someone very carefully sets things up in advance in such a way that this would be supported - and even then, at least some objects would need manual updating when the system site collection is updated.

  • Do I need to create a separate site and which is common across all the applications and do this kind of implementation.

  • 0
    Certified Lead Developer
    in reply to swapnar6405
    Do I need to create a separate site

    This would be the easiest approach for this by quite a bit - for instance I created a "default site" that's viewable to all users and loaded by default in case a user doens't have permission to one of the other sites they might have groupwise access to otherwise.

  • If I create a separate site(default site) then what about the users and groups. 

    Do I need to create groups and users in the default site otherwise, how can I verify groups/users which are part of other application(s).

    Please advice.

    Thanks.

  • 0
    Certified Lead Developer
    in reply to swapnar6405

    Create a "default site" with its own viewership group.  Add any other groups which should (ever) have viewership to that site, to this site's viewership group.  That might even include "all users" group(s) in this case.  Your other site(s) and their group(s) wouldn't necessarily be effected by this. 

    If you're after anything particularly more specific here, though, you'll need to specify what your special requirements are.

  • a!linkField(
    showWhen: a!isUserMemberOfGroup(
    username: loggedInUser(),
    group: cons!YOUR_ACCESS_GROUP_HERE,
    matchAllGroups: true
    ),
    links: {/* link here */}
    )

    We have different kind of links. Do I need to use any specific link types to navigate to Appian site?

  • 0
    Certified Lead Developer
    in reply to swapnar6405

    Don't use a!linkField for anything (ever).  Instead use a!richTextDisplayField(), and in its text item, use a!safeLink().  Your safeLink will need to (manually) call the URL of the Site in question.  I don't currently know of any programmatic way to link to an alternate site rather than manually linking the site URL (though this can include assembling the URL using the site's stub and the current environment's URL).