anchor.diff:           set_debug_mode/1
           ]).
   
  --export_type([
  -              oidc_id/0,
  -              user_info/0,
  -              cred/0
  -             ]).
  -
  --type oidc_id() :: { Issuer:: binary(), Subject::binary() }.
  -
  --type user_info() :: #{ uid => binary(),
  -                        uidNumber => integer(),
  -                        gidNumber => integer(),
  -                        homeDirectory => binary(),
  -                        issuer => binary(),
  -                        subject => binary(),
  -                        groups => [binary()],
  -                        userIds => [oidc_id()]
  -                      }.
  -
  --type cred() :: #{ cred_id => binary(), ctime => integer(),
  -                   cred_state => binary(), service_id => binary(),
  -                   interface => binary(), user_id => binary()
  -                 }.
  -
  +
  +login_with_oidcc(#{id := #{claims := #{ sub := Subject, iss := Issuer}}}
  += TokenMap) ->
  +    {ok, SessPid} = tts_session_mgr:new_session(),
  +    try
  +        {ok, UserInfo} = tts_user_cache:get_user_info(Issuer, Subject),
  +        {ok, SessId} = tts_session:get_id(SessPid),
  +        ok = tts_session:set_token(TokenMap, SessPid),
  +        ok = tts_session:set_user_info(UserInfo, SessPid),
  +        true = tts_session:is_logged_in(SessPid),
  +        lager:debug("login success"),
  +        {ok, #{session_id => SessId, session_pid => SessPid}}
  +    catch _:_ ->
  +            tts_session:close(SessPid),
  +            lager:debug("login internal fail"),
  +            {error, internal}
  +    end;
  +login_with_oidcc(_BadToken) ->
  +    lager:debug("bad token"),
  +    {error, bad_token}.
  +
  +login_with_access_token(AccessToken, Issuer) when is_binary(AccessToken),
  +                                                  is_binary(Issuer) ->
  +    {ok, SessPid} = tts_session_mgr:new_session(),
  +    try
  +        {ok, ProviderPid} = oidcc:find_openid_provider(Issuer),
  +        {ok, #{issuer := Issuer}} = oidcc:get_openid_provider_info(ProviderPid),
  +        {ok, #{sub := Subject} = OidcInfo} =
  +            oidcc:retrieve_user_info(AccessToken, ProviderPid),
  +        Token = #{access => #{token => AccessToken}, user_info => OidcInfo},
  +        {ok, UserInfo} = tts_user_cache:get_user_info(Issuer, Subject),
  +        {ok, SessId} = tts_session:get_id(SessPid),
  +        ok = tts_session:set_token(Token, SessPid),
  +        ok = tts_session:set_user_info(UserInfo, SessPid),
  +        ok = tts_session:set_iss_sub(Issuer, Subject, SessPid),
  +        true = tts_session:is_logged_in(SessPid),
  +        lager:debug("login success"),
  +        {ok, #{session_id => SessId, session_pid => SessPid}}
  +    catch _:_ ->
  +            tts_session:close(SessPid),
  +            {error, internal}
  +    end;
  +login_with_access_token(_AccessToken, _Issuer) ->
  +    {error, bad_data}.
  +
  +logout(Session) ->
  +    tts_session:close(Session).
  +
  +
  +does_provider_exist(Id, _Session) ->
  +    case oidcc:get_openid_provider_info(Id) of
  +        {ok, _Info} -> true;
  +        _ -> false
  +    end.
  +
  +does_service_exist(Id, Session) ->
  +    {ok, UserInfo} =  tts_session:get_user_info(Session),
  +    {ok, List} = tts_service:get_list(UserInfo),
  +    IsMember = fun(#{id := ServiceId}, Found) ->
  +                       case ServiceId of
  +                           Id ->
  +                               true;
  +                           _ -> Found
  +                       end
  +               end,
  +    lists:foldl(IsMember, false, List).
  +
  +does_credential_exist(Id, Session) ->
  +    {ok, #{site := #{uid :=UserId}}} =  tts_session:get_user_info(Session),
  +    tts_credential:exists(UserId, Id).
   
   get_openid_provider_list() ->
       {ok, OidcProvList} = oidcc:get_openid_provider_list(),
  
positive.code:     {ok, OpList}.
  
  
  get_service_list_for(Session) -> 
      {ok, UserInfo} = tts_session:get_user_info(Session),
      #{ site := #{uid := UserId}} = UserInfo,
      {ok, ServiceList} = tts_service:get_list(UserId),
      {ok, ServiceList}.
  
  get_credential_list_for(Session) -> 
      {ok, UserInfo} = tts_session:get_user_info(Session),
      #{ site := #{uid := UserId}} = UserInfo,
      {ok, CredentialList} = tts_credential:get_list(UserId),
      {ok, CredentialList}.
  
  
  get_credential_for(_CredId, _Session) -> ok.
  
  request_credential_for(ServiceId, Session, Params, Interface) -> 
      {ok, UserInfo} = tts_session:get_user_info(Session),
      {ok, Token} = tts_session:get_token(Session),
      {ok, SessionId} = tts_session:get_id(Session),
      true = tts_service:is_enabled(ServiceId),
      case tts_credential:request(ServiceId, UserInfo, Interface, Token, Params) of
          {ok, Credential, Log} ->
              [#{name := id, value:=CredId}|_] = Credential,
              lager:info("~p: requested credential ~p",
  
negative.code: %% limitations under the License.
  %%
  -author("Bas Wegh, Bas.Wegh<at>kit.edu").
  -include("tts.hrl").
  
  -export([
           login_with_oidcc/1,
           login_with_access_token/2,
           logout/1,
  
           does_provider_exist/2,
           does_service_exist/2,
           does_credential_exist/2,
  
           get_openid_provider_list/0,
           get_service_list_for/1,
           get_credential_list_for/1,
           request_credential_for/4,
           revoke_credential_for/2,
  
           get_access_token_for/1,
           get_display_name_for/1,
  
           store_temp_cred/2,
           get_temp_cred/2,
  
           start_full_debug/0,
           start_debug/1,
  