add Oauth link

Hi,

In my code I'm trying to create a new user, and I also want to add a new Oauth link, because our users connect to the community

using Oauth. I'm at the point in which I created the user and I want to add the new OAuthLink, but it needs a clientTypeclientUserId and a userId.

    public class OAuthLink
    {
        public OAuthLink(string clientType, string clientUserId, int userId);

        public string ClientType { get; set; }
        public string ClientUserId { get; set; }
        public int UserId { get; set; }
    }

I have the clientType and the userId, but how do I get a new clientUserId so it won't generate a duplicate in the community, or better yet how are clientUserId's generated?

            //the code I'm trying to use
            OAuthLink newLink = new OAuthLink(ClientType, userID, clientUserID);
            _OAuthService.AddOAuthLink(newLink);

Regards,

Silviu 

  • Hi . Can you explain a little more about what you're trying to achieve? That is a private, unsupported, API.

  • The second line of code is custom code indeed. Just want to add a new Oauth Link in the [te_OAuth_Links] table, and I was missing the ClientUserId code, but I made it work, thanks anyway.

  • You should never manually create this, it is  not necessary.  A correctly built OAuth client will internally do this automatically.

  • Hi Patrick,

    In the Verint.Services.SamlAuthenticationPlugin there is the option to implement ISamlOAuthLinkManager which would be used to automatically add/update the te_Oauth_Links table for existing users if say sso was added to an existing community and removes the need to manually add 

    /// <summary>
    /// Allows the plugin to use unsupported code to ensure the proper entries exist in the te_OAuth_Links table prior to sending the user
    /// back to the login form with the OAuth token. The net effect is this code will automatically link all SAML IDs to Telligent Accounts
    /// Due to the fact that the te_OAuth_Links table only allows a single nameid to relate to a userid, in some cases it may be necessary to remove
    /// the existing te_OAuth_Links table and re-add it if you have a use case where the same user can log in via different saml logins
    /// (ie same email associated with two seperate saml logins)
    /// </summary>

    This is for existing users only 

    // makes sure the user is not prompted to "link accounts" during the login form
    //if there is no suitable entry in the te_OAuth_Links table
    samlOAuthLinkManager.EnsureOAuthLink(samlTokenData);

    In this case what other options are there rather than using _OAuthService.AddOAuthLink(newLink);

    as otherwise we would need to perform direct db updates which is very bad

  • I have the same question. Yes I’m going to do some more bad coding to insert this record. Just to prototype.. maybe this is all sorted out on version 12, but I need to force this bad or not until we can upgrade.   FYI is there anyone that can comment on the changes and/or how to address this on 9-12?

  • So here is my  implementation on the above mention plugin.. I know I am missing something but let me know 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    using System.ServiceModel.Security;
    
    using System.Data;
    using System.Data.SqlClient;
    
    using System.Web;
    using System.Xml;
    using Telligent.DynamicConfiguration.Components;
    using Telligent.Evolution.Extensibility.Api.Version1;
    using Telligent.Evolution.Extensibility.Authentication.Version1;
    using Telligent.Evolution.Extensibility.Storage.Version1;
    using Telligent.Evolution.Extensibility.UI.Version1;
    using Telligent.Evolution.Extensibility.Urls.Version1;
    using Telligent.Evolution.Extensibility.Version1;
    using Telligent.Services.SamlAuthenticationPlugin.Components;
    using Telligent.Services.SamlAuthenticationPlugin.Extensibility.Events;
    using Telligent.Services.SamlAuthenticationPlugin.Extensibility;
    
    namespace Telligent.Services.SamlAuthenticationPlugin.Plugins.OauthLink
    {
        public class LinkSamlUsers : ISamlOAuthLinkManager
        {
    
            public bool Enabled { get { return true; } }
            string[] cats = { "SAML", "OAuth" };
            private IEventLog _eventLogApi;
            private IUsers _usersApi;
    
            public string Name { get { return "SAML Link Manager";  } }
    
            public string Description { get { return "Links a user account with SAML token";  } }
    
            public string[] Categories { get { return cats; } }
    
            public void EnsureOAuthLink(SamlTokenData samlTokenData )
            {
                var apiUser = _usersApi.Get(new UsersGetOptions { Id = samlTokenData.UserId });
                
                var oauthData = new OAuthData();
                oauthData.ClientId = apiUser.Id.ToString();
                oauthData.ClientType = samlTokenData.ClientType;
                oauthData.Email = apiUser.PrivateEmail; 
                oauthData.UserName = apiUser.Username; 
    
                if (!SqlData.isUserLinked(oauthData) && apiUser.Id.HasValue)
                {
                    // TODO: use an upgrade safe method
                    // to link saml user to account 
                    SqlData.Insert_te_OAuth_Links(samlTokenData.ClientType, samlTokenData.NameId, apiUser.Id.Value);
                }
                 
    
            }
    
    
            public void Initialize()
            {
                 _eventLogApi = PublicApi.Eventlogs;
                 _usersApi = PublicApi.Users; 
                
            }
    
           
            
        }
    }
    

    sql data to check and insert data.. 

    internal static bool isUserLinked(OAuthData oauthData)
            {
                bool _isUserLinked = false;
    
                bool clientIdParsed = Int32.TryParse(oauthData.ClientId, out int userId);
                if (clientIdParsed)
                {
    
                    try
                    {
                        using (var conn = GetSqlConnection())
                        {
    
                            var sql = string.Format(
                                  @"SELECT COUNT(*) FROM [{0}].[te_OAuth_Links] WHERE [UserId] = @userId",
                                    databaseOwner);
                            var myCommand = new SqlCommand(sql, conn); // { CommandType = CommandType.Text };
    
                            myCommand.Parameters.Add("@userId", SqlDbType.Int).Value = userId;
                            conn.Open();
                            int myCount = (Int32)myCommand.ExecuteScalar();
                            _isUserLinked = myCount > 0;
                            //myCommand.ExecuteNonQuery();
                        }
                    }
                    catch (Exception ex)
                    {
                        PublicApi.Eventlogs.Write("Error updating from dte_OAuth_Links. " + ex.ToString(), new EventLogEntryWriteOptions() { Category = "SAML", EventId = 6010, EventType = "Error" });
                    }
                }
                return _isUserLinked;
            }
    
             
            internal static void Insert_te_OAuth_Links(string clientType, string nameId, int userId)
            {
                try
                {
    
    
                    using (var conn = GetSqlConnection())
                    {
                        var sql = string.Format(
                              @"INSERT INTO [{0}].[te_OAuth_Links]
                                ([UserId]
                                ,[ClientType]
                                ,[ClientUserId])
                            VALUES
                                (@userId
                                ,@clientType
                                ,@clientUserId )",
                                databaseOwner);
                        var myCommand = new SqlCommand(sql, conn) { CommandType = CommandType.Text };
    
                        myCommand.Parameters.Add("@userId", SqlDbType.Int).Value = userId;
                        myCommand.Parameters.Add("@ClientType", SqlDbType.Text).Value = clientType;
                        myCommand.Parameters.Add("@clientUserId", SqlDbType.NVarChar).Value = nameId;
    
                        conn.Open();
                        myCommand.ExecuteNonQuery();
    
    
    
                    }
                }
                catch (Exception ex)
                {
                    PublicApi.Eventlogs.Write("Error updating from dte_OAuth_Links. " + ex.ToString(), new EventLogEntryWriteOptions() { Category = "SAML", EventId = 6010, EventType = "Error" });
                }
    
            }

  • Direct interaction with the schema is not supported.  You should not need it at all, you should always return new OAuthData adn the platform looks it up. 

    Also this version is end of life and has been for some time, please upgrade to 12.1.

  • I know I know. It's so embarrassing.  We have our upgrade on the road map. Our hold up is that we have an old authentication system that we must retire and replace first, using saml, and then upgrade Telligent 12.x.